【问题标题】:How to hide plane prefab used for plane detection in ARKit using Unity?如何使用 Unity 在 ARKit 中隐藏用于平面检测的平面预制件?
【发布时间】:2019-01-01 01:31:08
【问题描述】:

我正在使用 ARKit 构建一个用于垂直平面检测的应用程序。一旦检测到平面,我需要关闭平面检测。即使在检测到平面后,它仍在跟踪并查找更多平面。如何在平面被关闭时关闭检测到。

using System;
using System.Collections.Generic;
using UnityEngine.EventSystems;

namespace UnityEngine.XR.iOS

{
    public class UnityARHitTestExample : MonoBehaviour
    {
        public Transform m_HitTransform;
        public float maxRayDistance = 30.0f;
    public LayerMask collisionLayer = 1 << 10;  //ARKitPlane layer

    public List<GameObject> Instaobj = new List<GameObject>();

    public Transform ForSelect;
    int Select;
    UnityARCameraManager obj=new UnityARCameraManager();
    UnityARGeneratePlane obb=new UnityARGeneratePlane();


    bool HitTestWithResultType (ARPoint point, ARHitTestResultType resultTypes)
    {
        List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface ().HitTest (point, resultTypes);
        if (hitResults.Count > 0) {
            foreach (var hitResult in hitResults) {
                Debug.Log ("Got hit!");
                obj.Hideplane();
               // obb.planePrefab.SetActive(false);





                m_HitTransform.position = UnityARMatrixOps.GetPosition (hitResult.worldTransform);
                m_HitTransform.rotation = UnityARMatrixOps.GetRotation (hitResult.worldTransform);
                Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z));








                return true;
            }
        }
        return false;
    }

    // Update is called once per frame
    void Update () {


        #if UNITY_EDITOR   //we will only use this script on the editor side, though there is nothing that would prevent it from working on device
        if (Input.GetMouseButtonDown (0)) {
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            RaycastHit hit;

            //we'll try to hit one of the plane collider gameobjects that were generated by the plugin
            //effectively similar to calling HitTest with ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent
            if (Physics.Raycast (ray, out hit, maxRayDistance, collisionLayer)) {
                //we're going to get the position from the contact point
                m_HitTransform.position = hit.point;
                Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z));

                //and the rotation from the transform of the plane collider
                m_HitTransform.rotation = hit.transform.rotation;
            }
        }
        #else
        if (Input.touchCount > 0 && m_HitTransform != null )
        {
            var touch = Input.GetTouch(0);
            if ((touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved) &&  !EventSystem.current.IsPointerOverGameObject(touch.fingerId))
            {
                var screenPosition = Camera.main.ScreenToViewportPoint(touch.position);
                ARPoint point = new ARPoint {
                    x = screenPosition.x,
                    y = screenPosition.y
                };

                // prioritize reults types
                ARHitTestResultType[] resultTypes = {
                    //ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingGeometry,
                    ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent, 
                    // if you want to use infinite planes use this:
                    //ARHitTestResultType.ARHitTestResultTypeExistingPlane,
                    //ARHitTestResultType.ARHitTestResultTypeEstimatedHorizontalPlane, 
                    //ARHitTestResultType.ARHitTestResultTypeEstimatedVerticalPlane, 
                    //ARHitTestResultType.ARHitTestResultTypeFeaturePoint
                }; 

                foreach (ARHitTestResultType resultType in resultTypes)
                {
                    if (HitTestWithResultType (point, resultType))
                    {
                        return;
                    }
                }
            }
        }
        #endif

    }


}

}

下面是 UnityARCameraManager

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.iOS;

public class UnityARCameraManager : MonoBehaviour {

    public Camera m_camera;
    private UnityARSessionNativeInterface m_session;
    private Material savedClearMaterial;

