Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Why are my vectors not adding properly?

Discussion in 'Scripting' started by Richard_Ingalls, Mar 22, 2023.

  1. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    88
    I have two objects, and when they collide, they "merge". I want the result of this merge to have the combination of their two velocities, for example, if object a was traveling at Vector2(1, 0) and object b was traveling at Vector2(-0.1, 0.5), I want the "merged" object to travel at Vector2(0.9, 0.5). Or if a was traveling at Vector2(-1, -1) and b was traveling at Vector2 (1, 1), the "merged" object would be traveling at Vector2(0, 0). With my current code, this does not work. Does anyone know why this could be?
    Code (CSharp):
    1. void OnCollisionEnter2D(Collision2D collision)
    2.     {
    3.         if (collision.gameObject.tag == addend.tag)
    4.         {
    5.             var v = collision.gameObject.transform.GetComponent<Rigidbody2D>().velocity;
    6.             var pos = new Vector2(collision.transform.position.x, collision.transform.position.y);
    7.             Destroy(collision.gameObject);
    8.             Destroy(this.transform.gameObject);
    9.             Combine(v, pos);
    10.         }
    11.     }
    12.  
    13.     void Combine(Vector2 velocity1, Vector2 pos1)
    14.     {
    15.         var v = velocity + velocity1;
    16.         var pos = pos1 + new Vector2(this.transform.position.x, this.transform.position.y);
    17.         var o = Instantiate(sum, new Vector3(pos.x, pos.y, 0), Quaternion.identity);
    18.         o.GetComponent<Particle>().velocity = v;
    19.     }
     
  2. QuinnWinters

    QuinnWinters

    Joined:
    Dec 31, 2013
    Posts:
    490
    What is your variable "velocity" in the Combine method? It looks to me like it should be:
    Code (CSharp):
    1. Vector2 velocity = rigidbody2D.velocity;
    Where rigidbody2D is defined elsewhere either in start, serialized, or publicly.
    Then you would need to set the velocity of the rigidbody on the newly instantiated object to the newly combined velocity vector2.

    Edit: Just noticed you're also destroying the local gameobject before running the Combine method. Perhaps that Destroy call should be after finishing the Combine method.
     
    Bunny83 likes this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    You're combining a position and a velocity.

    Velocity is the time derivative of position.

    Explain your thinking.
     
  4. QuinnWinters

    QuinnWinters

    Joined:
    Dec 31, 2013
    Posts:
    490
    I don't see that he's combining them. He's certainly sending them both into the Combine method, though. Then he's using the position as the position of the newly instantiated object and needlessly combining it with the local object's position. The velocity seems to be used solely as a velocity, but it's not clear what's receiving that velocity; what is the Particle component, what does it do with the velocity variable being changed in it, and where is the vector2 "velocity" value coming from that's being added to the one that's sent to the Combine method? There are several oddities going on here, that's for sure.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    Agreed. I saw this in Combine():

    but didn't notice that the args are correctly named velocity / position until you pointed it out.

    Which begs the question of...

    what is
    velocity
    ?! <-- edit, I mean the one without the "1" on the end

    Either way, OP if you're looking for an inelastic collision, what happens is actually a momentum combination, not a velocity combination.

    So the ultimate output of two inelastic bodies hitting each other is the mass-weighted velocity of their incoming parts.

    And usually we treat everything between 100% inelastic to 100% elastic as a tween between the two swapping momentum and the two joining into a single larger body with the summed momentum.
     
    Last edited: Mar 22, 2023
  6. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    88
    Velocity is set manually in the inspector for now, eventually it will be random. I tried moving it before and after the combine method, it has no effect.
     
  7. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    88
    velocity1 is the velocity of the collided object.
    var v = collision.gameObject.transform.GetComponent<Rigidbody2D>().velocity;
    .
    How would I do that?
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    Momentum is mass times velocity.

    A perfectly inelastic collision adds the masses and adds the mass-weighted velocities.

    so if you have object1 with mass1 and velocity1

    and object2 with mass2 and velocity2

    final mass will be mass1 + mass2

    final velocity will be (v1 * m1 + v2 * m2) / (m1 + m2)

    https://en.wikipedia.org/wiki/Inelastic_collision

    ALSO though... keep in mind that by the time you get called back the velocities have been adjusted by the physics engine based on the impact, so all would be for naught.

    Check it out:

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. // @kurtdekker
    4. // velocities reported are POST-impact
    5. // to see, put on a Rigidbody and drop it on a hard surface
    6.  
    7. public class VelocityReporter : MonoBehaviour
    8. {
    9.     void OnCollisionEnter( Collision collision)
    10.     {
    11.         Debug.Log( GetComponent<Rigidbody>().velocity);
    12.     }
    13. }
    To handle this you could:

    1) use a trigger
    2) retain the velocity yourself from the previous FixedUpdate() call
     
  9. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    88
    This does not work, it results in the resulted particle traveling along the vector of one of the particles, not the preferably combined vector, which was my problem before, only now it has switched which one it uses the vector from. Also, does anyone know how to make the new particle appear at the midpoint of where the two particles are?
     
    Last edited: Mar 23, 2023