I have a script accessing an instantiated game object of Vuforia from Hierarchy and adding a component to it:
IEnumerable<TrackableBehaviour> tbs = TrackerManager.Instance.GetStateManager().GetTrackableBehaviours();
foreach (TrackableBehaviour tb in tbs)
{
if (tb.TrackableName == "Fashion")
{
if (tb.name == "New Game Object")
{
// change generic name to include trackable name
tb.gameObject.name = ++counter + "DynamicImageTarget-" + tb.TrackableName;
// add additional script components for trackable
tb.gameObject.AddComponent<DefaultTrackableEventHandler>();
tb.gameObject.AddComponent<TurnOffBehaviour>();
Up to here it is working but at this point/line when i try to add
tb.gameObject.GetComponent<DefaultTrackableEventHandler>().OnTargetFound.AddListener(DressFound);
is throwing null exception in runtime
When I try
tb.gameObject.GetComponent<DefaultTrackableEventHandler>().OnTargetFound.RemoveAllListeners();
throwing null exception in runtime as well
However when i try
tb.gameObject.GetComponent<DefaultTrackableEventHandler>().enable = false;
it is working and disabling script component
void DressFound()
{
augmentation.SetActive(true);
}
Why i can't reach events on the script?
/*============================================================================== Copyright (c) 2019 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. ==============================================================================*/
using UnityEngine;
using UnityEngine.Events;
using Vuforia;
/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
///
/// Changes made to this file could be overwritten when upgrading the Vuforia version.
/// When implementing custom event handler behavior, consider inheriting from this class instead.
/// </summary>
public class DefaultTrackableEventHandler : MonoBehaviour
{
public enum TrackingStatusFilter
{
Tracked,
Tracked_ExtendedTracked,
Tracked_ExtendedTracked_Limited
}
/// <summary>
/// A filter that can be set to either:
/// - Only consider a target if it's in view (TRACKED)
/// - Also consider the target if's outside of the view, but the environment is tracked (EXTENDED_TRACKED)
/// - Even consider the target if tracking is in LIMITED mode, e.g. the environment is just 3dof tracked.
/// </summary>
public TrackingStatusFilter StatusFilter = TrackingStatusFilter.Tracked_ExtendedTracked_Limited;
public UnityEvent OnTargetFound;
public UnityEvent OnTargetLost;
protected TrackableBehaviour mTrackableBehaviour;
protected TrackableBehaviour.Status m_PreviousStatus;
protected TrackableBehaviour.Status m_NewStatus;
protected bool m_CallbackReceivedOnce = false;
protected virtual void Start()
{
mTrackableBehaviour = GetComponent<TrackableBehaviour>();
if (mTrackableBehaviour)
{
mTrackableBehaviour.RegisterOnTrackableStatusChanged(OnTrackableStatusChanged);
}
}
protected virtual void OnDestroy()
{
if (mTrackableBehaviour)
{
mTrackableBehaviour.UnregisterOnTrackableStatusChanged(OnTrackableStatusChanged);
}
}
void OnTrackableStatusChanged(TrackableBehaviour.StatusChangeResult statusChangeResult)
{
m_PreviousStatus = statusChangeResult.PreviousStatus;
m_NewStatus = statusChangeResult.NewStatus;
Debug.LogFormat("Trackable {0} {1} -- {2}",
mTrackableBehaviour.TrackableName,
mTrackableBehaviour.CurrentStatus,
mTrackableBehaviour.CurrentStatusInfo);
HandleTrackableStatusChanged();
}
protected virtual void HandleTrackableStatusChanged()
{
if (!ShouldBeRendered(m_PreviousStatus) &&
ShouldBeRendered(m_NewStatus))
{
OnTrackingFound();
}
else if (ShouldBeRendered(m_PreviousStatus) &&
!ShouldBeRendered(m_NewStatus))
{
OnTrackingLost();
}
else
{
if (!m_CallbackReceivedOnce && !ShouldBeRendered(m_NewStatus))
{
// This is the first time we are receiving this callback, and the target is not visible yet.
// --> Hide the augmentation.
OnTrackingLost();
}
}
m_CallbackReceivedOnce = true;
}
protected bool ShouldBeRendered(TrackableBehaviour.Status status)
{
if (status == TrackableBehaviour.Status.DETECTED ||
status == TrackableBehaviour.Status.TRACKED)
{
// always render the augmentation when status is DETECTED or TRACKED, regardless of filter
return true;
}
if (StatusFilter == TrackingStatusFilter.Tracked_ExtendedTracked)
{
if (status == TrackableBehaviour.Status.EXTENDED_TRACKED)
{
// also return true if the target is extended tracked
return true;
}
}
if (StatusFilter == TrackingStatusFilter.Tracked_ExtendedTracked_Limited)
{
if (status == TrackableBehaviour.Status.EXTENDED_TRACKED ||
status == TrackableBehaviour.Status.LIMITED)
{
// in this mode, render the augmentation even if the target's tracking status is LIMITED.
// this is mainly recommended for Anchors.
return true;
}
}
return false;
}
protected virtual void OnTrackingFound()
{
if (mTrackableBehaviour)
{
var rendererComponents = mTrackableBehaviour.GetComponentsInChildren<Renderer>(true);
var colliderComponents = mTrackableBehaviour.GetComponentsInChildren<Collider>(true);
var canvasComponents = mTrackableBehaviour.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;
}
if (OnTargetFound != null)
OnTargetFound.Invoke();
}
protected virtual void OnTrackingLost()
{
if (mTrackableBehaviour)
{
var rendererComponents = mTrackableBehaviour.GetComponentsInChildren<Renderer>(true);
var colliderComponents = mTrackableBehaviour.GetComponentsInChildren<Collider>(true);
var canvasComponents = mTrackableBehaviour.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;
}
if (OnTargetLost != null)
OnTargetLost.Invoke();
}
}
The issue seems to be that both UnityEvent
s are not assigned in the case the component is attached on runtime via AddComponent
.
Usually these are assigned to automatically by the Unity Inspector since they are serialized.
To be sure you could simply initialize them always using
public UnityEvent OnTargetFound = new UnityEvent();
public UnityEvent OnTargetLost = new UnityEvent();