ARFoundation项目学习记录(五)--基于平面检测的AR家具开发

前言:

记录(四)是用Vuforia做的,现在来探索一下平面检测,仅记录我的学习过程,如果对你有帮助就更好了!

项目构思:

AR家具摆放是AR技术应用比较广泛的领域,而平面检测时实现家具摆放的重要功能,本案例将通过简单的AR家具Demo来展示ARfoundation的平面检测功能。

项目设计:

(1)可以通过对UI的选择实现对家具的选择

(2)可以通过按下确定按钮,固定家具的位置,按下取消按钮删除要摆放的家具

(3)在检测到平面时,可以控制模型的摆放

项目实施:

新建项目,命名为AR_Furniture分别导入ARFoundation和ARCore XR Plugin,进行Android平台的基本设置(在ARFoundation的基本环境配置已经介绍过了)

在Hierarachy窗口的空白处单击鼠标右键,在弹出的菜单中选择XR>AR Session Origin和XR>AR Session。然后我们需要可跟踪对象管理器ARPlaneManager和可跟踪对象ARPlane用来检测与管理平面。在Hierarachy窗口选择AR Session Origin对象,为其添加ARPlaneManager组件,如图所示。

补充一下,ARPlaneManager组件在检测到平面时会实例一个预制体来表示该平面,如果图中的ARPlanePrefab属性没有赋值,ARPlaneManager将会实例一个空对象,并在空对象上挂载ARPlane组件。

这里我们用UI中的Toggle来进行家具的选择,在Hierarachy窗口的空白处单击鼠标右键,在弹出的菜单中选择Create>UI>Toggle,如图所示,两个Toggle分别表示桌子和椅子,分别重命名为DeskToggle和ChairToggle,并修改“Toggle”层级下的“label”的Text属性分别为Desk和Chair,并调整大小和位置。

在“Canvas”的层级下,新建一个“Create Empty”空物体并改名为“Group”。在空物体的属性面板中,通过“Add Component”添加一个名为“Toggle Group”的组件,勾选Allow Switch Off,即允许都不勾选的状态,如图所示。

把两个Toggle拖拽到Canvas的层级下,选中两个“Toggle”,在其“Toggle(Script)”组件中的“Group”中,选择新建的空物体“Group”,如图所示。

现在两个“Toggle”最多只能有一个保持is On的状态,这样就实现了家具二选一的功能。后期还可以实现多选一的功能。

在Hierarachy窗口的空白处单击鼠标右键,在弹出的菜单中选择Create>UI>Button,创建两个按钮来控制模型的放置和删除,分别命名为SureButton和DelButton,如图所示,并修改“Button”层级下的“Text”为对应的文本“确认”和“取消”,调整大小和位置。

开始制作家具预制体,在文末素材链接中,将素材包AR_Furniture.unitypackage导入项目,将Prefabs中的素材Desk和Chair拖入Hierarachy窗口中。选择这两个游戏对象,为其添加碰撞体。通过“Add Component”添加一个名为“Box Collider”的组件,按下“Edit Collider”可以进行碰撞体大小的调整,如图所示。

补充一下,我们进行AR家具的摆放,是利用射线与场景中的物体进行碰撞检测,添加了碰撞体,后期可以通过射线来选择场景中的家具并进行操作。

新建一个C#脚本命名为PlayerRotate,用于控制家具的旋转,代码如下。

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class PlayerRotate : MonoBehaviour {


    float xSpeed = 150.0f;


    // Use this for initialization

    void Start () {

        

    }

   

    // Update is called once per frame

    void Update () {

        if (Input.GetMouseButton(0))

        {

            if (Input.touchCount == 1)

            {

                if (Input.GetTouch(0).phase == TouchPhase.Moved)

                {

                    transform.Rotate(Vector3.up * Input.GetAxis("Mouse X") * -xSpeed * Time.deltaTime, Space.World);

                }

            }

        }


       

    }


   

}

为两个家具游戏对象挂载该脚本,如图所示,再拖入Project窗口的Prefabs文件夹中,这样家具的预制体就制作完成了。

新建一个C#脚本命名为AppControler,用于控制家具的摆放,代码如下。

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.XR.ARFoundation;

using UnityEngine.XR.ARSubsystems;

using UnityEngine.UI;

[RequireComponent(typeof(ARRaycastManager))]

public class AppControler : MonoBehaviour

{

    public Toggle[] toggles;

    //存储模型的数组

    public GameObject[] spawnPrefabs;

    public GameObject[] buttons;

    static List<ARRaycastHit> Hits;

    private ARRaycastManager mRaycastManager;

    //当前要放置的模型

    private GameObject spawnedObject = null;

    //选择的当前模型的下标

    private int currentIndex;

    //判断是否选择了家具

    private bool ischoose;

    private void Start()

    {

        Hits = new List<ARRaycastHit>();// ARRaycastHit类保存的是发生碰撞时检测到的碰撞体相关信息

        mRaycastManager = GetComponent<ARRaycastManager>();

    }

