0

I made a script that spawns (instantiates) random game objects at random positions in a scene, on a Start(). But I have two problems:

  1. If I change scene and I come back, the instantiated objects are not there anymore, i.e., they are not permanent. How do I make them permanent like those objects I placed in the scene through the Unity editor? I'm not talking about dontdestroyonload, which keeps the objects across all scenes and never destroys them.

  2. My spawn script, which I want to run only once when the scene is loaded for the first time, runs every time I come into the scene instead, even if I added a line in the script that destroys both the script and the parent game object. I want it to run once and be gone forever. How does one do that?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Learner
  • 13
  • 1
  • 4

5 Answers5

0

Save the position using PlayerPrefs and then read it:

//Write
PlayerPrefs.SetFloat("PlayerX", player.transform.position.x);
PlayerPrefs.SetFloat("PlayerY", player.transform.position.y);
PlayerPrefs.SetFloat("PlayerZ", player.transform.position.z)

//Read
var x = PlayerPrefs.GetFloat("PlayerX");
var y = PlayerPrefs.GetFloat("PlayerY");
var z = PlayerPrefs.GetFloat("PlayerZ");

//Apply
Vector3 posVec = new Vector3(x,y,z);
player.transform.position = posVec;
David
  • 15,894
  • 22
  • 55
  • 66
  • Hi, thanks for your help. To add some clarifications, what I need is to spawn objects at runtime, and the objects should stay there permanently, so when the player changes scene and comes back, the objects are still there. Like say I spawn a monster in a cave, the monster should be there when the player comes back. But if I understand correctly, playerprefs would be: the monster stay there across all save games? The monster only needs to stay there in their respective save games, like all other things. – Learner Apr 07 '18 at 23:20
0

Why exactly do you want to keep the objects when you leave the scene? Wouldn't it then be easier for you to get a Unity Editor Extension to generate the random objects? Then you can just generate the objects whenever you want and save them to the scene.

If you use an Editor Extension, you don't have to worry about the Start() either.

Edit: Based on your comments, it looks like what you need is a save/load system where you store the ID's and positions of the generated objects upon leaving the scene, then load it back in when you return to the scene. It is impossible to save a runtime scene as a scene file as it is compiled into the data of your game.

The easiest way to do it would be to get a system from the asset store, and based on your self-proclaimed inexperience, that may be the best option for you.

Otherwise, you'll have to make it yourself. How to do that is answered in this question: What is the best way to save game state?

To summarize what is said there: You'll have to make a class that will allow you to save the data to a file. This can be done by using the BinaryFormatter in Unity. Though there are many more options, like XML.

basklein
  • 365
  • 3
  • 15
  • I solved problem #2, but #1 remains. To add some clarifications, what I need is to spawn objects at runtime, and the objects should stay there permanently, so when the player changes scene and comes back, the objects are still there. Like say I spawn a monster in a cave, the monster should be there when the player comes back. Currently my monsters spawn, but when I come back to the scene, they are gone. I want to save them permanently in the save game, I'm not sure how to do that, I'm a complete noob. I've looked at playerprefs, not sure if that's the right solution though. – Learner Apr 07 '18 at 23:23
  • I edited my answer with a link to another question that covers the same problem. What you want to do, is basically put all the objects you want to save in a list, then assign object ID's to the different prefabs used, get the position of all of the objects and save that data to a file. – basklein Apr 09 '18 at 12:40
  • Thanks, I'll look into that. – Learner Apr 11 '18 at 04:04
0

You can add an ExecuteInEditMode attribute to your class. If you do not want it's logic to execute on scene being loaded - surround this logic with if(!Application.isPlaying).

Having said that - I would rather make an editor tool, an inspector button, a context menu - anything like that would be better in my opinion.

pdeschain
  • 1,411
  • 12
  • 21
0

I would create a JSON file in your assets that contains a JsonArray with each object with its scene, filepath and its location/rotation. Every time you switch to a new file, it loops through all of them and if the scene its from is not the scene that's stored it doesn't store it. If it is, then it parses the json object inside and places a new object with the location and rotation settings.

Here's some pseudocode if that made no sense:

To Load:

jsonArray = parseJsonArray

foreach Json object inside of jsonArray

  if object["scene"] = currentscene

     intantiate new object and set properties to properties that are parsed by the json file

To Save:

Convert Array of all of the gameObjects to jsonArray

Write Json Array => json file
0

This appears to be the solution:

public static void UnpackPrefabInstance(GameObject instanceRoot, PrefabUnpackMode unpackMode, InteractionMode action);    

from: https://docs.unity3d.com/ScriptReference/PrefabUtility.UnpackPrefabInstance.html

jannone
  • 41
  • 3