- Home /
Spawn Objects randomly and save their locations
Hey guys, I'm working on a garden project, where I use UnityWebRequest to download an assetbundle from online that contains a lot of of assets ( about 50 assets and will increase ) in runtime. I want to spawn these assets in the assetbunlde at "random" locations for first time it loads, but after it's spawned in the location, it will stay there and the next time the application is ran, the assets will still spawn at same locations they did. Of course I can set the location manually for each asset... but that would be a pain. I've been trying to think of a way to automate the locations but still don't have a clear approach on this, so any help or suggestion would really help. thank you!
Answer by Llama_w_2Ls · Jul 30, 2020 at 08:57 AM
float randomX;
float randomZ;
void SpawnInRandomPositions()
{
AssetBundle[] assets = FindObjectsOfType<AssetBundle>();
//Create list of all assets in assetbundle
for (int i = 0; i < assets.Length; i++)
{
randomX = UnityEngine.Random.Range(-10, 10);
randomZ = UnityEngine.Random.Range(-10, 10);
//autogenerates a random position on the x and z axis
Instantiate(assets[i], new Vector3(randomX, 1, randomZ), Quaternion.identity);
//spawns those objects at a random position every time
}
}
Is this what you wanted?
Hi, thank you for your answer, however, that's not what I meant. I want for each asset to have a fixed position that they will always spawn in, instead of spawning at random position every time. Since I have too many assets, it's not really ideal to assign location for each asset, so I wanted to ask if there's anyway to automatically assign the location for each asset and save them so that the assets will always spawn at the same locations every time the game starts, and if a new asset is added to the assetbundle, it will be assigned a new location that's not taken and stays there.
$$anonymous$$aybe this but as an editorscript? I'm not sure how but if you manage to do it you could run the script before building.
Sorry for taking so long to respond. but I guess you could replace it with the i variable. This means the first object spawns at (1, 0, 1) and the second at (2, 0, 2) etc. float randomX; float randomZ;
void SpawnInRandomPositions()
{
AssetBundle[] assets = FindObjectsOfType<AssetBundle>();
//Create list of all assets in assetbundle
for (int i = 0; i < assets.Length; i++)
{
randomX = i;
randomZ = i;
//autogenerates a random position on the x and z axis
Instantiate(assets[i], new Vector3(randomX, 1, randomZ), Quaternion.identity);
//spawns those objects at a random position every time
}
}
Im not very experienced in editorscripting, so I dont think I could help you with your second request. Sorry @giangvubinhn
Answer by Aviryx · Aug 12, 2020 at 10:19 PM
What you are asking for isn't exactly simple. You want to use data persistence in order to persist data between sessions. This requires using a binary formatter, serializing and deserializing data (ideally using Scriptable Objects to store the data in transit/during gameplay) so it might be outside of the scope in terms of "here is complete code". However, I might be able to help point you in the right direction.
To persist data between sessions (user plays game, some updates happen, user quits game, user loads game again and data has been persistent) you need to create a binary formatter, a filestream, and then create/open/load binary files from/to the users local storage.
There is an entire tutorial that will show you how to do this (about 1 hour). Watch it and try to persist something basic like increasing a number between sessions.
https://learn.unity.com/tutorial/persistence-saving-and-loading-data
I think you should hold off on "spawning x and doing y" until you can persist data. Then maybe come back and ask again.
In theory you would
1) Have a binary file that stores booleans used to record certain actions. You only want this to happen once right? so you would have some kind of binary file that has a "HaveAssetsBeenAssignedLocation" boolean and if it's false - do xyz. If it's true, skip to the next step.
2) When going through the initial spawn, I would go for spawning locations between a random range for x/z axis, and then save those locations to a scriptable object.
3) The scriptable object would pass this data to the binary formatter responsible for saving data.
4) When the player loads the game (each time) a check is made to see which assets have already been placed, and which assets have no location. If assets need to be placed, this is when you do it. Then, you unload the binary data, store it in a scriptable object, and then use the SO data to place your objects in the scene.
so yeah.... not the easiest thing to do to be honest.