keeping gameObject Positions during scene changes.

Hi,

I am developing a game where the player object enters an area and can goto the 'shop' scene when you exit from here to the game scene i would like to keep the player object at the same position as it entered but application.load seems to load the original scene.

How do you keep gameobjects at the same position during Application.LoadLevel changes ?

There are various ways to cause data to persist between scenes. Three of the most common are:

  • Use static variables
  • Use an object marked as 'don't destroy on load' (using the DontDestroyOnLoad() function)
  • Use PlayerPrefs (data stored using PlayerPrefs will persist between runs of the application as well)

I Use this Script

public class Teleport : MonoBehaviour {
	public string Scene;
	public GameObject Player;

	public float xPosition;
	public float yPosition;
	public float zPosition;

	// Use this for initialization
	void OnTriggerEnter () {
		Application.LoadLevel(Scene);
	}

	// Ketika Kembali ke Scene Sebelumnya
	void OnLevelWasLoaded () {
		Player.transform.position = new Vector3(xPosition, yPosition, zPosition);
		DontDestroyOnLoad(this);
	}
}

But I have Problem , I use DontDestroyOnLoad(this); and Every Object was spawn on the new scene ,

I have one Manager game object and script that manages a database. The database class/object stores positions, rotations of game objects. I usually just have characters and important game objects positions and rotations stored because

 [System.Serializable]
public class Database { 
    public List<Scene> Scenes = new List<Scene>();

    [System.Serializable]
    public class Scene { 
         public List<Character> Characters = new List<Character>();

         [System.Serializable]
         public class Character { 
               public string Name;
               public Vector3 position;
               public Vector3 eulerAngles;
         }
    }
}

Then just do:

public Database gameDB = new Database();

Then you make public methods inside your Database class like ‘AddCharacter’, ‘CreateCharacter’, and then you call them doing gameDB.AddCharacter(“characterNameGoesHere”);.

I usually create a Database class and a SM class (for ‘SceneManager’ but in Unity that name is taken).

You have your Scene Manager load scenes with like SceneManager.Scene_Goto(string sceneName). You have a state machine for your Scene Manager that runs through, grabs all the game objects that are characters in your scene and stores their positions and rotations on loading the scene before you reveal the scene. If you build this kind of custom scene manager you can always re-use it for multiple games as well.

Keep in mind you can’t serialize the GameObject class so you need to create your own class like this called either Character or Entity or whatever. You need to put [System.Serializable] at the beginning of each class that you want saved to a file.

You then create in your custom scene manager a save game method like sm.SaveGame(“GameName”); for example. This is where you will use a method that stores the positions and rotations of all of your game objects that are characters or entities in your scene.

What I do is name my game objects in the level editor “O_” then a game object name. I have only the game objects with this prefix have their rotations and positions stored in the database. When you save a game or load a scene you just scan through all the game objects in the scene and look for the “O_” prefix using substring like if (gameObject.name.Substring(0,2) == “O_”).

This way you won’t have this insanely large database, only the game objects with a prefix are stored to the database.

Now you can have an optional argument for your custom scene manager’s Scene_Goto() method or whatever like Scene_Goto(string sceneName, bool storeCharacterData). This now gives you the option of either storing the character data (positions and eulerAngles in this case) or not using a bool.

This is for me the most ideal way to save, just creating a custom Database class and a custom Scene Manager class for managing scenes (I still use the Unity default Scene Manager for loading, making certain scenes persistent etc… by the way).

The idea is that you want to whittle it all down to these very short simple and organized methods like this:

currentScene.GetCharacter("George").setName("Greg");

That’s the whole idea with C# object oriented programming, it makes it insanely neat, simple and organized so you have this robust easy to use means of quickly writing code in the end.