В ARkit Любой учебник для FocusSquare Scene. Как показать модели одним касанием, похожим на ARHitCubeScene? - PullRequest
0 голосов
/ 23 июня 2018

Я попытался сделать проект в примере сцены Arkit FoucusSquare.In ArHitCubeTest, когда мы прикасаемся, например, если мы добавим куб, он будет создан одним касанием, когда куб станет дочерним по HitCubeParent. Аналогично, в FocusSquare Scene я сделал дочерний куб FoucusSquareFocused. Когда плоскость обнаружена, она показывает куб, в противном случае мы не можем видеть его, так как он отслеживает. Так, как только плоскость обнаружена, как разместить куб одним прикосновением к экрану, как в примере ArHitCubeTest.

1 Ответ

0 голосов
/ 25 июня 2018

Как и в большинстве вопросов, вы можете подойти к этому несколькими способами, и, пожалуйста, обратите внимание, что мой ответ предоставляет только базовое решение и не учитывает повторную инициализацию FocusSquare и т. Д.

В этом примере модель будет размещена, как только будет обнаружен ARPlaneAnchor, а затем будет отключена.

Прежде всего, вы можете добавить Transform вашей модели к FocusSquare Class например:

//The Transform Of Our Model To Place
public Transform modelToPlace;

А затем добавьте логическое значение, чтобы определить, была ли размещена наша модель, например:

//Boolean Determining Whether Our Model Has Been Placed
public bool modelPlaced = false;

Используя эти две переменные, пример FocusSquare Class может выглядеть так:

public class FocusSquare : MonoBehaviour {

public enum FocusState {
    Initializing,
    Finding,
    Found
}

public GameObject findingSquare;
public GameObject foundSquare;

//The Transform Of Our Model To Place
public Transform modelToPlace;

//Boolean Determining Whether Our Model Has Been Placed
public bool modelPlaced = false;

public float maxRayDistance = 30.0f;
public LayerMask collisionLayerMask;
public float findingSquareDist = 0.5f;

private FocusState squareState;
public FocusState SquareState { 
    get {
        return squareState;
    }
    set {
        squareState = value;
        foundSquare.SetActive (squareState == FocusState.Found);
        findingSquare.SetActive (squareState != FocusState.Found);
    } 
}

bool trackingInitialized;

//------------------
//MARK: - Life Cycle
//------------------

void Start () {
    SquareState = FocusState.Initializing;
    trackingInitialized = true;
}


void Update () {

    //If Our Model Hasnt Been Placed Continue Updating The Focus Square
    if (!modelPlaced) {

        Vector3 center = new Vector3 (Screen.width / 2, Screen.height / 2, findingSquareDist);
        var screenPosition = Camera.main.ScreenToViewportPoint (center);
        ARPoint point = new ARPoint {
            x = screenPosition.x,
            y = screenPosition.y
        };

        //We Only Want To Place A Model When The Focus Square Has Detected An ARPlance Acnhor
        ARHitTestResultType[] resultTypes = {
            ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent, 

        }; 

            foreach (ARHitTestResultType resultType in resultTypes) {
                if (HitTestWithResultType (point, resultType)) {
                    SquareState = FocusState.Found;
                    return;
                }
            }

            //No ARPlaneAnchor Has Been Detected So Continue Updating The Focus Square
            if (trackingInitialized) {
                SquareState = FocusState.Finding;


                if (Vector3.Dot (Camera.main.transform.forward, Vector3.down) > 0) {


                    findingSquare.transform.position = Camera.main.ScreenToWorldPoint (center);


                    Vector3 vecToCamera = findingSquare.transform.position - Camera.main.transform.position;


                    Vector3 vecOrthogonal = Vector3.Cross (vecToCamera, Vector3.up);


                    Vector3 vecForward = Vector3.Cross (vecOrthogonal, Vector3.up);


                    findingSquare.transform.rotation = Quaternion.LookRotation (vecForward, Vector3.up);

                } else {

                    findingSquare.SetActive (false);
                }

            }

        } else {

            //Our Model Has Been Placed So Disable The Focus Square
            findingSquare.SetActive (false);
            foundSquare.SetActive (false);

        }

    }


    /// Performs An SCNHitTest For Any Detected ARPlaneAnchore
    bool HitTestWithResultType (ARPoint point, ARHitTestResultType resultTypes)
    {
        List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface ().HitTest (point, resultTypes);
        if (hitResults.Count > 0) {
            foreach (var hitResult in hitResults) {

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

                //An ARPlaneAnchor Has Been Detected So Position Our Model & Set Our Boolean To Indicate It Has Been Placed
                if (!modelPlaced) {

                    modelToPlace.transform.position = UnityARMatrixOps.GetPosition (hitResult.worldTransform);
                    modelToPlace.transform.rotation = UnityARMatrixOps.GetRotation (hitResult.worldTransform);
                    modelPlaced = true;

                }

                return true;
            }
        }
        return false;
    }

}

Надеюсь, это укажет вам правильное направление ...

...