Here's my DefaultTrackableEventHandler that handles multiple scenes with multiple targets. Your main scene would contain all the targets and the ARCamera. Each scene would have a root gameobject and no camera. Async is Pro only i think, so you may have to use regular loadleveladditive. Also in this script i run an animation script when the level is loaded, you might want to remove those lines. Hope it helps.
using UnityEngine;
using System.Collections;
public class DefaultTrackableEventHandler : MonoBehaviour,
ITrackableEventHandler
{
private TrackableBehaviour mTrackableBehaviour;
private Hashtable trackables = new Hashtable();
private static string currentTrackableName = "";
private static bool loaded = false;
private static bool working = false;
public static bool lostQueued = false;
public static bool isCurrentlyTracking = false;
private const int SCENE_NAME = 0;
private const int MODEL_NAME = 1;
private const int IMAGE_TARGET_NAME = 2;
void Start()
{
mTrackableBehaviour = GetComponent<TrackableBehaviour>();
if (mTrackableBehaviour)
{
mTrackableBehaviour.RegisterTrackableEventHandler(this);
}
trackables.Add("", new string[] {"", "", "" }); //SCENE_NAME, MODEL_NAME (ROOT GAMEOBJECT), IMAGE_TARGET_NAME
trackables.Add("", new string[] {"", "", "" });
trackables.Add("", new string[] {"", "", "" });
OnTrackingLost();
}
void Update()
{
if (lostQueued)
{
OnTrackingLost();
}
}
public void OnTrackableStateChanged(
TrackableBehaviour.Status previousStatus,
TrackableBehaviour.Status newStatus)
{
if (newStatus == TrackableBehaviour.Status.DETECTED ||
newStatus == TrackableBehaviour.Status.TRACKED)
{
OnTrackingFound();
isCurrentlyTracking = true;
}
else
{
OnTrackingLost();
isCurrentlyTracking = false;
}
}
private void OnTrackingFound()
{
if (working || loaded || lostQueued)
return;
working = true;
loaded = true;
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>();
foreach (Renderer component in rendererComponents)
{
component.enabled = true;
}
foreach(DictionaryEntry t in trackables)
{
if (mTrackableBehaviour.TrackableName == t.Key.ToString())
{
string[] sa = (string[])t.Value;
currentTrackableName = t.Key.ToString();
StartCoroutine(LoadLevel(sa[SCENE_NAME], sa));
}
}
}
IEnumerator LoadLevel(string levelName, string[] levelData)
{
AsyncOperation async = Application.LoadLevelAdditiveAsync(levelName);
yield return async;
LoadLevelData(levelData[MODEL_NAME], levelData[IMAGE_TARGET_NAME]);
working = false;
}
private void OnTrackingLost()
{
if (working)
{
lostQueued = true;
return;
}
lostQueued = false;
working = true;
if (!gameObject.activeSelf)
return;
foreach(DictionaryEntry t in trackables)
{
if (currentTrackableName == t.Key.ToString())
{
string[] sa = (string[])t.Value;
DestroyLevelData(sa[MODEL_NAME]);
}
}
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>();
foreach (Renderer component in rendererComponents)
{
component.enabled = false;
}
System.GC.Collect();
working = false;
loaded = false;
}
private void LoadLevelData(string objectName, string parentName)
{
GameObject go = GameObject.Find(objectName);
if (go != null)
{
SetParent(go, parentName);
AnimationScript script = go.GetComponent<AnimationScript>();
if (script != null) {
script.begin();
}
}
}
private void SetParent(GameObject child, string parentName)
{
GameObject parent = GameObject.Find(parentName + " Plane");
if (parent != null && child != null)
{
child.transform.parent = parent.transform;
child.transform.position = parent.transform.position;
}
}
private void DestroyLevelData(string objectName)
{
GameObject go = GameObject.Find(objectName);
if (go != null)
{
AnimationScript script = go.GetComponent<AnimationScript>();
if (script != null) script.end();
Destroy(go);
}
}
}
Actaully come to find out, the unity navmesh system doesn't allow loading a navmesh from another scene using LoadLevelAdditive. So although this works well for Vuforia's purposes, I can't use it for my original problem. Oh well, thanks for the help though.