- Home /
Don't destroy on load not working?
I randomly create a grid based world using this script. However if my player enters a building, then returns to the over world it is still recreated.
using UnityEngine;
using System.Collections;
public class CubeGrid : MonoBehaviour {
public GameObject border;
public GameObject grassLand;
public GameObject house;
public GameObject city;
public GameObject tree;
public GameObject wolf;
public GameObject bandit;
public int randNum = 0;
public int xCubes;
public int zCubes;
public bool fighting = false;
public bool enterWolf = false;
void Start () {
GenerateLandscapeAndObjects(xCubes,zCubes);
GenerateBorder(xCubes,zCubes);
}
void Awake() {
DontDestroyOnLoad(transform.gameObject);
}
private void GenerateLandscapeAndObjects(int xMax, int zMax) {
//create a GameObject to contain the landscape and objects
//to keep things neat in the Hierarchy tab if you decide
//to start generating huge landscapes later on
GameObject landscape = new GameObject("Landscape and Objects");
for ( int z = 0; z < zMax; z++ )
{
for ( int x = 0; x < xMax; x++ )
{
float rnd = Random.value;
if ( rnd < 0.01 )
{
DoInstantiate(city, new Vector3(x, 0, z), Quaternion.identity,landscape.transform);
}
else if (rnd < 0.07)
{
DoInstantiate(tree, new Vector3(x,0,z), Quaternion.identity,landscape.transform);
}
else if ( rnd < 0.15 )
{
DoInstantiate(house, new Vector3(x, 0, z), Quaternion.identity,landscape.transform);
}
else
{
DoInstantiate(grassLand, new Vector3(x, 0, z), Quaternion.identity,landscape.transform);
randNum = Random.Range(0,50);
if(randNum <= 3){
DoInstantiate(wolf,new Vector3(x,0,z), Quaternion.identity,landscape.transform);
}
else if(randNum ==4){
DoInstantiate(bandit, new Vector3(x,0,z), Quaternion.identity,landscape.transform);
}
}
}
}
}
private void GenerateBorder(int xMax, int zMax) {
//create a GameObject to contain the border
//to keep things neat in the Hierarchy tab if you decide
//to start generating huge landscapes later on
GameObject borderGameObject = new GameObject("Landscape and Objects");
//create border blocks along x axes
for ( int x = 0; x < xMax; x++ )
{
DoInstantiate(border, new Vector3(x,1,0), Quaternion.identity,borderGameObject.transform);
DoInstantiate(border, new Vector3(x,1,zMax), Quaternion.identity,borderGameObject.transform);
}
//create border blocks along z axes
for ( int z = 0; z < zMax; z++ )
{
DoInstantiate(border, new Vector3(0,1,z), Quaternion.identity,borderGameObject.transform);
DoInstantiate(border, new Vector3(xMax,1,z), Quaternion.identity,borderGameObject.transform);
}
}
//A helper function to let you organise GameObjects easily in
//the hierarchy by setting the transform.parent of the instantiated prefab.
private void DoInstantiate(GameObject prefab, Vector3 position, Quaternion rotation, Transform parent) {
Transform temp = ((GameObject)Instantiate(prefab,position,rotation)).transform;
temp.parent = parent;
}
}
Example script for being inside a house
using UnityEngine;
using System.Collections;
public class InnCameraScript : MonoBehaviour {
void OnGUI(){
if(GUI.Button(new Rect(10,400,1200,100), "Leave the tavern.")){
Application.LoadLevel("Map Creator");
}
}
}
Can someone tell me why don't destroy isn't working?
DontDestroyOnLoad
doesn't prevent the object from being reloaded from the scene. It just prevents it from being destroyed when loading a new scene.
Jesus, please don't include the code that isn't releavent. Use common sense, public int cubeX
isn't the issue.
Answer by fendorio · Apr 17, 2014 at 03:58 AM
What's happening is another is being created. You could add this to your script to make it persistent and destroy further objects of the same type that get created on loading the scene again.
//Needs to be static.
private static bool spawned = false;
void Awake()
{
if(spawned == false)
{
spawned = true;
DontDestroyOnLoad(gameObject);
//Code...
}
else
{
DestroyImmediate(gameObject); //This deletes the new object/s that you
// mentioned were being created
}
}
So yeah what's happening here is that the first time you create this, spawned is false. So the first object makes a call to the DontDestroyOnLoad(), which as the name suggests, means the first object will persist through scenes.
This is why we set the static bool spawned to true, static meaning it's 'shared' between all instances of this object.
Now when you load that scene again, 'it's' going to create another GameObject of this type, along with everything else in the hierarchy.
So the second time you load this scene, a second instance of the GameObject is created, however because the first GameObject set the static bool spawned to true, it's true when the second GameObject is created, thus the else block is entered and the second object is destroyed :)
Alright I understand what you've written does, but where you've put //code am I actually moving anything there? If I just use this code verbatim when I return to the world its completely gone. The old world is gone and no new world is spawned.
Sorry for the late reply. Get rid of either your start or awake?
static bool spawned = false;
void Start ()
{
if(spawned == false)
{
spawned = true;
DontDestroyOnLoad(gameObject);
GenerateLandscapeAndObjects(xCubes,zCubes);
GenerateBorder(xCubes,zCubes);
}
else
{
DestroyImmediate(gameObject);
}
}
void Awake()
{
//Leave this empty and try that.
}
Hey no problem, thanks for offering the help! This still does the same thing though unfortunately. I also tried moving it to awake but it still does it.
I'm still looking for help with this if anyone knows why it won't work :(
So I think part of your issue is that you creating lots of GameObjects here and it's likely those GameObjects aren't part of the hierarchy attached to this GObj w/ DontDestroy; if it won't wreck your world you could change the instantiated object transform.parent to this GObj and see if you are getting different results.
Answer by honor0102 · Oct 05, 2021 at 05:36 PM
Pretty old topic and its even answered but i think there is something good to mention and may help someone
DontDestroyOnLoad only works for root game objects or components of a root game object
this means that your gameObject should not have any parent object
Answer by iamsidv · Aug 12, 2014 at 10:47 AM
@Razputin There is a SILLY MISTAKE here...
Let me help you and this will definitely work.
void Awake()
{
if(spawned == false)
{
spawned = true;
DontDestroyOnLoad(gameObject);
//Code...
return; //<--- YOU HAVE TO PUT RETURN HERE.
// BECAUSE once the value is true, it will go in the else condition
//So we have to stop letting it go in the another condition.
}
else
{
Destroy(gameObject); //This deletes the new object/s that you
// mentioned were being created
}
}
Hope it helps out.
You actually would not need the return there. Once you are inside the if statement you can't get into the else statement without rechecking the if statement which would only happen if another gameObject was created.
Answer by unity_VYAo9PCTYYamFA · Jun 11, 2021 at 11:50 AM
Put it in First line of Awake function it will solve. because it need to execute first