- Home /
Object spawns itself instead of it's prefab.
I have a GameObject which I have programmed to instantiate it's own prefab. Instead of instantiating the prefab, it instantiates a copy of itself. (I can tell as the copy has variables in it's scripts which are equal to those of the object that spawned it rather than those of the prefab). How do I have it that it spawns the prefab with the values as they should be, instead of a copy of the object?
N.B. I know this is hard to understand. I'm tired.
We need to see the code to pinpoint the problem. It is likely that you are either:
Changing variable in the prefab
Spawning the game object ins$$anonymous$$d of the prefab
Overwriting the reference to the prefab.
Answer by clunk47 · Sep 23, 2013 at 10:46 PM
Well you didn't post any code, so it's impossible for us to tell you what you may be doing wrong. So I'll just give an example. In this example, I'll have a public GameObject that you will need to assign via the inspector, which means you will drag the prefab in your assets folder to the slot on your script component. You need to clone the prefab to create a new instance, you don't want to directly instantiate the prefab itself.
using UnityEngine;
using System.Collections;
public class example : MonoBehaviour
{
public GameObject prefab;
void Awake()
{
GameObject clone = (GameObject)Instantiate(prefab, transform.position, Quaternion.identity);
}
}
Answer by jaredmo · Oct 05, 2016 at 06:45 AM
I know the best answer has been chosen and this issue is super old, but I've hit this exact case. Let me outline what I did to have the issue, and at the bottom I'll provide my solution. Hopefully this helps someone out there:
First, create a Prefab with an attached script where it creates another instance of the same prefab, like so (This code is a simple illustration that creates the problem, not meant to be perfect):
using UnityEngine;
using System.Collections;
public class Respawnable: MonoBehaviour {
private int hp;
public GameObject guyPrefab; // The same type of prefab this script will be linked to
void Awake()
{
hp = 10;
}
void Update()
{
// Is this dead?
if(hp <= 0)
{
this.gameObject.SetActive(false);
StartCoroutine(Respawn(15f));
}
}
IEnumerator Respawn(float timeToRespawn)
{
float timer = timeToRespawn;
while (timer > 0)
{
timer -= Time.deltaTime;
yield return null;
}
Instantiate(guyPrefab, aPosition, Quaternion.identity);
Destroy(this.gameObject);
}
}
For me, the prefab that is instantiated during that respawn coroutine will be a copy of the instance of the prefab that called the coroutine as long as that coroutine is part of a script attached to the original instance of the prefab. Phew! That was a mouthful. Hopefully This makes sense.
To illustrate, I'll provide a screenshot:
In this scene I had 13 instances of a prefab that represented a gravestone. When the gravestone was "destroyed", it would start a coroutine to respawn a new instance of itself (exactly like in the example code above). In this particular test, I destroyed grave (4). As you can see, instead of the expected grave(Clone) we instead got a grave (4)(Clone), as though it was instantiating an instance of the now destroyed grave (4)! But I wanted a fresh instance of the prefab!
robertbu pointed out a few concerns about the problem. First off, let me assure you that I did not change any variables in the prefab itself. I prove this because I made one important script change that fixed the problem. I'll get to this below. Second, as the GameObject variable is set to be a prefab, and that variable is only referenced when it is time to instantiate, I'm guessing that I'm not spawning an instance of the game object, though I suppose I could be wrong and am missing something. Finally, the prefab is definitely not being overwritten in the code, as it is only referenced when instantiating.
And now the solution:
I simply created another script to facilitate. This script has a GameObject variable where I set the prefab, and then the other class calls the external coroutine and things work fine:
using UnityEngine;
using System.Collections;
public class RespawnManager : MonoBehaviour {
public static RespawnManager instance;
public GameObject guyPrefab;
void Awake()
{
if(instance == null)
{
instance = this;
}
}
public IEnumerator Respawn(float timeToRespawn, Vector3 aPosition)
{
float timer = timeToRespawn;
while (timer > 0)
{
timer -= Time.deltaTime;
yield return null;
}
Instantiate(gravePrefab, aPosition, Quaternion.identity);
}
}
public class Respawnable: MonoBehaviour {
private int hp;
void Awake()
{
hp = 10;
}
void Update()
{
// Is this dead?
if(hp <= 0)
{
this.gameObject.SetActive(false);
StartCoroutine(RespawnManager.instance.Respawn(15f, this.transform.position));
}
}
}
This successfully creates a clean instance of the prefab.
Your answer
Follow this Question
Related Questions
Retrieving GameObjects from a Prefab 1 Answer
Spawning a prefab at another object's location 3 Answers
How to instantiate a prefab with a script attached? 2 Answers
I cant delete multiple instantiated prefabs 0 Answers
Instantiate Prefab in memory? 2 Answers