简体   繁体   中英

ARKit - place object without touching the screen

Using ARKit I can tap on the surface to place 3D object here. I also can move my finger and thus move the object along the surface.

How can I make an object to automatically appear and stick to the surface in front of the camera, with no need in touching the screen?

Here is the example script for placing 3D objects by finger tap:

using System;
using System.Collections.Generic;

namespace UnityEngine.XR.iOS
{
    public class UnityARHitTestExample : MonoBehaviour
    {
        public Transform m_HitTransform;

        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!");
                    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 (Input.touchCount > 0 && m_HitTransform != null)
            {
                var touch = Input.GetTouch(0);
                if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved)
                {
                    var screenPosition = Camera.main.ScreenToViewportPoint(touch.position);
                    ARPoint point = new ARPoint {
                        x = screenPosition.x,
                        y = screenPosition.y
                    };

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

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


    }
}

I've done something similar in Objective-C, so hopefully I can help with your unity example.

My logic was basically that placing the objects using a tap is based on the hitTest function with a point provided to it retrieved from the touch location. So I just created a CGPoint programmatically in the center of the screen and ran the hitTest function with this point. Had it hooked to a timer, and when a hit returned objects were added there.

CGPoint point = CGPointMake(self.sceneView.frame.size.width / 2, self.sceneView.frame.size.height / 2); //Get a point at the middle of the screen
NSArray <ARHitTestResult *> *hitResults = [_sceneView hitTest:point types:ARHitTestResultTypeFeaturePoint]; //Try to do a AR Hit Test on this point
if ([hitResults count] != 0) { //If have any results
    //Perform desired operation
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM