Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Vector2.MoveTowards to manipulate Rigibody.Velocity

Discussion in 'Scripting' started by FFaUniHan, May 8, 2019.

  1. FFaUniHan

    FFaUniHan

    Joined:
    Feb 26, 2018
    Posts:
    11
    Hi! I need to move object from point A to point B with speed of X by manipulating velocity. I don't like the way unity's MoveTowards directly manipulates transform.position, which makes my object goes through walls. So I decided to create a rigidbody.velocity equivalent. So far, here's what I got:

    Code (CSharp):
    1. public Vector2 a;
    2. public Vector2 b;
    3. public float speed;
    4.  
    5. private Update()
    6. {
    7.     rigidbody2d.velocity = VelocityMoveTowards(a, b, speed)
    8. }
    9.  
    10. private Vector2 VelocityMoveTowards(Vector2 current, Vector2 target, float maxDistanceDelta)
    11.     {
    12.         //Split the speed into X and Y vector
    13.         //Get the direction in degree
    14.         float angle = 0;
    15.         angle = Mathf.Atan((target.y - current.y) / (target.x - current.x));
    16.  
    17.         Vector2 returnValue;
    18.         //Move by speed splitted into Vector X and Vector Y
    19.         returnValue.x = Mathf.Cos(angle) * maxDistanceDelta;
    20.         returnValue.y = Mathf.Sin(angle) * maxDistanceDelta;
    21.  
    22.         //Don't overshoot
    23.         if(current.x + returnValue.x > target.x || current.y + returnValue.y > target.y)
    24.         {
    25.             returnValue.x = target.x - current.x;
    26.             returnValue.y = target.y - current.y;
    27.         }
    28.  
    29.         return returnValue;
    30.     }
    The problem is, sometimes it doesn't work properly. I try to tinker with it several times, but it's either caused the object to accelerate and decelerate randomly, or not moving at all.

    I'm open to any alternative solution, if there's another another way I could move from point A to point B, with speed X by manipulating velocity
     
  2. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    565
    Atan is only for half a circle - use Atan2. But beyond that, it's easier to use standard vector math:

    Vector2 toTarget = (target-current).normalized() // this has length 1
    velocity = toTarget*speedPerSecond;


    Since velocity is in meters per second, the don't overshoot code isn't quit right - it slows you down when you will get there in less than a second. Which might be cool, but isn't about overshooting.
     
  3. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    2,146
    Not sure why you think MoveTowards has anything to do with the transform, it simply returns a vector result. You should be able to use it just fine.

    Code (csharp):
    1.  
    2. rigidbody2d.velocity = Vector2.MoveTowards(a, b, speed)
    3.  
     
    SparrowsNest likes this.
  4. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    565
    Pretend you're moving from a=(0,10) to b=(20,10). That's directly to the right, along +x. Suppose speed is 3 (per second, since that's how velocity works). That code will always set velocity to (3,10). It will blast you almost straight on +y, at a speed of about 10. Wrong direction and wrong speed.
     
    GroZZleR likes this.
  5. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    2,146
    I assume(d) the OP was trying to modulate some sort of acceleration forces.

    If they're working with positions, then I'd recommend Rigidbody2D.MovePosition() instead to reach a fixed point.
     
  6. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    565
    Depending how you use it, RB.MovePosition, I think, can also go through walls. The problem is trying to use trig to compute a direction to the target. It can work, but (B-A).normalized is shorter and safer.