ARfoundaction Placement Indicator остается на одном месте, а не движется вместе с камерой - PullRequest
1 голос
/ 06 ноября 2019

Я создаю приложение, используя arfoundation для размещения объектов на плоскости земли. Для этой цели я построил индикатор размещения, но проблема, с которой я сталкиваюсь, заключается в том, что он создается впервые, а индикатор не движется вместе с моей камерой. Может кто-нибудь, пожалуйста, помогите мне. Предоставляя мой код ниже. Я проверил это, используя только Android.

Я также создал функцию для размещения объектов на кране, которая также не работает

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.Experimental.XR;
using System;

public class ArTapToPlace : MonoBehaviour
{
    public GameObject objectToPlace;
    public GameObject placementIndicator;

    private ARSessionOrigin arOrigin;
    private Pose placementPose;
    private bool placementPoseIsValid = false;

    void Start()
    {
        arOrigin = FindObjectOfType<ARSessionOrigin>();
    }

    void Update()
    {
        UpdatePlacementPose();
        UpdatePlacementIndicator();

        if (placementPoseIsValid && Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
        {
            PlaceObject();
        }
    }

    private void PlaceObject()
    {
        Instantiate(objectToPlace, placementPose.position, placementPose.rotation);
    }

    private void UpdatePlacementIndicator()
    {
        print(placementIndicator);
        if (placementPoseIsValid)
        {
            placementIndicator.SetActive(true);
            placementIndicator.transform.SetPositionAndRotation(placementPose.position, placementPose.rotation);
        }
        else
        {
            placementIndicator.SetActive(false);
        }
    }

    private void UpdatePlacementPose()
    {
        var screenCenter = Camera.current.ViewportToScreenPoint(new Vector3(0.5f, 0.5f));
        var hits = new List<ARRaycastHit>();
        arOrigin.GetComponent<ARRaycastManager>().Raycast(screenCenter, hits, UnityEngine.XR.ARSubsystems.TrackableType.Planes);
        print(hits.Count);
        print(hits);


        placementPoseIsValid = hits.Count > 0;
        if (placementPoseIsValid)
        {
            placementPose = hits[0].pose;

            var cameraForward = Camera.current.transform.forward;
            var cameraBearing = new Vector3(cameraForward.x, 0, cameraForward.z).normalized;
            placementPose.rotation = Quaternion.LookRotation(cameraBearing);
        }
    }
}

1 Ответ

0 голосов
/ 06 ноября 2019

Это может быть связано со строкой

var cameraForward = Camera.current.transform.forward;

Camera.current (почти) используется только для постобработки и устанавливается только во время рендеринга:

Большую часть времени вы захотите использовать Camera.main. Используйте эту функцию только при реализации одного из следующих событий: MonoBehaviour.OnRenderImage, OnPreRender, OnPostRender.

Так что вы скорее хотите использовать Camera.main, которая является текущей основной камерой вашей сцены.

var cameraForward = Camera.main.transform.forward;

В общем, этот вызов довольно дорогой, поэтому вы должны хранитьпри запуске приложения и повторном использовании ссылки

Это свойство внутренне использует FindGameObjectsWithTag и не кеширует результат. Рекомендуется кэшировать возвращаемое значение Camera.main, если оно используется несколько раз за кадр.

, и я бы расширил документы до "..., если оно используется несколько раз."

// If possible already reference it via the Inspector
[SerializeField] private Camera _camera;

private void Awake()
{
    // otherwise get it once on runtime
    if(!_camera) _camera = Camera.main;
}

...

var cameraForward = _camera.transform.forward;
...