【问题标题】:How to move object/prefab in the direction of camera view on a plane generated by ARCore如何在 ARCore 生成的平面上沿相机视图方向移动对象/预制件
【发布时间】:2019-02-16 10:26:15
【问题描述】:

我正在使用 LeanTouch+ 平移对象,但它只能在基于 android 屏幕的 Y 上移动,所以在相机上对象只能上下移动。我想要实现的是能够将对象移动得更远或更靠近相机视图。在 ARCore 中,您首先检测环境,然后将其生成为平面,这就是我需要对象移动到的平面。

如果可能的话,我想在“检测到的平面”上使用 Clamp 来限制比检测到的平面更远的移动

这是我使用 LeanFingerTap 生成 obj 的代码

public void Spawn(LeanFinger finger)
    {
        if (AndyPlanePrefab != null && finger != null)
        {
            // Raycast against the location the player touched to search for planes.
            TrackableHit hit;
            TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
                TrackableHitFlags.FeaturePointWithSurfaceNormal;

            if (Frame.Raycast(finger.ScreenPosition.x, finger.ScreenPosition.y, raycastFilter, out hit))
            {
                if(currentNumberofPrefab<numberOfPrefabsAllowed)
                {
                    currentNumberofPrefab = currentNumberofPrefab + 1;

                    // 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.
                        if (hit.Trackable is FeaturePoint)
                        {
                            AndyPrefab = AndyPointPrefab;
                        }
                        else
                        {
                            getValue = ItemScrollList.valuePrefab;
                            if (getValue == 1)
                            {
                                AndyPrefab = AndyPlanePrefab[0];
                                Debug.Log("value 1");
                            }
                            else if (getValue == 2)
                            {
                                AndyPrefab = AndyPlanePrefab[1];
                                Debug.Log("value 2");
                            }
                            else if (getValue == 3)
                            {
                                AndyPrefab = AndyPlanePrefab[2];
                                Debug.Log("value 3");
                            }
                            else if (getValue == 4)
                            {
                                AndyPrefab = AndyPlanePrefab[3];
                                Debug.Log("value 4");
                            }
                            else if (getValue == 5)
                            {
                                AndyPrefab = AndyPlanePrefab[4];
                                Debug.Log("value 5");
                            }
                        }

                        // Instantiate Andy model at the hit pose.
                        var andyObject = Instantiate(AndyPrefab, hit.Pose.position, hit.Pose.rotation);
                        //adding tag to andyObject for destroying spawn purposes
                        andyObject.tag = "HomePrefab";

                        // Compensate for the hitPose rotation facing away from the raycast (i.e. camera).
                        andyObject.transform.Rotate(0, k_ModelRotation, 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;
                    }
                }

            }
        }
    }

【问题讨论】:

    标签: unity3d arcore


    【解决方案1】:

    您可以通过在(0, 0, 0) 中创建一个将空游戏对象作为父对象并将您的对象作为子对象的预制件来实现此目的。

    然后,当您检测到飞机时,您会使用 Session.GetTrackable 将飞机添加到列表中。 然后您可以使用以下代码在检测到的平面中心实例化您的预制件:

    Anchor anchor = m_AllPlanes[0].CreateAnchor(m_AllPlanes[0].CenterPose);
    var obj = Instantiate(myPrefab, m_AllPlanes[0].CenterPose);
    obj.transform.parent = anchor.transform;
    

    然后,如果您想让 obj 离相机更远或更近,您可以在局部 z 中移动它。然后你的夹子可以是m_AllPlanes[0].CenterPose.position.z - m_AllPlanes[0].ExtentZ 到m_AllPlanes[0].CenterPose.position.z + m_AllPlanes[0].ExtentZ

    我建议使用游戏对象创建预制件的原因是能够使用局部坐标,因为 ARCore 坐标在每个 Session 中都会发生变化。

    【讨论】:

    • 我如何将它与 LeanFinger 结合起来,比如说 LeanFingerTap?还是最好删除 LeanFinger 而只使用锚?请查看我上面更新的帖子以获取生成 obj 的代码。非常感谢!
    • 好吧,我没有使用过精益触摸,但不管怎样,您都需要以某种方式从用户那里获取移动对象的输入。您也许可以使用虚拟操纵杆。但是,您获得的输入必须更改锚点的 z 位置才能越来越靠近相机。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    相关资源
    最近更新 更多