Change hierarchy of prefab in script
Hello!
I am trying to create "a prefab" in script, so I can Instantiate it freely whenever I want. To be specific, I have a Unity prefab "Player" -> that should be a tank with two parts - body and gun. So I have also prefabs of many Bodies and many Guns so player can choose from those. Now I want to create something like playerPrefab object in script, whose instantiated gameobject will contain all those parts.
For now it looks like this:
GameObject playerPrefab = ...
GameObject playerPrefabBody = ...
GameObject playerPrefabGun = ...
playerPrefabBody.transform.parent = playerPrefab.transform;
playerPrefabGun.transform.parent = playerPrefab.transform;
.....
GameObject player = Instantiate (playerPrefab, ...);
I'm still getting this:
Setting the parent of a transform which resides in a Prefab Asset is disabled to prevent data corruption (GameObject: 'Body 2').
UnityEngine.Transform:set_parent(Transform)
I was googling a bit, but hadn't found anything useful. I know, I can instantiate all three prefabs and THEN join them, but that would be ugly, as i will need to do that every time player is beeing spawned (which could be once each 5 seconds, or even less. Well, that sould not pose any problem, but it's still ugly :D )
Just to point out, I don't really want to change the prefab itself, as it will be used for the same player, when he chooses other type of Body or Gun...
Is there any way to do this as described?
Answer by streeetwalker · Sep 13, 2020 at 11:37 AM
@Loles, we do this all the time. All you need to do is add the instances to the parent instance. The general syntax is instance transform.parent = parent instance transform. You must create instances of all the objects involved first.
For example:
GameObject playerPrefab = ...
GameObject playerPrefabBody = ...
GameObject playerPrefabGun = ...
GameObject player = (GameObject) Instantiate( playerPrefab, ... );
GameObject body = (GameObject) Instantiate( playerPrefabBody, ... );
GameObject gun = (GameObject) Instantiate( playerPrefabGun, ... );
body.transform.parent = player.transform;
gun.transform.parent = player.transform;
// or if you want the gun on the body and the body on the player
gun.transform.parent = body.transform;
Answer by Loles · Sep 13, 2020 at 11:59 AM
@streeetwalker Yes, I know, I can do that. I was wondering, if i can somehow prepare that prefab in script and then do only ONE call of Instantiate function, as I will be calling it in more than one places (spawning on login, spawning on next map, spawning upon death), and also to all players logged in the game (as it will be an online game) (many players should Instantiate on one Client with that function).
@Loles Sorry, I misunderstood - I thought you wrote you did not want to alter the prefab. The short answer is, no, you can't alter prefabs through script while a game is running. You can do it in an editor script.
@Loles, on futher thought, you can, for example the code I pasted, create the composite once up front, and then just make instances of the composite game object.
@streeetwalker You've said "create the composite once up front". That looks really promising. Can you paste here an example of that?
Your answer
Follow this Question
Related Questions
How to spawn a prefab at a duplicate objects location 1 Answer
How To Reset Prefab Values after exiting Playmode? 0 Answers
How to Change the Variables of an Instantiated Object? 0 Answers
Unity overwrites prefab values in runtime 0 Answers
Instantiate works fine in Editor and does not work after building game 0 Answers