    //当Toggle被选中时,判断选择哪个模型

    public void juadge()

    {

        bool isOn = false;

        foreach (var item in toggles)

        {

            if (item.isOn)

            {

                isOn = true;

            }

        }

        if (!isOn) return;

        if (toggles[0].isOn)

        {

            ischoose = true;

            currentIndex = 0;

            Debug.Log("true");

        }

        else {

            ischoose = true;

            currentIndex = 1;

            Debug.Log("true");

        }


    }

    void Update()

    {

        if (Input.touchCount == 0)

            return;

        var touch = Input.GetTouch(0);

        //当检测到平面并且Toggle被选择

        if (mRaycastManager.Raycast(touch.position, Hits, TrackableType.PlaneWithinPolygon | TrackableType.PlaneWithinBounds)&&ischoose)

        {

            var hitPose = Hits[0].pose;

            if (spawnedObject == null)

            {

                spawnedObject = Instantiate(spawnPrefabs[currentIndex], hitPose.position, hitPose.rotation);

                Changestate();


            }

            else

            {

               

                    spawnedObject.transform.position = hitPose.position;


                

            }

        }

    }

    // 当确定按钮被按下

    public void OnSureClick() {

        //禁用控制模型旋转的脚本

        spawnedObject.GetComponent<PlayerRotate>().enabled = false;

        Changestate();

        spawnedObject = null;


    }

    //当取消按钮被按下时,按钮消失,删除放置的模型

    public void OnDelClick()

    {

        if (spawnedObject != null) {

            Changestate();

            DestroyImmediate(spawnedObject);

            spawnedObject = null;

        }

    }

    //控制UI按钮的显示

    private void Changestate() {

        foreach (var item in buttons) {

            item.SetActive(!item.activeInHierarchy);

        }

   


    }

}

随后把脚本挂载到场景中的AR Session Origin上,并为Toggles、Spawn Prefabs、Buttons赋值,如图所示,注意Toggles和Spawn Prefabs中按钮和模型要一一对应。

选择场景中的DelButton然后单击On Click()下面的“+”号按钮,指定AR Session Origin作

为消息接收对象,选择AppControler的OnDelClick ()函数作为响应按钮单击事件

的回调函数,如图所示。

选择场景中的SureButton然后单击On Click()下面的“+”号按钮,指定AR Session Origin作为消息接收对象,选择AppControler的OnSureClick() 函数作为响应按钮单击事件的回调函数,如图所示。

选择场景中的两个Toggle,然后单击On Value Changed(Boolean)下面的“+”号按钮,指定AR Session Origin作为消息接收对象,选择AppControler的juadge() 函数作为响应按钮单击事件,如图所示

存在问题

这里因为在点击UI时,还是会认为可能在放置家具。

因此我们可以先update中判断是否按下了按钮,在lateupdate中决定是否要摆放家具(还没有做)

同时用toggle来做选项有点low了,后面有时间把它改成图片。

4.项目测试:

打包成apk发布到手机运行

效果如下:

素材链接:

https://pan.baidu.com/s/1M_gyT1vUkY9qh5bLUjNGpg?pwd=2yar
提取码:2yar

源码链接:

https://pan.baidu.com/s/1B-HXQmSbkmVk6FVTA138Dw?pwd=9utd
提取码:9utd

安装包链接:

链接:https://pan.baidu.com/s/1yKa-u-L8RygJ6r0jUUNBMQ?pwd=1234
提取码:1234

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ARFoundation是一个基于Unity的增强现实(AR开发框架,用于在移动设备上创建AR应用程序。在ARFoundation中,平面检测可以看作是AR应用程序中的一种基本功能。但并不是所有的AR应用都必须先进行平面检测平面检测是指ARFoundation使用传感器数据和计算算法来识别设备摄像头视野中的平面,并将这些平面作为虚拟物体放置和交互的基础。通过平面检测,应用程序可以识别水平的平面,例如地面、桌面等,用户可以在这些平面上放置虚拟物体,使其看起来像是与真实世界的物体进行交互。 在许多AR应用中,平面检测是一个重要的步骤,它为用户提供了与虚拟内容进行互动的机会,并将其与真实世界环境相结合。例如,一个AR游戏可以使用平面检测来将虚拟关卡放置在用户当前所处的地面上。然后用户可以在这个平面上行走,并与游戏中的虚拟角色进行互动。 然而,并不是所有的AR应用都需要平面检测。一些AR应用可能更关注于物体跟踪或人脸识别等其他功能。例如,一个AR镜框应用可能更关注如何准确地将虚拟眼镜放在用户的脸上,而不是在平面上。在这种情况下,平面检测可能并不是首要的任务。 总的来说,ARFoundation提供了平面检测的功能,可以在AR应用程序中使用。然而,具体的AR应用功能需求决定了是否需要平面检测

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值