- Home /
Persistent GameObject Between scene Without Serilization
Hello, Here my purpuse : I want to keep GameObject in a Dictionnary.
Problem : When I changed scene my GameObject in my Dictionnary become null.
What I tried : Clone / Duplicate / Instantiate - And DontDestroyOnLoad (but just cloning objects in other scene. If then I destroy them, GameObject will be null too).
MapController : Save, Load, GameObject with Tag MapController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MapController : MonoBehaviour {
private GameObject[] respawns;
private GameObject[] destroy;
string currentSceneName;
public static MapController instanceRef;
// Singleton for change Scene
void Awake()
{
Debug.Log("Awake");
if (instanceRef == null)
{
instanceRef = this;
DontDestroyOnLoad(gameObject);
}
else
{
DestroyImmediate(gameObject);
}
}
// LoadData -- When player Enter in NewScene
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
currentSceneName = SceneManager.GetActiveScene().name;
Debug.Log("currentSceneName " + currentSceneName);
if (MapDatabase.Instance.getDictionnaryDB().ContainsKey(currentSceneName))
{
respawns = MapDatabase.Instance.getObjectsByKey(currentSceneName);
DestroySceneObject();
LoadDataDB();
}
}
// Call When just before SceneLoader (other class)
public void CommitDataDB()
{
Debug.Log("CommitDataDB ");
respawns = GameObject.FindGameObjectsWithTag("MapController");
// foreach (GameObject respawn in respawns)
// {
// Debug.Log("CommitDataDB respawn " + respawn);
// DontDestroyOnLoad(respawn);
// }
Debug.Log("currentSceneName CommitDataDB" + currentSceneName);
MapDatabase.Instance.setObjectsByKey(SceneManager.GetActiveScene().name, respawns);
}
// Want to destroy object already in scene
public void DestroySceneObject()
{
destroy = GameObject.FindGameObjectsWithTag("MapController");
foreach(GameObject d in destroy)
{
Destroy(d);
}
}
// Load Data when enter in new scene
public void LoadDataDB()
{
foreach (GameObject respawn in respawns)
{
Debug.Log("respawn " + respawn);
Instantiate(respawn, respawn.transform.position, respawn.transform.rotation);
}
}
// Event for SceneLoad
void OnEnable()
{
Debug.Log("OnEnable called");
SceneManager.sceneLoaded += OnSceneLoaded;
}
// Just Disable Event when finished
void OnDisable()
{
Debug.Log("OnDisable");
SceneManager.sceneLoaded -= OnSceneLoaded;
}
}
MapDatabase : Dictionnary, store information.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapDatabase {
private static readonly MapDatabase instance = new MapDatabase();
Dictionary<string, GameObject[]> dictionnaryDB = new Dictionary<string, GameObject[]>();
static MapDatabase()
{
}
public static MapDatabase Instance
{
get
{
return instance;
}
}
public Dictionary<string, GameObject[]> getDictionnaryDB()
{
return dictionnaryDB;
}
public GameObject[] getObjectsByKey(string key)
{
return dictionnaryDB[key];
}
public void setObjectsByKey(string key, GameObject[] respawn)
{
dictionnaryDB[key] = respawn;
}
}
If you find a better way (optimization) to just DestroyAll then LoadAll (I mean go for Delta Object) i'm interest too. But I think if i do Observable or Loop over Object for controle if Object is still in same position, angle, etc ... This cost time too
Answer by OlivierROGER · May 04, 2018 at 01:02 PM
Ok I found a solution with InactiveObject.
Not the best solutions (waiting for serialization methods)