Replacing objects in new scenes???

Hello,
I was wondering if Unity has a feature where IF an object has a ‘DontDestroyOnLoad()’ constraint on it and a new scene loads, and the new scene has an object of the same name or same tag, the object from the other scene ‘replaces’ the object from the new scene, but keeps the position, rotation and scaling of the object that gets replaced. Wouldn’t that be a great feature?

Sincerely,
Michael S. Lowe

It would, but it would also be a very specific one. :wink: How about just something simple like this:

public class Highlander : MonoBehaviour { //there can be only one
    void Awake(){
        DontDestroyOnLoad();
        GameObject previous = GameObject.Find("Highlander"); //finds by name; Can also use FindWithTag() or FindObjectOfType()
        if(previous != null){
            transform.position = previous.transform.position;
            transform.rotation = previous.transform.rotation;
            //etc.
            Destroy(previous);
        }
    }
}

Untested, but you get the idea I’m sure.

EDIT: Oops, I went the other way around, but same idea. Either set previous.transform.position to transform.position and so on and then destroy itself, call a function on previous that aligns it with the new one, or use OnLevelWasLoaded() instead of Awake().

On a sidenote, this kind of question really should be over in the Scripting forum. =)

… but how does Unity know WHICH “highlander” to look for after the new scene loads (with another “Highlander” object already in it), one “Highlander” that did not destroy on load, and the other already in the scene?

Ah, you’re right! Seems I typed that post in too much of a hurry, apologies. All the Find() functions also have variants that return multiple matches though. You could use that, and then iterate over the results to see which one matches the one running the search. Iirc (could be wrong here) Awake() will only be called on the new Highlander, and OnLevelWasLoaded() only on the old one, so that way you’re only running the search once. Alternatively you could set a bool in your Highlander script, indicating whether or not it’s “new”.

Then, how would I also have all the scripts in the loaded scene that have variables that reference to the game objects within that scene, re-link itself to the ‘replaced’ game objects that didn’t destroy on load, without having to do a whole bunch of re-scripting on each C# script in order for that to happen? That is why ReplaceOnLoad() should be a considered new added feature to save developers some time and coding. Then, wherever the “player” object is inside the scenes that are to be loaded, the player that doesn’t get destroyed from the main scene gets placed there once the scene loads. I think that would be a great feature to add.

Hmm, ok, I see what you’re saying. It’s still hard to generalize though. In the case of a player for instance, should the player physically move, or just replace all references?

For now though, is it an option for you to remove all Players from your scene except the first, and instead of an object having a public/ serialized “Player player” field just do a search on Awake()?

The player should both physically move and the other objects that access “Player” in that scene should re-link itself to the replaced object instead of it being a “Missing” object.