- Home /
Instantiated Object's Scripts not enabled? Not sure why
Don't have code right now, but I wanted to get this up in case anyone had any ideas. I will post it this evening in an edit. I have an object being InStantiated after the Enemy dies which respawns the object as a clone. Everthing looks right, but it's no longer doing anything. When I click on the object during Play mode in the Hierarchy all the scripts are unchecked. Any ideas? I do this with my player and all its scripts are enabled/checked.
@Bunny83 I will experiment with this, I think I saw something about a prefab manager in the Wiki. I was using JS, but I think I can modify this easily enough. Not entirely sure though why the player GameObject when being destroyed doesn't have this issue. I will let you know how it goes thanks.
Answer by Bunny83 · Jan 28, 2011 at 10:32 PM
I had that issue just a few hours ago. I posted a detailed explaination in the Unity forum.
In short: The problem is that when you assign a prefab to a variable inside that prefab, unity recognise this reference as local reference and adjust it to your real object when it gets instantiated.
That means the variable you assigned your prefab and that you use to Instantiate a new version of your object, is now pointing to the actual object in the scene and not longer to the prefab.
That alone wouldn't be such a big problem because your new object would be cloned from your old object instead from the prefab. But when you call Destroy() on your object all scripts gets disabled before it will be removed. When you instantiate a new object from the old one, all scripts are disabled.
Furthermore it causes another nasty effect. When your object is named "Enemy" the clone will be named "Enemy(clone)". The next instance will be named "Enemy(clone)(clone)". That causes endless names. That can be avoided by assigning a name after instantiate but it's all not really a good solution.
All in all you will always run into such problems when a prefab is holding a reference to itself. The best solution is to use a prefab manager script that provides easy access to this reference.
Since you didn't specified a language i will use C#:
// This script should be an a empty gameobject somewhere in the scene
// DontDestroyOnLoad would be great (like for the most manager)
using UnityEngine;
public class PrefabManager : MonoBehaviour
{
// Assign the prefab in the inspector
public GameObject EnemyPrefab;
//Singleton
private static PrefabManager m_Instance = null;
public static PrefabManager Instance
{
get
{
if (m_Instance == null)
{
m_Instance = (PrefabManager)FindObjectOfType(typeof(PrefabManager));
}
return m_Instance;
}
}
}
It's not a perfect singleton, you could check after FindObjectOfType if we found it and in case there is no manager, create one. But it's quite useless because all the prefabs will not be assigned to it and that's the main usage of that manager.
To instantiate a new enemy from inside the enemy script can easily done with:
Instantiate(PrefabManager.Instance.EnemyPrefab);
I'll hope that doesn't confuse you too much :D it's a really tricky problem but i don't see much better solutions. I use such a manager in our game project for nearly everything but watch out: all prefabs assigned to the manager script on the empty gameobject will be packed into the scene where the manager is placed. When you put that manager in the first scene the size of this scene will increase (but the over all size stay the same). It's just a bit nasty when you stream your game in webplayer because it can't start until the first scene is loaded.
If you have more questions on these themes just ask ;)
the code above, gives many errors when used as a script
@GamesDeveloper12:
$$anonymous$$aybe you forgot the "using UnityEngine;" at the top? I didn't included it since every C# script in Unity needs it. Anyway i added it to the code snippet above.
@Vadymka: Thanks, this is a quite old question (and answer). I'm not sure what happend there back then. Anyways i've fixed the singleton.
edit
Uhm i just took a look at your error messages.... The script you have errors in is called "DontDestroyOnLoad.cs" which certainly isn't the script i've posted. The script name and the class name have to match. The script i posted has to be called "Prefab$$anonymous$$anager.cs".
Also "DontDestroyOnLoad" is already a method from the Unity API so you really shouldn't use that as classname / scriptname.
Great code! so far it works flawlessly. I was wondering though, through the use of Instantiate(Prefab$$anonymous$$anager.Instance.EnemyPrefab);, can you also select the position in which it will get instantiated? I got several empty gameObjects which will serve as respawners.
So in short: is there a way to decide the position of the gameobject for when it get's instatiated?
Answer by tendercorpse · Dec 16, 2017 at 10:04 PM
The simple solution is:
put destroy command under the instantiate command.
this way you'll create the child first, before killing the parent.
example: instantiate (gameobject,b,c) destroy.gameobject,
Answer by klendigocci · Dec 04, 2016 at 10:47 AM
public class ObjectScript: MonoBehaviour
{
public GameObject ObjectToRespawn = null;
public GameObject newObjToRespawn = null;
Vector3 pos = new Vector3(5f, -2.5f, -124f); // the fixed pos that i want my object to spawn
void Start()
{
}
void Update()
{
if (transform.position.z > 50)
{
Destroy(this.gameObject);
createPrefab(ChallengeToRespawn); //overload the gameobject that you want to clone
}
}
private void createPrefab(GameObject go)
{
//MoveObj and ObjDestroyer are my script files, u must replace those with ur script file names
(newChallenge.GetComponent("MoveObj") as MoveObj).enabled = true;
//this is initialize the script at runtime (Make it true or false)
(newChallenge.GetComponent("ObjDestroyer") as ObjDestroyer).enabled = true;
newChallenge = go;
newChallenge = Instantiate(newChallenge, pos, Quaternion.identity) as GameObject;
// this clone object
}
}
Hope that it works for you guys :)
Your answer
Follow this Question
Related Questions
Clone Selector 1 Answer
Assign an instantiated GameObject? 1 Answer
Instantiate GameObject cloned into wrong position. 1 Answer
Reference an Instance of an Object?C# 1 Answer
Variable being shared between clones 2 Answers