- Home /
Unparenting and then deleting a child part of a prefab, SOMETIMES child throws null reference exception?
I've got a bullet being trailed with particles, so when it hits something bullet gets deleted, and I want to wait for the particles to disappear naturally before deleting the particle system. So I unparent the particle system, delete the bullet, then attempt to delete the particle system. Sometimes the particle system (the child in this case) doesn't get found when I fire two bullets in a specific situation (one bullet hits a target, the other is naturally destroyed when it's off screen, both are deleted using the bullets public delete function.) When the bullet hits the target, the target also calls the delete function on the bullet. Is unity handling children of the game object in a way I'm not expecting?
Some code is definitely ragged as I was trying to speed run making a game as fast as possible, the bullet script isn't really out of the ordinary. Hoping this is just me overlooking something simple. Bullet Code:
public class bullet : MonoBehaviour {
public float bulletSpeed = 1;
public float bulletDamage = 1;
// Use this for initialization
void Start () {
//gameObject.hideFlags = HideFlags.HideInHierarchy;
}
// Update is called once per frame
void Update () {
transform.Translate(Vector3.left * Time.deltaTime * bulletSpeed);
if(!GetComponent<Renderer>().isVisible)
{
Invoke("delete", 2);
}
}
public void delete()
{
transform.FindChild("Particle System").GetComponent<bulletSmokeFade>().waitASec();
transform.DetachChildren();
GameObject.Destroy(gameObject);
}
}
bulletSmokeFade code:
public class bulletSmokeFade : MonoBehaviour {
// Use this for initialization
// Update is called once per frame
public void waitASec () {
GetComponent<ParticleSystem>().Stop();
Invoke("cleanUp", 0.25f);
}
void cleanUp()
{
Destroy(gameObject);
}
}
The situation where the exception occurs:
higher quality MP4: https://i.gyazo.com/35f0a2d91941403f94a4ef62d60f23bd.mp4
I think the problem is because your running this in Update - which is called every frame, so while on the first frame it actually runs your delete 2 seconds later, it remains unrendered, and will continue to call stacks of that function every 2 seconds, and the second or 5th time or whenever it actually happens, the object is already deleted or in the process of being deleted from a previous call of that function
The best thing to do if you want to keep it in Update, is also use IsInvoking.
if(!IsInvoking("cleanUp")){Invoke("cleanUp", 0.25f);}
for example.
Or add a condition check like so:
if (gameObject != null)
Destroy(gameObject);
The error is not the destroy line but this one:
transform.FindChild("Particle System").GetComponent<bulletSmokeFade>().waitASec();
When FindChild returns null GetComponent can't be executed.
Answer by FiveFingerStudios · Oct 03, 2017 at 10:50 AM
no need to have the bulllet call waitasec.
Just have the particle delete itself after it's done playing.
Get the duration and use a coroutine with a delay to destroy it.
Your answer
Follow this Question
Related Questions
Make a simple tree 1 Answer
destroy Parent when child is destroyed 1 Answer
[SOLVED] Rotating child objects fix 0 Answers
Object won't instantiate at parents position(solved) 2 Answers
delete parent or send message to parent? 2 Answers