我正在使用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;
}
}
我在UnityhittestAR示例中进行了尝试。我一直在寻找类似FocusSquare的示例。一旦我们触摸屏幕后检测到飞机,物体就会被放置并且不再进行跟踪
答案 0 :(得分:0)
它是一个临时解决方案,但可以。在您的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);
}
}
}
}