x


Rigidbody magnitude comparison is not working correctlly?

i want to compare the magnitudes of two rigidbodies and destroy the one that is moving slower when they collide. I do this by comparing the magnitudes of the 2 rigidbodies. It works fine most of the time but sometimes the wrong object gets destroyed, and when this happens one of the objects is completely at rest and the other is moving, so there is no way that the magnitudes would be equal. The code looks likes this:

function OnCollisionEnter(collision : Collision) {



    if(collision.gameObject.tag == "projectile") {


       if(collision.rigidbody.velocity.magnitude < rigidbody.velocity.magnitude)     {

           collision.gameObject.GetComponent(ProjectileScript).destroyMe(player);

       }



    }

any ideas??

more ▼

asked Apr 30 '12 at 07:28 AM

filler03 gravatar image

filler03
117 15 23 30

Can you show us the code for the destroyMe method?

Also, not related but small perofrmance improvement, use sqrMagnitude when you just want to check a difference:

if(collision.rigidbody.velocity.sqrMagnitude < rigidbody.velocity.sqrMagnitude)
Apr 30 '12 at 07:31 AM Kryptos

start with a Debug Log. As in :

Debug.Log(collision.rigidbody.velocity.magnitude); Debug.Log(rigidbody.velocity.magnitude);

that may provide a clue. also, the mass will affect magnitude along with speed, so if the objects have different masses, that could affect it.

Apr 30 '12 at 07:43 AM Seth Bergman

Also might not be working as expected because they've already collided when it checks the velocity ; so the velocity has already changed, and isn't what it was before impact.
e.g.
before Impact : Obj01 speed = 100.0 , and Obj02 speed = 500.0 ; ... you want Obj01 to die here
... but...
After Impact : Obj01 got a kickstart from highspeed Obj02 and it's speed now = 50 heading in the other direction, and Obj02 bounced off the other one fairly hard and it's speed ended up decreasing to 35 so it dies instead.
Not sure if that's what's going on here, but that's the first thing that came to mind. Need the speeds of them from right BEFORE they hit each other, not afterward ; and not sure if OnCollisionEnter would call and calculate quite fast enough all the time to catch the speed before it changed. Might be why it works for you most of the time, but not always.

Apr 30 '12 at 07:55 AM Lo0NuhtiK

Mass doesn't affect magnitude or speed at all, and it would be really wrong if it did. Velocity is speed/direction only, magnitude is simply how much speed there is. The only affect mass has is how much force it takes to get to a given speed.

Apr 30 '12 at 07:57 AM Eric5h5

duh, my mistake, of course. Thinking of the wrong thing

Apr 30 '12 at 08:02 AM Seth Bergman
(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

The magnitude inside OnCollisionXXX is the magnitude after the collision has been processed by the physics engine.

If you want the magnitude before the collision, you will have to save it in a variable and update it each FixedUpdate (in both scripts):

var prevSqrMagnitude : float;

void FixedUpdate()
{
    prevSqrMagnitude = rigidbody.velocity.sqrMagnitude;
}

Then, in the script with the OnCollisionEnter function:

function OnCollisionEnter(collision : Collision) {
    if(collision.gameObject.tag == "projectile") {

        var projectile : ProjectileScript = collision.gameObject.GetComponent(ProjectileScript);
        if(projectile.prevSqrMagnitude < prevSqrMagnitude ) {
            projectile.destroyMe(player);
        }
    }
}
more ▼

answered Apr 30 '12 at 03:01 PM

Kryptos gravatar image

Kryptos
7.2k 5 32

(comments are locked)
10|3000 characters needed characters left

@Lo0NuhtiK may be right: the velocities may have been changed by the collision. You could store the velocities in FixedUpdate in both objects and compare them:

var lastVel: float = 0;

function FixedUpdate(){ // this function must exist in both scripts!
  lastVel = rigidbody.velocity.magnitude;
}

function OnCollisionEnter(collision : Collision) {
    if (collision.gameObject.tag == "projectile") {
        var otherScript = collision.gameObject.GetComponent(ProjectileScript);
        if (otherScript.lastVel < lastVel){ // compare the velocities prior collision
            otherScript.destroyMe(player);
        }
    }
}
more ▼

answered Apr 30 '12 at 03:03 PM

aldonaletto gravatar image

aldonaletto
41.4k 16 42 196

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x2485
x1786
x317
x28

asked: Apr 30 '12 at 07:28 AM

Seen: 723 times

Last Updated: Apr 30 '12 at 03:03 PM