[C#] Storing a game object between scenes

I’m reworking my Transition Manager for scene transitions. The idea is this: Player game object enters a trigger, which causes the game object to be saved to a Singleton manager, and various target information is given to that same manager (position, rotation, scene ID). When the screen fade-out is complete, the Transition Manager’s ChangeScene() method is fired, which causes the actual Application.LoadLevel() call.

When the new scene loads, another script (SceneSpawner) acquires a reference to the Transition Manager object, and (in theory) looks at the Game Object that was saved, and instances it at the target position/rotation in the new scene.

Problem is: this approach is not working. It appears that the Game Object instance is not being saved between scenes, or that when the prior scene is unloaded, the reference to the Game Object gets nuked, even though a copy is created with GameObject.Instantiate().

My code is as such:

TransitionManager.cs

using UnityEngine;
using System;
using System.Collections;

public class TransitionManager
{
	#region Variables / Properties
	
	public Vector3 spawnPosition;
	public Vector3 spawnRotation;
	public int targetSceneID = -1;
	public string targetSceneName = string.Empty;
	public GameObject playerPiece;
	
	protected static TransitionManager _Instance;
	public static TransitionManager Instance
	{
		get
		{
			return _Instance
				   ?? (_Instance = new TransitionManager());
		}
	}
	
	#endregion Variables / Properties
	
	#region Constructor
	
	protected TransitionManager()
	{
	}
	
	#endregion Constructor
	
	#region Methods
	
	public void ChangeScenes()
	{
		// If it's an intra-level transition, skip the App.LoadLevel calls!
		if(targetSceneID == Application.loadedLevel
		   || targetSceneName == Application.loadedLevelName)
		{
			throw new ApplicationException("Change Scenes should only be used for scene transitions!");
		}
		
		if(targetSceneID == -1)
		{
			Application.LoadLevel(targetSceneName);
		}
		else
		{
			Application.LoadLevel(targetSceneID);
		}
	}
	
	// Information:
	// -------------------------------------------------------------------------------
	// The following methods are responsible for the player piece being copied to the 
	// destination scene when it has loaded, via the SceneSpawner script (this script
	// is pre-set on the GameCamera prefab!)
	//
	// In the prior scene, the player's piece is acquired by the manager, which means 
	// a clone is saved to the class.
	//
	// In the target scene, when it is loaded, the SceneSpawner will Instantiate the 
	// piece, then lock the camera to it.
	
	public void AcquirePlayerPiece(GameObject piece)
	{
		if(piece == null)
			throw new ArgumentNullException("Must specify a game object to copy and transition to the new scene.");
		
		// Instantiate the copy object 10,000 WU below ground level.
		playerPiece = (GameObject) GameObject.Instantiate(piece, new Vector3(0,-10000,0), piece.transform.rotation);
	}
	
	public void InstantiateAndFocusOnPlayerPiece ()
	{
		if(playerPiece == null)
		{
			Debug.Log("No player piece was observed.");
			return;
		}
		
		GameObject piece = (GameObject) GameObject.Instantiate(playerPiece, spawnPosition, Quaternion.Euler(spawnRotation));
		if(piece == null)
			throw new Exception("Player piece was not instantiated!");
		
		var cam = (RPGCamera) GameObject.FindObjectOfType(typeof(RPGCamera));
		cam.SetTarget(piece);
	}
	
	// Information:
	// -------------------------------------------------------------------------------
	// The following methods are used when the transition is ready, for instance, when
	// the screen is fully faded and the player cannot see it.
	//
	// You give these methods the position, rotation, and scene info for the scene you
	// want to perform the transition to.  ChangeScene() will automatically call that
	// information and perform the scene swap.
	
	public void PrepareTransition(Vector3 targetPos, Vector3 targetRot, int sceneID)
	{
		SetLocationRotation(targetPos, targetRot);
		targetSceneID = sceneID;
		targetSceneName = string.Empty;
	}
	
	public void PrepareTransition(Vector3 targetPos, Vector3 targetRot, string sceneName)
	{
		SetLocationRotation(targetPos, targetRot);
		targetSceneName = sceneName;
		targetSceneID = -1;
	}
	
	private void SetLocationRotation(Vector3 targetPos, Vector3 targetRot)
	{
		spawnPosition = targetPos;
		spawnRotation = targetRot;
	}
	
	#endregion Methods
}

SceneTransition.cs

using UnityEngine;
using System.Collections.Generic;

public class SceneTransition : MonoBehaviour 
{
	#region Variables / Properties
	
	public List<string> recognizedTags;
	public Vector3 targetPosition;
	public Vector3 targetRotation;
	public int targetSceneID;
	
	private bool _TransitionInitiated = false;
	private Fader _Fader;
	private Maestro _Maestro;
	private TransitionManager _TransitionManager;
	
	#endregion Variables / Properties
	
	#region Engine Hooks
	
	void Start()
	{
		_Fader = (Fader) GameObject.FindObjectOfType(typeof(Fader));
		_Maestro = Maestro.DetectLastInstance();
		_TransitionManager = TransitionManager.Instance;
		
		_Maestro.FadeIn();
	}
	
	void FixedUpdate()
	{
		if(_Fader.ScreenHidden
		    _Maestro.IsSilent
		    _TransitionInitiated)
		{
			_TransitionManager.PrepareTransition(targetPosition, targetRotation, targetSceneID);
			_TransitionManager.ChangeScenes();
		}
	}
	
	void OnTriggerEnter(Collider who)
	{
		if(! recognizedTags.Contains(who.tag))
			return;
		
		PlayerControl controlSystem = (PlayerControl) who.GetComponent("PlayerControl");	
		controlSystem.enabled = false;
		
		_TransitionManager.AcquirePlayerPiece(who.gameObject);
		
		_Fader.FadeOut();
		_Maestro.FadeOut();
		_TransitionInitiated = true;
	}
	
	#endregion Engine Hooks
}

SceneSpawner.cs

using UnityEngine;
using System.Collections;

public class SceneSpawner : MonoBehaviour 
{
	#region Variables
	
	private TransitionManager _Transition = TransitionManager.Instance;
	
	#endregion Variables
	
	#region Engine Hooks
	
	public void Awake()
	{
		_Transition.InstantiateAndFocusOnPlayerPiece();
	}
	
	#endregion Engine Hooks
}

Is this setup even viable in the first place, or am I missing something, as I suspect I am?

Did you forget to call “DontDestroyOnLoad()”, so it wouldn’t be nuked when the new scene loads?

Nope, I didn’t think to do that! While that raises some (surmountable) issues, I’m not sure how I’m going to get around using it.

But, problem solved. Thanks!