- Home /
Instantiated object not keeping transform of the instantiator after instantiator is destroyed
Hi all, first time using the forum and I'm a proper noob that has been smacking my head against a wall for the last 2 days with this one so any help is appreciated.
The Set Up:
A GameObject enemy prefab which instantiates the eggs using a coroutine and random time (I don't think this is causal in any way).
Egg prefab with Spitball script (shown below)
Uses Transform; Rigidbody; Sphere Collider
In the code the public GameObject spider is the baby spider prefab to be instantiated and the public Transform spawnLoc takes the egg prefab to get the Transform (I think).
Baby Spider prefab, used in the public GameObject slot of the Spitball script.
Uses the following components; Transform; Rigidbody; Sphere Collider; Capsule Collider; Nav Mesh Agent; Animation; Animator; Audio Source; Enemy AI script (health, dmg & movement)
The Problem:
I have an enemy that 'spits' out a set of 5 eggs, which on collision with the terrain are supposed to spawn a baby spider at each egg. This is part is working, however as soon as the eggs are destroyed the baby spiders are instantly changing their Transform to 0, 0, 0 (the base Transform of the baby spider prefab).
Example of the problem:
Enemy spits egg > egg hits ground/terrain > baby spider instantiates > egg is destroyed > baby spider Transforms to 0, 0, 0.
The Code [C#] (current version) :
using UnityEngine; using UnityEngine.Events; using System.Collections; using System.Collections.Generic;
public class Spitball : MonoBehaviour {
public Rigidbody spider; // Reference to the spider RigidBody to be spawned
public Transform spawnLoc; // Reference to the Transform where the spider should spawn
private bool collided;
void Update(){
if(collided == true){
// Show in debug the transform.position of the collision
Debug.Log ("Colliding at" + transform.position);
// Set the GameObject spider and Instantiate the spid at the eggs's transform.position
Instantiate (spider, spawnLoc.position ,Quaternion.identity);
StartCoroutine ("Pop");
}
}
void OnCollisionEnter(Collision other){
if(other.gameObject.tag != "Terrain"){
collided = true;
}
}
IEnumerator Pop(){
yield return new WaitForSeconds (0.2f);
// Destroy the egg
Destroy(spawnLoc.gameObject);
}
}
The Code [C#] (older version) :
using UnityEngine; using UnityEngine.Events; using System.Collections; using System.Collections.Generic;
public class Spitball : MonoBehaviour {
public GameObject spider; // Reference to the spider GameObject to be spawned
public Transform spawnLoc; // Reference to the Transform where the spider should spawn
void OnCollisionEnter(Collision other){
if(other.gameObject.tag != "Terrain"){
// Show in debug the transform.position of the collision
Debug.Log ("Colliding at" + transform.position);
// Set the GameObject spider and Instantiate the spid at the eggs's transform.position
Instantiate (spider, spawnLoc.transform.position ,Quaternion.identity);
}
}
}
The current version (shown first) allows the spiders to spawn but as soon as the Pop coroutine is run and the egg is destroyed the spiders reset to their own transform.
Hopefully this is detailed enough and my thanks in advance to anyone with the patience to help me, a humble noob, to understand and remedy my issue.
First of all use the older version it makes more sense, obvisously you should add the coroutine call in it too.
After that most probably you assign wrongfully the spawLoc which according of what you say is the transform of the object, thus you could use the property transform ins$$anonymous$$d of manual assignment, also as the SpitBall script is on the egg which you want to destroy use Destroy(gameObject) .
Now if none of this make any difference odds are you manipulate the transform from another script.
Lastly what @Shemamforash says is wrong because when you instatiate an object it does not reference the same transform but it copies the values you provide which is obvious from the overload you are using and the fact that structs are value type.
Cheers
If you are changing an instantiated object that true, but he is calling Destroy on a reference to a prefab (spawnLoc), which Unity does not allow.
Answer by Shemamforash · Jul 19, 2018 at 12:36 PM
Hi there! How is your spawnLoc assigned? If the spawnLoc transform is the transform of the Spider itself, then as soon as you destroy it Unity is going to add a new Transform component with the default position value of (0,0,0). This behaviour occurs because Unity won't allow a gameobject to be without a transform. Let me know if this helps!
Whoops forgot to say the egg prefab is dragged in to the public Transform spawnLoc slot. Will add it to main question.
What you say makes sense and thanks :)
If I understand correctly, you are referencing the egg prefab in your script. If so just remove the spawnLoc variable and change these lines:
Instantiate(spider, spawnLoc.position, Quaternion.identity);
//change to
Instantiate(spider, transform.position, Quaternion.identity);
and
Destroy(spawnLoc.gameObject);
//change to
Destroy(gameObject);
Also you should change your rigidbody reference to a gameobject reference if you are instantiating the spider from a prefab.
Answer by mayur7garg · Jul 19, 2018 at 12:41 PM
I totally understood your problem but from the code, I am unable to understand the role of the "spawnLoc" Transform variable in the current version. Whose transform is it storing? By the way, since this script is attached to the egg which when collides with the terrain generates a spider, you can simply use "this.transform.location" in the second argument of the Instantiate call instead of the spawnLoc.position. I guess that should work.
Updated the question, thanks for spotting I'd missed that.
The egg prefab gets dragged in to the spawnLoc slot in the editor (if that makes sense).
When changing "spawnLoc.posistion" to "this.transform.position" the baby spiders are still warping to 0,0,0 after the egg is destroyed, thanks anyway though :)