0
\$\begingroup\$

Recently I've started learning Unity3D. I'm working on a game as an exercise in which you control a space ship and have to dodge asteroids. If you feel like it's getting a bit too much you can hit the space bar, emitting a blast in all directions that repulses nearby asteroids. To create this blast I have the following code:

public class PlayerBlastScript : MonoBehaviour {

public ParticleSystem BlastEffect;

// Update is called once per frame
void Update () {
    if (Input.GetKeyUp(KeyCode.Space)) {
        Fire();
    }
}

public void Fire() {
    ParticleEmitter effect = (ParticleEmitter) Instantiate (BlastEffect, transform.position, Quaternion.identity);
    effect.Emit();

    Vector3 explosionPos = transform.position;
    Collider[] colliders = Physics.OverlapSphere(explosionPos, 25.0f);

    foreach(Collider hit in colliders) {
        if (!hit) {
            continue;
        }

        if (hit.rigidbody) {
            hit.rigidbody.AddExplosionForce(5000.0f, explosionPos, 100.0f);
        }
    }   
}
}

Even though the blast effect appears, the asteroids are not affected at all. The asteroids are all rigid bodies so what's the problem?

\$\endgroup\$
4
  • \$\begingroup\$ The sphere you're using to get nearby asteroids is much smaller than the radius of the explosive force. Have you ensured that your asteroids are actually being captured in the overlap sphere? \$\endgroup\$ – MichaelHouse Oct 19 '13 at 15:06
  • \$\begingroup\$ Yes, the "playing field" is only 20 units wide and 10 units high so it should be alright. \$\endgroup\$ – Zero Oct 19 '13 at 15:55
  • 1
    \$\begingroup\$ So the asteroids are being detected by your overlap sphere? As in, you put a break point or print out inside the if (hit.rigidbody) condition, and saw it trigger? \$\endgroup\$ – MichaelHouse Oct 19 '13 at 16:01
  • \$\begingroup\$ Oh actually apparently they are not detected. Following your advice I put a Debug.Log() inside the if (hit.rigidbody) condition but no logs showed up. \$\endgroup\$ – Zero Oct 19 '13 at 19:20
1
\$\begingroup\$

You're checking the colliders like they're boolean variables.

If a collider is inside colliders, it should have the explosion effect applied to it, there are no additional collision tests you need to do inside your foreach loop. However, you may want to check the type of object if you don't want things like power ups being affected by the blast effect.

You can change your code to be:

foreach(Collider hit in colliders) {
    hit.rigidbody.AddExplosionForce(5000.0f, explosionPos, 100.0f);
}  
\$\endgroup\$
2
  • \$\begingroup\$ Alright, I think this solves the problem. However I now get the error: InvalidCastException: Cannot cast from source type to destination type. at the line: ParticleEmitter effect = (ParticleEmitter) Instantiate (BlastEffect, transform.position, Quaternion.identity);. I get that its because I'm converting ParticleEmitter to ParticleSystem, but when I change ParticleSystem to ParticleEmitter I can't assign my ParticleSystem prefab anymore. Any ideas on how to fix that problem? Answer accepted by the way, as you helped me with the problem in the title :D . \$\endgroup\$ – Zero Oct 19 '13 at 20:10
  • \$\begingroup\$ Yeah, you can cast it as a GameObject (since that's what Instantiate returns), then use effect.GetComponent<ParticleSystem>(). \$\endgroup\$ – MichaelHouse Oct 19 '13 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.