- Home /
How to not duplicate game objects on DontDestroyOnLoad?
So I am making a 2D RPG game. When I load a new scene, I have DontDestroyOnLoad() attached to my player script, this is so that my players (soon to be) stats and equipment will not be removed. However, when I go back to the starting scene, where my player spawned, it duplicates the player every time the scene is laoded. Any Suggestions? Here is my code. Any help would be nice, thanks.
using UnityEngine;
using System.Collections;
public class Player : Entities {
void Start () {
DontDestroyOnLoad (this);
}
void Update ()
{
if (Input.GetKey (KeyCode.W))
{
GetComponent<Rigidbody2D>().transform.position += Vector3.up * speed * Time.deltaTime;
}
if (Input.GetKey (KeyCode.A))
{
GetComponent<Rigidbody2D>().transform.position += Vector3.left * speed * Time.deltaTime;
}
if (Input.GetKey (KeyCode.S))
{
GetComponent<Rigidbody2D>().transform.position += Vector3.down * speed * Time.deltaTime;
}
if (Input.GetKey (KeyCode.D))
{
GetComponent<Rigidbody2D>().transform.position += Vector3.right * speed * Time.deltaTime;
}
}
}
Answer by zaid87 · Jun 08, 2015 at 10:20 AM
One way is to have a static instance variable of the class in the class itself and use it to check whether you should destroy it or not. Example:
private static Player playerInstance;
void Awake(){
DontDestroyOnLoad (this);
if (playerInstance == null) {
playerInstance = this;
} else {
DestroyObject(gameObject);
}
}
Another one I can think of is to create another class that holds the stats values and refer to that everytime you load up the level.
thanks man, it works. But actually object gets created then you check and destroy it.It was creating some problem for me. I did little change in your code. With this object is not getting recreated only.
private static Player playesInstance; void Awake(){ if (playerInstance == null) { DontDestroyOnLoad (this); playerInstance = this; } }
I'm having a problem with this where my original object will delete itself and the new copy stays but the new one is missing all its References.
poss creo que me pasaba algo similar y para encontrar las referencias ponía esto en el metodo start :
public comprarPez com;
com = GameObject.Find("Comprarpez1").GetComponent();
nota: con GameObject.Find(" ") vas a poder encontrar tu referencia otra vez, no sé si esto ayude a alguien pero aquí lo dejo.
Answer by BlankSlates · Jul 13, 2018 at 01:27 AM
public class MusicPlayer : MonoBehaviour
{
private void Awake()
{
int numMusicPlayers = FindObjectsOfType<MusicPlayer>().Length;
if (numMusicPlayers != 1)
{
Destroy(this.gameObject);
}
// if more then one music player is in the scene
//destroy ourselves
else
{
DontDestroyOnLoad(gameObject);
}
}
I don't know why this got down-voted. Worked perfectly for me!
I have a similar situation like yours. The problem is that each time I come back to the main menu where I can adjust the volume of the music player with a silder I can not change it anymore. Changing is only possible when main menu is loaded the first time. do you know what the problem could be here?
did you ever find a solution to this? I'm having the same problem
Answer by junedmmn · Mar 08, 2019 at 10:40 AM
Use this, this is the simplest way.
private static GameObject instance;
void Start()
{
DontDestroyOnLoad(gameObject);
if (instance == null)
instance = gameObject;
else
Destroy(gameObject);
}
You can use this.gameobject
wherever gamebject
is written in the code above, as gameobject
in the script directly refers to the GameObject that this component is attached to. So to optimize the code, I have used directly gameobject
.
This is literally the accepted answer for the question, you've just repeated it and bumped up the thread pointlessly.
The one given above was not working, I tested it. So I modified the solution and posted it.
Answer by $$anonymous$$ · Jun 08, 2015 at 11:05 AM
Make a GameObject named for example _GM ( Game manager ) and place it in your first scene, but no other. Make an empty GameObject for your spawn position, or just simply check the Vector3 coordinates where you'd like to spawn.
In the start method of _GM do this:
Void Start()
{
DontDestroyOnLoad(this)
//Position to spawn your player
Vector3 position = GameObject.Find("SpawnPoint").transform.position;
//If your player prefab doesn't exist in the scene, then instantiate it
if (GameObject.Find("Player") == null)
{
GameObject player = Instantiate(player, position, Quaternion.rotation) as GameObject;
}
}
If you switch scenes then you can either:
1.)reinstantiate it at a new position
2.)set the position of your player again, but you have to attach the DontDestroyOnLoad script to it aswell if your going with the 2nd method!
For Instantiating prefabs, check this reference: http://docs.unity3d.com/ScriptReference/Object.Instantiate.html
But when I do this, it looks like the new instantiation is missing its assembly references, how can I make it so this doesn't happen?
Answer by $$anonymous$$ · Jul 12, 2018 at 11:34 PM
This is unrelated but for player movement try...
using UnityEngine;
using System.Collections;
public class Player : Entities {
public float speed = 10;
void Update ()
{
GetComponent<Rigidbody2D>().velocity = new Vector2(speed * Input.GetAxisRaw("Horizontal"), speed * Input.GetAxisRaw("Vertical"));
}
}