产生游戏对象时不会扫描目标

时间:2019-06-15 11:01:54

标签: unity3d vuforia

我有多个游戏对象作为ImageTarget的子对象。

自拍相机 世界中心模式= first_target 跟踪设备的姿势检查和位置

当我启动游戏模式时。

所有对象开始下落(球形碰撞器和网格渲染器关闭)。

当我扫描目标时,物体已经从我下方的平面掉落了(该平面上有一个网格碰撞器)。

如果我在启动游戏模式后立即扫描目标,一切都按计划进行,则球体将与平面碰撞并停留在其上方。

是否可以冻结对象的Y轴,直到扫描到目标为止,以及如何启用扩展跟踪(将摄像机从目标移开并重新扫描目标后,对象就会穿过飞机)

1 个答案:

答案 0 :(得分:0)

Vuforia有DefaultTrackableEventHandler ..代码很难找到(source),但看起来像这样

/*==============================================================================
Copyright (c) 2017 PTC Inc. All Rights Reserved.
Copyright (c) 2010-2014 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
Confidential and Proprietary - Protected under copyright and other laws.
==============================================================================*/

/*
 * Modified by PauloSalvatore on 04/03/2018 - 15:38 (GMT-3)
 *
 * Change Log:
 *
 * Track Events added on Inspector
 * Custom events can be added to be invoked during initialization,
 * when appear start, when object is appearing and when disappear start.
 */

using UnityEngine;
using UnityEngine.Events;
using Vuforia;

[System.Serializable]
public class TrackEvents
{
    #region PUBLIC_EVENTS

    public UnityEvent onInitialized;
    public UnityEvent onAppear;
    public UnityEvent isAppearing;
    public UnityEvent onDisappear;

    #endregion PUBLIC_EVENTS
}

/// <summary>
///     A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class DefaultTrackableEventHandler : MonoBehaviour, ITrackableEventHandler
{
    #region PUBLIC_EVENTS

    public TrackEvents trackEvents;

    #endregion PUBLIC_EVENTS

    #region PRIVATE_MEMBER_VARIABLES

    protected TrackableBehaviour mTrackableBehaviour;

    #endregion PRIVATE_MEMBER_VARIABLES

    #region UNTIY_MONOBEHAVIOUR_METHODS

    protected virtual void Start()
    {
        mTrackableBehaviour = GetComponent<TrackableBehaviour>();
        if (mTrackableBehaviour)
            mTrackableBehaviour.RegisterTrackableEventHandler(this);

        // onInitialized custom events
        if (trackEvents.onInitialized != null)
            trackEvents.onInitialized.Invoke();
    }

    protected virtual void Update()
    {
        // isAppearing custom events
        if (trackEvents.isAppearing != null)
            trackEvents.isAppearing.Invoke();
    }

    #endregion UNTIY_MONOBEHAVIOUR_METHODS

    #region PUBLIC_METHODS

    /// <summary>
    ///     Implementation of the ITrackableEventHandler function called when the
    ///     tracking state changes.
    /// </summary>
    public void OnTrackableStateChanged(
        TrackableBehaviour.Status previousStatus,
        TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED ||
            newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
            OnTrackingFound();
        }
        else if (previousStatus == TrackableBehaviour.Status.TRACKED &&
                 newStatus == TrackableBehaviour.Status.NOT_FOUND)
        {
            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
            OnTrackingLost();
        }
        else
        {
            // For combo of previousStatus=UNKNOWN + newStatus=UNKNOWN|NOT_FOUND
            // Vuforia is starting, but tracking has not been lost or found yet
            // Call OnTrackingLost() to hide the augmentations
            OnTrackingLost();
        }
    }

    #endregion PUBLIC_METHODS

    #region PRIVATE_METHODS

    protected virtual void OnTrackingFound()
    {
        var rendererComponents = GetComponentsInChildren<Renderer>(true);
        var colliderComponents = GetComponentsInChildren<Collider>(true);
        var canvasComponents = GetComponentsInChildren<Canvas>(true);

        // Enable rendering:
        foreach (var component in rendererComponents)
            component.enabled = true;

        // Enable colliders:
        foreach (var component in colliderComponents)
            component.enabled = true;

        // Enable canvas:
        foreach (var component in canvasComponents)
            component.enabled = true;

        // onAppear custom events
        if (trackEvents.onAppear != null)
            trackEvents.onAppear.Invoke();
    }

    protected virtual void OnTrackingLost()
    {
        var rendererComponents = GetComponentsInChildren<Renderer>(true);
        var colliderComponents = GetComponentsInChildren<Collider>(true);
        var canvasComponents = GetComponentsInChildren<Canvas>(true);

        // Disable rendering:
        foreach (var component in rendererComponents)
            component.enabled = false;

        // Disable colliders:
        foreach (var component in colliderComponents)
            component.enabled = false;

        // Disable canvas:
        foreach (var component in canvasComponents)
            component.enabled = false;

        // onDisappear custom events
        if (trackEvents.onDisappear != null)
            trackEvents.onDisappear.Invoke();
    }

    #endregion PRIVATE_METHODS
}

