当PlaneFinderBehaviour使用Vuforia 7接收输入时触发自定义方法

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

今天我开始用Vuforia 7和它的Ground Plane / Plane Finder功能尝试一些东西。我做了在Vuforia网站上找到的简单示例,现在我正在尝试用它创建一个简单的应用程序。

我想要完成的是,当Vuforia PlaneFinderBehaviour检测到一个平面时,我想在屏幕上显示一个工具箱,用户可以在几个原始3D游戏对象(Cube,Sphere,Cilinder)之间进行选择。选择所需的3D GameObject后,我希望它出现在Vuforia检测到的地面上。接下来,当走动并且Vuforia再次检测到地面时,需要出现相同的工具箱,用户可以选择将不同类型的3D GameObject放置在地面上。

在Unity中乱搞之后,我仍然没有设法用Vuforia检测到地面时需要触发的方法创建我自己的PlaneFinderBehaviour C#脚本。

我做了什么:

  • 创建了一个扩展PlaneFinderBehaviour的C#脚本,并且有一个名为CustomPerformHitTest的方法,它只是在控制台中打印一些内容。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Vuforia;

public class CustomPlaneFinderBehaviour : PlaneFinderBehaviour
{
    public void CustomPerformHitTest(Vector2 screenPosition)
    {
        print("CustomPlaneFinderBehaviour > CustomPerformHitTest has been triggered");
    }
}
  • 用我的自定义脚本替换了PlaneFinder GameObject的默认PlaneFinderBehaviour

CustomPlaneFinderBehaviour

有人可以向我发送正确的方向并解释Vuforia飞机检测是如何工作的,以便让我了解我做错了什么。

谢谢!

c# unity3d vuforia
1个回答
3
投票

您不需要自定义平面查找器行为来实现此目的。只需使用标准OnAutomaticHitTest的基本事件PlaneFinderBehaviour

OnAutomaticHitTest在检测到飞机的每一帧都会发射。因此,您可以使用此事件切换工具箱。 (如果事件是在最后一帧中被触发的话,以某种方式记录。例如,如果事件被触发,你可以记录帧数,然后在LateUpdate函数中进行比较。如果帧数匹配,你知道当前检测到一个平面,如果没有......然后不是。)

然后,如果您的工具箱已显示且您的用户与之交互,则只需触发PerformHitTest的公共方法PlaneFinderBehaviour。该方法从给定的屏幕位置拍摄光线并返回地平面上的相应位置。如果这个方法成功,另一个名为PlaneFinderBehaviourOnInteractiveHitTest事件会被解雇。

收听此事件,然后定位/生成如下内容:

public class CustomContentPositioningBehaviour : MonoBehaviour
{
    public GameObject yourContentPrefab;

    private PositionalDeviceTracker deviceTracker;
    private GameObject previousAnchor;

    public void Awake()
    {
        VuforiaARController.Instance.RegisterVuforiaStartedCallback( OnVuforiaStarted );
    }

    public void OnDestroy()
    {
        VuforiaARController.Instance.UnregisterVuforiaStartedCallback( OnVuforiaStarted );
    }

    private void OnVuforiaStarted()
    {
        deviceTracker = TrackerManager.Instance.GetTracker<PositionalDeviceTracker>();
    }

    public void SpawnContent( HitTestResult result )
    {
        if( result == null || yourContentPrefab == null)
        {
            Debug.LogWarning( "Hit test is invalid or content is not set" );
            return;
        }

        var anchor = deviceTracker.CreatePlaneAnchor( Guid.NewGuid().ToString(), result );
        if( anchor != null )
        {
            anchor.transform.parent = this.gameObject.transform;

            GameObject content = Instantiate( yourContentPrefab );

            content.transform.parent = anchor.transform;
            content.transform.localPosition = Vector3.zero;
            content.transform.localRotation = Quaternion.identity;
            content.SetActive( true );
        }

        if( previousAnchor != null )
        {
            Destroy( previousAnchor );
        }

        previousAnchor = anchor;
    }
 }

SpawnContentOnInteractiveHitTest事件处理程序调用。如果您有不同类型的内容,您当然需要在此方法中区分它们。

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