DontDestroyOnLoad should only be used in game objects that lives to scene unloading. If you only use the GameCanvas in the Game scene, remove the DontDestroyOnLoad.
If you’r concerned about having 2 instances of a UnityEngine.UI.Canvas, don’t be. There is no problem at all of having multiples instances of the Canvas class.
Use Singleton for your Canvas, since you want it to persist over different scenes. It will handle multiple copies of your canvas object, as well as provide you a global access point for accessing your UI related scripts. Preferably, keep a Singleton UIManager script at root of your canvas and access things via the UIManager class.
using UnityEngine;
using System.Collections;
public class Singleton<T> : MonoBehaviour where T: MonoBehaviour {
private static T _instance;
public static T instance
{
get
{
if (_instance == null)
{
_instance = GameObject.FindObjectOfType<T>();
//Tell unity not to destroy this object when loading a new scene!
DontDestroyOnLoad(_instance.gameObject);
}
return _instance;
}
}
public static bool HasInstance
{
get
{
return _instance != null;
}
}
protected virtual void Awake()
{
if (_instance == null)
{
//If I am the first instance, make me the Singleton
_instance = this as T;
DontDestroyOnLoad(this);
}
else
{
//If a Singleton already exists and you find
//another reference in scene, destroy it!
if (this != _instance)
Destroy(this.gameObject);
}
}
}
So now your UIManager would be something like this:
public class UIManager : Singleton<UIManager>
{
[HideInInspector]
public GameUI _gameUI;
public GameUI ShowGameUI()
{
if(_gameUI == null)
{
_gameUI = //Instantiate GameUI from resources...
}
return _gameUI;
}
}
And you would use it like this somewhere in your code: UIManager.instance.ShowGameUI();