应将其放置在相应的ImageTarget或defualt afaik使用的任何目标上。如您所见,如果目标丢失,他们将禁用RendererCollider等...我个人将始终将其删除,而以UnityEvent代替,以便稍后决定应该会发生而不会发生。

由于两种方法OnTrackingFound()OnTrackingLost()virtual,因此您可以从DefaultTrackableEventHandler继承并覆盖/替换它们的功能。通过不同时调用base.OnTrackingFound()base.OnTrackingLost(),我们告诉c#执行父类最初实现的任何内容,而仅 使用我们实现的内容:

// This is used to directly pass a string value into the event
// I'll explain why later ...
[Serializable]
public class VuforiaTargetFoundEvent : UnityEvent<string, Transform> { }

public MyTrackableEventHandler : DefaultTrackableEventHandler
{
    // Give this specific VuforiaTarget a certain custom ID
    // We will pass it dynamically into the UnityEvent
    // so every listener automatically also knows WHICH target
    // was lost or found
    public string TargetID;

    public VuforiaTargetEvent _OnTrackingFound;
    public VuforiaTargetEvent _OnTrackingLost;

    protected override void OnTrackingFound()
    {
        // call _OnTrackingFound with your specific target ID and
        // also pass in the Transform so every listener can know
        // WHICH target was found and WHERE it is positioned
        _OnTrackingFound?
    }

    protected override void OnTrackingLost()
    {
        // call _OnTrackingLost with your specific target ID and
        // also pass in the Transform so every listener can know
        // WHICH target was lost and WHERE it was last positioned
        _OnTrackingLost?
    }
}

只需将其放置在Vuforia目标而不是DefaultTrackableEventHandler上(如果已经存在),因此默认情况下,儿童中的RendererCollider等均不会被禁用。 (如果您仍然需要它,您当然可以再次添加base.OnTrackingLost()base.OnTrackingFound()或在单独的脚本中实现它,并在刚添加的UnityEvents中将相应的方法作为回调引用;) )


现在要掉落的物体。首先,将useGravity设置为false,以使它们不再掉下去。找到图像目标后,将其作为回调。

public GravityEnabler : MonoBehaviour
{
    // either reference this in the Inspector ...
    public RigidBody _rigidBody;

    // also this either reference it in the Inspector ...
    public MyTrackableEventHandler target;

    // ... or get them on runtime
    private void Awake()
    {
        if(!_rigidBody) _rigidBody = GetComponent<RigidBody>();
        if(!target= target = FindObjectOfType<MyTrackableEventHandler>();

        // before start disable gravity
        _rigidBody.useGravity = false;

        // setup the callback for the target
        target._OnTrackingFound.AddListener(OnTargetScanned);
        target._OnTrackingLost.AddListener(OnTargetLost);
    }

    privtae void OnDestroy()
    {
        // If this object gets destroyed be sure to remove the callbacks
        // otherwise you would get exceptions because the callbacks
        // would still exist but point to a NULL reference
        target._OnTrackingFound.RemoveListener(OnTargetScanned);
        target._OnTrackingLost.RemoveListener(OnTargetLost);
    }

    public void OnTargetFound(string targetID, Transform targetTransform)
    {
        _rigidBody.useGravity = true;
    }

    public void OnTargetLost(string targetID, Transform targetTransform)
    {
        // If you need to do anything here
        // maybe you want to stop the falling again when the target is lost
        _rigidBody.useGravity = false;
        _rigidBody.velocity = Vector3.zero;
    }
}

将其放置在每个衰落的对象上,并尽可能在Inspector中设置引用(效率更高)。