В приложении ARCore, использующем Unity3d, вращение с помощью прокрутки не работает? - PullRequest
1 голос
/ 14 июня 2019

Из приведенного ниже кода зум работает двумя пальцами (ущипнуть, чтобы увеличить), но мое вращение не работает с помощью одного пролистывания. Для тестирования я добавил текст. экран.

Не могу понять, что масштабирование работает, но вращение не работает. Я загрузил последнюю версию ARcore SDK. Я использовал пример сцены HelloAR для размещения объекта, где HeartModel - это место, где я создаю экземпляр при касании при обнаружении плоскости.

public class HelloARController : MonoBehaviour
{
    /// <summary>
    /// The first-person camera being used to render the passthrough camera image (i.e. AR
    /// background).
    /// </summary>
    public Camera FirstPersonCamera;

    /// <summary>
    /// A prefab for tracking and visualizing detected planes.
    /// </summary>
    public GameObject DetectedPlanePrefab;

    /// <summary>
    /// A model to place when a raycast from a user touch hits a plane.
    /// </summary>
    public GameObject AndyPlanePrefab;
    public GameObject HeartModel;

    /// <summary>
    /// A model to place when a raycast from a user touch hits a feature point.
    /// </summary>
    public GameObject AndyPointPrefab;

    /// <summary>
    /// The rotation in degrees need to apply to model when the Andy model is placed.
    /// </summary>
    private const float k_ModelRotation = 180.0f;

    /// <summary>
    /// True if the app is in the process of quitting due to an ARCore connection error,
    /// otherwise false.
    /// </summary>
    private bool m_IsQuitting = false;


    public static HelloARController helloinstance;

    public GameObject ExampleControl;

    //To spawn only once
    private bool spawned = false;

    private void Start()
    {
        helloinstance = this;
    }

    /// <summary>
    /// The Unity Update() method.
    /// </summary>
    public void Update()
    {
        _UpdateApplicationLifecycle();

        // If the player has not touched the screen, we are done with this update.
        Touch touch;
        if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
        {
            return;
        }

        // Should not handle input if the player is pointing on UI.
        if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
        {
            return;
        }

        // Raycast against the location the player touched to search for planes.
        TrackableHit hit;
        //TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
            //TrackableHitFlags.FeaturePointWithSurfaceNormal;

        TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinInfinity;

        if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit) && spawned==false)
        {
            // Use hit pose and camera pose to check if hittest is from the
            // back of the plane, if it is, no need to create the anchor.
            if ((hit.Trackable is DetectedPlane) &&
                Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position,
                    hit.Pose.rotation * Vector3.up) < 0)
            {
                Debug.Log("Hit at back of the current DetectedPlane");
            }
            else
            {
                // Choose the Andy model for the Trackable that got hit.
                GameObject prefab;
                if (hit.Trackable is FeaturePoint)
                {
                    //prefab = AndyPointPrefab;
                    prefab = null;
                }
                else
                {
                   // prefab = AndyPlanePrefab;
                    prefab = HeartModel;
                }

                // Instantiate Andy model at the hit pose.
                var andyObject = Instantiate(prefab, hit.Pose.position, hit.Pose.rotation);

                // Compensate for the hitPose rotation facing away from the raycast (i.e.
                // camera).
                //andyObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);


               // andyObject.transform.Rotate(0, 0, 0, Space.Self);
                // Create an anchor to allow ARCore to track the hitpoint as understanding of
                // the physical world evolves.
                var anchor = hit.Trackable.CreateAnchor(hit.Pose);

                // Make Andy model a child of the anchor.
                andyObject.transform.parent = anchor.transform;
            }

            spawned = true;
        }
    }

    /// <summary>
    /// Check and update the application lifecycle.
    /// </summary>
    private void _UpdateApplicationLifecycle()
    {
        // Exit the app when the 'back' button is pressed.
        if (Input.GetKey(KeyCode.Escape))
        {
            Application.Quit();
        }

        // Only allow the screen to sleep when not tracking.
        if (Session.Status != SessionStatus.Tracking)
        {
            const int lostTrackingSleepTimeout = 15;
            Screen.sleepTimeout = lostTrackingSleepTimeout;
        }
        else
        {
            Screen.sleepTimeout = SleepTimeout.NeverSleep;
        }

        if (m_IsQuitting)
        {
            return;
        }

        // Quit if ARCore was unable to connect and give Unity some time for the toast to
        // appear.
        if (Session.Status == SessionStatus.ErrorPermissionNotGranted)
        {
            _ShowAndroidToastMessage("Camera permission is needed to run this application.");
            m_IsQuitting = true;
            Invoke("_DoQuit", 0.5f);
        }
        else if (Session.Status.IsError())
        {
            _ShowAndroidToastMessage(
                "ARCore encountered a problem connecting.  Please start the app again.");
            m_IsQuitting = true;
            Invoke("_DoQuit", 0.5f);
        }
    }


}

