我有多个游戏对象作为ImageTarget的子对象。
自拍相机 世界中心模式= first_target 跟踪设备的姿势检查和位置
当我启动游戏模式时。
所有对象开始下落(球形碰撞器和网格渲染器关闭)。
当我扫描目标时,物体已经从我下方的平面掉落了(该平面上有一个网格碰撞器)。
如果我在启动游戏模式后立即扫描目标,一切都按计划进行,则球体将与平面碰撞并停留在其上方。
是否可以冻结对象的Y轴,直到扫描到目标为止,以及如何启用扩展跟踪(将摄像机从目标移开并重新扫描目标后,对象就会穿过飞机)
答案 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使用的任何目标上。如您所见,如果目标丢失,他们将禁用Renderer
,Collider
等...我个人将始终将其删除,而以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
上(如果已经存在),因此默认情况下,儿童中的Renderer
,Collider
等均不会被禁用。 (如果您仍然需要它,您当然可以再次添加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中设置引用(效率更高)。