Search Unity

Why does Lerp not reach target if setting rb.position, but rb.transform.position works?

Discussion in 'Scripting' started by ynm11, Jul 27, 2021.

  1. ynm11

    ynm11

    Joined:
    Jul 6, 2021
    Posts:
    57
    Hi,
    I don't understand the logic here.
    I have the following script which makes a player jump towards a target:

    Code (CSharp):
    1.  
    2. public IEnumerator JumpToTarget()
    3.     {
    4.         Vector3 startPosition = rb.transform.position;
    5.         Vector3 targetPosition = (nearestAnchor.FindClosestEnemy().transform.position - offset);
    6.      
    7.         float distance = (startPosition - targetPosition).magnitude;
    8.         float movementSpeed = 10;
    9.         float duration = distance / movementSpeed;
    10.  
    11.         for (float f = 0; f < 1; f += Time.deltaTime / duration)
    12.         {
    13.             rb.transform.position = Vector3.Lerp(
    14.                 startPosition,
    15.                 targetPosition,
    16.                 f);
    17.             yield return null;
    18.         }
    19.     }
    Notice `rb.transform.position = Vector3.Lerp(` here. This works and does reach the target. However, I am noticing that it seems to ignore collisions despite Player and the object it's jumping to both having Rigidbodies and colliders.

    So I looked up this problem and saw the suggestion to simply change `rb.transform.position = Vector3.Lerp(` to `rb.position = Vector3.Lerp(`. However, doing this makes the Player basically only begin to jump. Player gets like 20% towards target and just stops, whereas when it was `rb.transform.position` it would reach the target near-immediately.

    Does anyone know why this is happening? The ultimate goal is to have a JumpToTarget code that reaches the target *and* does not ignore collisions. Thank you.
     
    Last edited: Jul 27, 2021
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    If you move a Rigidbody yourself, you are always bypassing the physics system.

    The only way to NOT bypass the physics system is to call Rigidbody.MovePosition() with each new position.

    This will cause full physics simulation (as long as the RB is non kinematic!) and handle all collisions.
     
    ynm11 likes this.
  3. ynm11

    ynm11

    Joined:
    Jul 6, 2021
    Posts:
    57
    I changed it to MovePosition, but with this code, character just only jumps 20% off the floor, stops, and then starts sinking through ground.

    Code (CSharp):
    1.  
    2. private void Update()
    3. {
    4.      if (Input.GetKeyDown(KeyCode.X))
    5.      {
    6.          launchTo = true;
    7.      }
    8. }
    9.  
    10.  
    11. private void FixedUpdate()
    12. {
    13.      if (launchTo)
    14.      {
    15.          StartCoroutine(LaunchCR());
    16.      }
    17. }
    18.  
    19.  
    20. public IEnumerator LaunchCR()
    21. {
    22.      Vector3 targetPosition = launchZone.transform.position;
    23.  
    24.      while (rb.transform.position != targetPosition) {
    25.          rb.MovePosition((rb.transform.position - targetPosition) * 10 * Time.deltaTime);
    26.          yield return null;
    27.      }
    28. }
    Any ideas of what is going so wrong would be appreciated
     
    Last edited: Jul 27, 2021
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    Sounds like gravity is still acting on it, or perhaps your target is inside the ground.

    Instead of massive single-line statements like this, do yourself a favor and break it up a bit.

    How to break down hairy lines of code:

    http://plbm.com/?p=248

    Break it up, practice social distancing in your code, one thing per line please.

    Once you have done that, print some positions out.

    Print out the current position.

    Print out the proposed movement vector

    Print out the destination position.

    Then you have a fighting chance to reason about what is happening.
     
    ynm11 likes this.