Я добавил еще один скрипт для масштабирования и поворота, приведенный ниже. В исправленном обновлении я использую касание, чтобы провести одним пальцем по оси y, что не работает. Но в то же время работает масштабирование. ** Поэтому я сомневаюсь, что вращение модели заблокировано для начала координат? ** Ниже приведен скрипт поворота, который является другим скриптом (Rotate.cs, который я прикрепил к префабу)

  void FixedUpdate()
 {
      if (Input.touchCount > 0 && isLocked==true)
      {
          var touch = Input.GetTouch(0);

          if ((Input.touchCount > 0  && Input.touchCount < 2 && Input.GetTouch(0).phase == TouchPhase.Moved) && !EventSystem.current.IsPointerOverGameObject(touch.fingerId) )
          {
              // Get movement of the finger since last frame
              Debug.Log("One touch Move");
              Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
              Messagetxt.text = this.gameObject.name;

             this.transform.Rotate(Vector3.up, -touchDeltaPosition.x * rotspeed * Time.deltaTime, Space.World);
           }

           if (Input.touchCount == 2 &&  !EventSystem.current.IsPointerOverGameObject(touch.fingerId))
           {
               // Store both touches.
               Touch touchZero = Input.GetTouch(0);
               Touch touchOne = Input.GetTouch(1);

               // Find the position in the previous frame of each touch.
               Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
               Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;

               // Find the magnitude of the vector (the distance) between the touches in each frame.
               float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
               float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;

               // Find the difference in the distances between each frame.
               float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;

               float scale = deltaMagnitudeDiff * perspectiveZoomSpeed * Time.deltaTime;

               Vector3 tt;
               tt.x = scale;
               tt.y = scale;
               tt.z = scale;
                if (this.transform.localScale.x > 0 && this.transform.localScale.y > 0 && this.transform.localScale.z > 0)
                {
                    this.transform.localScale += new Vector3(-scale, -scale, -scale);
                }

                if (this.transform.localScale.x < 1 && this.transform.localScale.y < 1 && this.transform.localScale.z < 1)
                {
                    this.transform.localScale += new Vector3(scale, scale, scale);
                }

                if (this.transform.localScale.x > 3 && this.transform.localScale.y > 3 && this.transform.localScale.z > 3)
                {
                    this.transform.localScale += new Vector3(scale, scale, scale);
                }
            }
       }
 }


public void Lock_Unlock()
{

    if (!isLocked)
    {
        Lock_Unlock_btn.GetComponent<Image>().sprite = Locksprite;
        isLocked = true;
        //  UnityARHitTestExample.InstanceHitManger.m_HitTransform.GetComponent<UnityARHitTestExample>().enabled = false;
        HelloARController.helloinstance.ExampleControl.GetComponent<HelloARController>().enabled = false;
        hidecanvas.SetActive(false);
    }
    else
    {
        Lock_Unlock_btn.GetComponent<Image>().sprite = Unlocksprite;
        isLocked = false;
        //UnityARHitTestExample.InstanceHitManger.m_HitTransform.GetComponent<UnityARHitTestExample>().enabled = true;
        HelloARController.helloinstance.ExampleControl.GetComponent<HelloARController>().enabled = true;
    }
}
...