如何在一个场景中添加多个模型,然后统一使用场景识别来检索它?

时间:2018-09-21 10:33:31

标签: c# unity3d arkit

每次触摸屏幕时,屏幕上都会出现相同的模型。如果我在五个不同的位置上触摸屏幕,则会在屏幕上的五个触摸位置上实例化模型,稍后将其保存到云中。当我加载保存的映射并扫描识别场景的同一位置,但屏幕上仅显示一个模型。我添加了一个“箭头”作为模型。我将在下面提供代码。

那么位置如何保存在这里?仅保存单个模型位置?为什么其他位置模型没有显示?是因为我使用的是同一模型?如何保存其他模型位置?

如果我在下面的代码行中添加代码(//如果添加了下面的代码行),则该实现有效。许多形状将在触摸时实例化,并且即使在应用关闭后也可以加载。

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!");

            Vector3 position = UnityARMatrixOps.GetPosition(hitResult.worldTransform);
            Quaternion rotation = UnityARMatrixOps.GetRotation(hitResult.worldTransform);

            //Transform to placenote frame of reference (planes are detected in ARKit frame of reference)
            Matrix4x4 worldTransform = Matrix4x4.TRS(position, rotation, Vector3.one);
            Matrix4x4? placenoteTransform = LibPlacenote.Instance.ProcessPose(worldTransform);

            Vector3 hitPosition = PNUtility.MatrixOps.GetPosition(placenoteTransform.Value);
            Quaternion hitRotation = PNUtility.MatrixOps.GetRotation(placenoteTransform.Value);

            // add shape
            AddShape(hitPosition, hitRotation);


            return true;
        }
    }
    return false;
}


//-----------------------------------
// Update function checks for hittest
//-----------------------------------

void Update()
{

    // Check if the screen is touched
    //-----------------------------------

    if (Input.touchCount > 0)
    {
        var touch = Input.GetTouch(0);
        if (touch.phase == TouchPhase.Began  )
        {
            if (EventSystem.current.currentSelectedGameObject == null)
            {

                Debug.Log("Not touching a UI button. Moving on.");

                // add new shape
                var screenPosition = Camera.main.ScreenToViewportPoint(touch.position);
                ARPoint point = new ARPoint
                {
                    x = screenPosition.x,
                    y = screenPosition.y
                };

                // prioritize reults types
                ARHitTestResultType[] resultTypes = {
                    //ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent,
                    //ARHitTestResultType.ARHitTestResultTypeExistingPlane,
                    //ARHitTestResultType.ARHitTestResultTypeEstimatedHorizontalPlane,
                    //ARHitTestResultType.ARHitTestResultTypeEstimatedVerticalPlane,
                    ARHitTestResultType.ARHitTestResultTypeFeaturePoint
                };

                foreach (ARHitTestResultType resultType in resultTypes)
                {
                    if (HitTestWithResultType(point, resultType))
                    {
                        Debug.Log("Found a hit test result");
                        return;
                    }
                }
            }
        }
    }
}

public void OnSimulatorDropShape()
{
    Vector3 dropPosition = Camera.main.transform.position + Camera.main.transform.forward * 0.3f;
    Quaternion dropRotation = Camera.main.transform.rotation;

    AddShape(dropPosition, dropRotation);

}

//-------------------------------------------------
// All shape management functions (add shapes, save shapes to metadata etc.
//-------------------------------------------------

public void AddShape(Vector3 shapePosition, Quaternion shapeRotation)
{
//if line below added
   // System.Random rnd = new System.Random(); 
//if line below added
    //PrimitiveType type = (PrimitiveType)rnd.Next(0, 3);

    ShapeInfo shapeInfo = new ShapeInfo();
    shapeInfo.px = shapePosition.x;
    shapeInfo.py = shapePosition.y;
    shapeInfo.pz = shapePosition.z;
    shapeInfo.qx = shapeRotation.x;
    shapeInfo.qy = shapeRotation.y;
    shapeInfo.qz = shapeRotation.z;
    shapeInfo.qw = shapeRotation.w;
//if line below added
   // shapeInfo.shapeType = type.GetHashCode();
    shapeInfoList.Add(shapeInfo);

    GameObject shape = ShapeFromInfo(shapeInfo);
    shapeObjList.Add(shape);
}


public GameObject ShapeFromInfo(ShapeInfo info)
{
    //if line below added
//GameObject shape = GameObject.CreatePrimitive((PrimitiveType)info.shapeType);

//Instead of
    GameObject shape =Instantiate(arrow);   

    shape.transform.position = new Vector3(info.px, info.py, info.pz);
    shape.transform.rotation = new Quaternion(info.qx, info.qy, info.qz, info.qw);
    shape.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
    shape.GetComponent<MeshRenderer>().material = mShapeMaterial;
    shape.GetComponent<MeshRenderer> ().material.color = Color.yellow;
    return shape;
}

1 个答案:

答案 0 :(得分:1)

在HitTestWithResultType()中,foreach中有一个返回值,因此在完成一次迭代后,代码将退出该方法。 基本上,每次调用该方法时,在foreach中仅执行一次迭代。 将返回的两行移到右括号之后。

我想每个人都需要另一双眼睛:)