    [Header("AR Config Options")]
    public UnityARAlignment startAlignment = UnityARAlignment.UnityARAlignmentGravity;
    public UnityARPlaneDetection planeDetection = UnityARPlaneDetection.Horizontal;
    public ARReferenceImagesSet detectionImages = null;
    public bool getPointCloud = true;
    public bool enableLightEstimation = true;
    public bool enableAutoFocus = true;
    private bool sessionStarted = false;
    private ARKitWorldTrackingSessionConfiguration config;

// Use this for initialization
void Start () {

    m_session = UnityARSessionNativeInterface.GetARSessionNativeInterface();

    Application.targetFrameRate = 60;
    //ARKitWorldTrackingSessionConfiguration config = new ARKitWorldTrackingSessionConfiguration();
     config = new ARKitWorldTrackingSessionConfiguration();
    config.planeDetection = planeDetection;
    config.alignment = startAlignment;
    config.getPointCloudData = getPointCloud;
    config.enableLightEstimation = enableLightEstimation;
    config.enableAutoFocus = enableAutoFocus;
    if (detectionImages != null) {
        config.arResourceGroupName = detectionImages.resourceGroupName;
    }

    if (config.IsSupported) {
        m_session.RunWithConfig (config);
        UnityARSessionNativeInterface.ARFrameUpdatedEvent += FirstFrameUpdate;
    }

    if (m_camera == null) {
        m_camera = Camera.main;
    }
}

void FirstFrameUpdate(UnityARCamera cam)
{
    sessionStarted = true;
    UnityARSessionNativeInterface.ARFrameUpdatedEvent -= FirstFrameUpdate;
}

public void SetCamera(Camera newCamera)
{
    if (m_camera != null) {
        UnityARVideo oldARVideo = m_camera.gameObject.GetComponent<UnityARVideo> ();
        if (oldARVideo != null) {
            savedClearMaterial = oldARVideo.m_ClearMaterial;
            Destroy (oldARVideo);
        }
    }
    SetupNewCamera (newCamera);
}

private void SetupNewCamera(Camera newCamera)
{
    m_camera = newCamera;

    if (m_camera != null) {
        UnityARVideo unityARVideo = m_camera.gameObject.GetComponent<UnityARVideo> ();
        if (unityARVideo != null) {
            savedClearMaterial = unityARVideo.m_ClearMaterial;
            Destroy (unityARVideo);
        }
        unityARVideo = m_camera.gameObject.AddComponent<UnityARVideo> ();
        unityARVideo.m_ClearMaterial = savedClearMaterial;
    }
}

// Update is called once per frame

void Update () {

    if (m_camera != null && sessionStarted)
    {
        // JUST WORKS!
        Matrix4x4 matrix = m_session.GetCameraPose();
        m_camera.transform.localPosition = UnityARMatrixOps.GetPosition(matrix);
        m_camera.transform.localRotation = UnityARMatrixOps.GetRotation (matrix);

        m_camera.projectionMatrix = m_session.GetCameraProjection ();
    }

}


public void Hideplane()
{

    config.planeDetection = UnityARPlaneDetection.None;

}

}

我尝试使用 Hideplane() 方法,仍然显示蓝色平面

我在 UnityhittestAR 示例中尝试过这个。我正在寻找类似 FocusSquare 的示例。一旦在我们触摸屏幕时检测到平面,对象就会被放置并且不再跟踪

【问题讨论】:

    标签: c# unity3d augmented-reality arkit


    【解决方案1】:

    它是一个临时解决方案,但它有效。在你的 UnityARKitScene 中附加一个新脚本

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    public class EventHandler : MonoBehaviour {
        public GameObject MainPlane;
        public GameObject DestroyedPlane;
        public GameObject p;
        public int Got;
        private void Start()
        {
            Instantiate(p);
        }
        private void Update()
        {
    
            MainPlane = GameObject.Find("Plane");
            if(MainPlane!=null){
                if(Got==0){
                    MainPlane.name = "MainPlane";
                    Got = 1;
                }
                if(Got==1){
                    MainPlane = null;
                    DestroyedPlane = GameObject.Find("Plane");
                    Destroy(DestroyedPlane);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      • 2020-04-09
      • 2018-12-05
      • 1970-01-01
      相关资源
      最近更新 更多