当用户触摸GameObject时,如何阻止ARCore模型放置?

问题描述 投票:3回答:2

免责声明:我对Unity3D和ARCore都很陌生,所以请耐心等待。

我在Unity3D中使用ARCore来创建一个场景,用户可以在屏幕上选择ScrollView中的模型,并使用Google的ARCore框架放置它们。

到目前为止,我有它的工作;用户触摸ScrollView中的模型(在Panel屏幕上显示为当前所选模型,因为我的计划是让ScrollView切换可见性以获得更多屏幕视图空间)。

问题是,当用户选择模型时,ARCore将模型放置在ScrollView和所选模型Panel对象后面的检测平面上(即使您第一次触摸开始滚动ScrollView)。请参阅下文以帮助可视化。

enter image description here

如何让ARCore不将对象放在ScrollViewPanel后面?我试过的是添加到我的控制器(实际上只是Google HelloARController)我想要阻止ARCore的Raycast并用foreach迭代它们的对象集合,看看Raycast是否击中了集合中的GameObjects

Touch touch;
if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
{
    return;
}

//my code; above is Google's
foreach (var item in BlockingObjects) { //BlockingObjects is a List<GameObject>
    if (IsTouchInObject(FirstPersonCamera.ScreenPointToRay(touch.position), item)) {
        return;
    }
}
//end of my code; below is Google's

TrackableHit hit;
TrackableHitFlag raycastFilter = TrackableHitFlag.PlaneWithinBounds | TrackableHitFlag.PlaneWithinPolygon;

使用IsTouchInObject函数定义如下:

private bool IsTouchInObject(Ray ray, GameObject obj) {
    RaycastHit rch;
    Physics.Raycast (ray, out rch);
    return (rch.collider != null);
}

失败的是rch.collider总是null(我知道我根本没有测试对象,我会担心一旦我能让Raycast实际上与GameObject碰撞)。我已经尝试使用Physics / Physics2DRaycastHit / RacastHit2D并将BoxCollider / BoxCollider2D组件附加到我想要检测到的对象上,但我所做的一切都没有效果。

(这个解决方案取自Unity3D论坛上的某些东西,其中有人有类似的问题,但没有AR,他们自己的3D世界有2D覆盖。我找不到该论坛帖子提供参考,对不起)。

任何帮助将不胜感激。

编辑/注意:我现在注意到Graphic Raycaster上有一个Canvas组件,其中包含我的ScrollViewPanel。我已经尝试将Blocking Objects设置为Two D(同时将Box Collider 2D添加到ScrollViewPanel)和Blocking Mask设置为Ignore Raycast(以及其他一些事情)无济于事。这些属性的值是否可以组合使用?

本着今天的精神:

帮助我,StackOverflow ......呃...... Kenobi ......你是我唯一的希望。

android raycasting arcore
2个回答
4
投票

你有没有试过用以下方法包装Raycast:

 if (!EventSystem.current.IsPointerOverGameObject(touch.fingerId)) {...}

https://answers.unity.com/questions/1406243/ui-in-arcore-helloar-example.html


3
投票

这是我在StackOverflow上的第一个答案,所以请耐心等待。我正在构建一个类似的应用程序,您可以从UI面板中统一选择不同的模型,并将模型放置在现实世界中检测到的平面上。我能够设计出来解决您遇到的问题的唯一方法是执行以下操作:

在HelloARController.CS中,初始化bool'place_model'(或您想要的任何名称)并将其设置为false。现在,您需要滚动到在现实世界中扩充模型的部分。

if (Session.Raycast(m_firstPersonCamera.ScreenPointToRay(touch.position), raycastFilter, out hit))
                {
                    // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
                    // world evolves.



                        var anchor = Session.CreateAnchor(hit.Point, Quaternion.identity);

                        // Intanstiate an Andy Android object as a child of the anchor; it's transform will now benefit
                        // from the anchor's tracking.
                        var andyObject = Instantiate(m_andy, hit.Point, Quaternion.identity,
                            anchor.transform);

                        // Andy should look at the camera but still be flush with the plane.
                        andyObject.transform.LookAt(m_firstPersonCamera.transform);
                        andyObject.transform.rotation = Quaternion.Euler(0.0f,
                            andyObject.transform.rotation.eulerAngles.y, andyObject.transform.rotation.z);

                        andyObject.AddComponent<BoxCollider>();
                        // Use a plane attachment component to maintain Andy's y-offset from the plane
                        // (occurs after anchor updates).
                        andyObject.GetComponent<PlaneAttachment>().Attach(hit.Plane);
}

将上面的代码更改为以下代码:

if (place_model){   // changed portion
if (Session.Raycast(m_firstPersonCamera.ScreenPointToRay(touch.position), raycastFilter, out hit))
                {
                    // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
                    // world evolves.



                        var anchor = Session.CreateAnchor(hit.Point, Quaternion.identity);

                        // Intanstiate an Andy Android object as a child of the anchor; it's transform will now benefit
                        // from the anchor's tracking.
                        var andyObject = Instantiate(m_andy, hit.Point, Quaternion.identity,
                            anchor.transform);

                        // Andy should look at the camera but still be flush with the plane.
                        andyObject.transform.LookAt(m_firstPersonCamera.transform);
                        andyObject.transform.rotation = Quaternion.Euler(0.0f,
                            andyObject.transform.rotation.eulerAngles.y, andyObject.transform.rotation.z);

                        andyObject.AddComponent<BoxCollider>();
                        // Use a plane attachment component to maintain Andy's y-offset from the plane
                        // (occurs after anchor updates).
                        andyObject.GetComponent<PlaneAttachment>().Attach(hit.Plane);

place_model = false // changed portion
    }

}

现在,无论如何,您都无法放置模型。因为将模型扩展到现实世界的脚本没有运行,因为bool'place_model'设置为false。现在,当您想要将模型扩展到现实世界时,您可以从面板中选择模型并将'place_model'bool设置为true。这很简单,因为您只需要为按钮设置事件监听器,单击按钮时将bool设置为true。下次触摸跟踪的平面时,模型会得到增强。

希望这能解决你的问题......

© www.soinside.com 2019 - 2024. All rights reserved.