- Home /
[Solved] Unable to instantiate an object from within the OnTriggerEnter callback.
[SOLUTION] The object was instantiating but it was instantly destroying itself due to update order of some scripts.
[ORIGINAL PROBLEM] Hello again helpful Unity Answers community!
I have encountered something which is either a bug or the way the engine works, either way it might be something that needs looking in to.
I have a proximity bomb, that upon entering of it's radius it explodes. Now the explosion is comprised of 2 parts.
sphere check for targets to damage
instantiation of visual effects
The proximity bomb can also be exploded when it is shot, which executed Detonate when the message ApplyDamage is sent to it. Exploding it this way spawns the effect, as it is still technically within the update loop. But as mentioned before, when it is triggered via the trigger collider nothing is spawned.
This is how I was calling it / would like to call it:
void OnTriggerEnter(Collider collider)
{
if(collider.tag == "Enemy")
{
Detonate();
}
}
void ApplyDamage(DamageInfo info)
{
Detonate ();
}
Doing it this way half works, in the sense that that the detonation happens, does the damage and removes the bomb object. But with no visual effects from the trigger.
However, doing it this way works perfectly:
void OnTriggerEnter(Collider collider)
{
if(collider.tag == "Enemy")
{
m_doDetonate = true;
}
}
void ApplyDamage(DamageInfo info)
{
Detonate ();
}
void Update()
{
if (m_doDetonate)
Detonate ();
}
Any ideas on why this is and how to fix it? I really hate using the Update() for one time checks when it should be doable via callback.
Whole script available: Proximity Bomb, Inherited Class
In your first script, where do you call the apply damage function?
I'm just trying to find out why you posted that function if it is never called
I don't see what your detonate function does, but if what you are trying to do is have detonate run for multiple frames without using the update function after it enters the trigger than you will want to use a coroutine with a while loop making sure that you call yield return null or WaitForEndOfFrame() or something until it is finished your process.
What @highpockets said: Without actual code, I assume your Detonate()
is probably a continuous function, but you are only calling it once in the first scenario.
Certainly interesting - there's nothing blindingly obvious...
So firstly spawning objects in OnTriggerEnter works just fine - I use it everywhere - so it's got to be something to do with the way the code flows.
I notice your recursion trap, and my feeling without being able to run the code is that it is possibly related to this. The effect of putting it on the next Update will move the logic out of the physics timestep and into the mainloop - though it should of course be the same frame - of course you using flagging also means that you will have deduplicated multiple calls. Why that might make any difference as you are using the location of the proximity bomb for your instantiation is not clear.
Now given you are not filtering any of the collisions in the OverlapSphere you will also end up with the proximity bomb sending ApplyDamage to itself - causing the recursion you are trapping out.
So I guess it "smells" like something in this series of interactions.
Also if the spawned prefab has a collider it will also OnTriggerEnter the moment you instantiate it, so perhaps if the spawned prefabs have colliders they are destroying themselves?
Answer by MaGuSware™ · Feb 13, 2014 at 06:46 PM
There really isn't anything like that attached to the object.
I restepped through the script with the desired method and no object is shown in the hierarchy even though it runs the instantiation code, the Vector3 is still intact.
--Edit-- Oh bloody hell, there was a script attached to it which handled it's destruction (totally forgot about it and it was hidden... sandwiched between audio and particle XD). The script uses particle count to judge whether or not to delete the object. Obviously after the physics step where the emitter hasn't had chance to emit yet... that count is going to be zero. I added an extra condition to check to see if the emitter is playing as well as having the count at zero. Works fine. I would have thought that the particle emitter would have been processed before this script though, given the component order (which should have averted this problem). Ah well... s'all good now.
Glad you found it - these things can be a total nightmare :)