Search Unity

RigidBody2D Kinematic teleportation

Discussion in 'Physics' started by Goty-Metal, Apr 21, 2021.

  1. Goty-Metal

    Goty-Metal

    Joined:
    Apr 4, 2020
    Posts:
    168
    Hi there! so in the docs it's said to use "MovePosition" for a "smooth" transition of a rigidbody (i'm using kinematic rigidbody 2D with interpolate), it also sais to use "rigidbody2d.position" to "teleport" the rigidbody instead, BUT, if i set the position for a teleport like it says i can see for 2-3 frames the game objet moving really fast from point B to point B, that issue DISSAPEARS if i disable the interpolate (interpolate = none), i tried by disabling the interpolate by code, then teleporting and again set the interpolate but it doesn't work because the process is really fast and i suppose that those changes needs at least 1 frame to be applied.

    Any suggestions?

    thanks!
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    It would be clearer to state what you want and not just what you've guessed at because it's kind of confusing. Let's start by saying that interpolation has nothing to do with physics in the sense that it doesn't change collision-detection or body poses at all, operates per-frame and ONLY changes the Transform with relation to the previous/current body poses. It only works when the body moves via its velocity which also includes MovePosition/MoveRotation. Setting the pose directly via the Rigidbody2D or Transform doesn't support interpolation.

    Can you also distinguish between frames and physics update because they are (by default) not the same thing. By this I mean you'll get fixed updates then potentially many frames. Interpolation happens during the render frames .

    Honestly, can you just state what it is you want and I'll tell you how to do it? If it's just moving smoothing then use MovePosition with interpolation and it just works.
     
  3. Goty-Metal

    Goty-Metal

    Joined:
    Apr 4, 2020
    Posts:
    168
    I'm sorry english is not my native lang, ok let's go easy, i'm making a tower defense game, so i want the creatures move along the path as smooth as possible.

    So i have teleports alont the path to instantly teleport creatures from point A to point B:
    If i have interpolation, using "rigidbody2d.position = newposition;" does NOT transport the gameobject instantly, i can see (barely but i can) the game object moving really fast from it's current position to the new position, that DOESN'T happen if i turn off interpolation.

    So what i need is to avoid that "glitch?" because if i move creatures along the path with "MovePosition" and it looks more smooth if interpolation is enabled, rigidbodies are kinematic by the way.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    This changes the Rigidbody2D position only. It doesn't change the Transform. That'll happen when the next simulation step happens. It also doesn't support interpolation as I've said above.

    MovePosition isn't for moving at a set speed over a period of time; it's for moving to that position instantly during the next simulation step ... you've completely misunderstood it. You continually issue a MovePosition to a position inbetween; it's for Kinematic motion. You do issue this per fixed-update based upon some Lerp function you create that moves from point A to point B over a specified time.
     
    Goty-Metal likes this.
  5. Goty-Metal

    Goty-Metal

    Joined:
    Apr 4, 2020
    Posts:
    168
    Ok so i'm using MovePosition with a lerp along a path, that's wrong? how should i do it then? is working really good now but i'll hear any recommendation :)

    About the teleporting, the docs says "Teleporting a Rigidbody from one position to another uses Rigidbody.position instead of MovePosition."

    So i'm doing it wrong cause interpolation? should i change the transform position then?

    Thanks!
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    Everything you said above is opposite of what I said. ;)
     
  7. Goty-Metal

    Goty-Metal

    Joined:
    Apr 4, 2020
    Posts:
    168
    So ... i'm right? MovePosition with lerp for pathing.
    rigidbody.position for teleporting, but you said it does not support interpolation so i can't use rigidbody.position for teleporting... i'm confused :(
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    I am not sure why you are confused. I never said to use Rigidbody2D.position.

    Kinematic bodies should use MovePosition and MoveRotation because only those support interpolation.

    If you have a problem with this then you're doing something else wrong. Perhaps when calculating the next position to move you're using the current Transform.position as a base which is wrong if you're using interpolation. You should use Rigidbody2D.position to base the calculations i.e. lerp(rigidbody2D.position, another-position)
     
    Goty-Metal likes this.
  9. Goty-Metal

    Goty-Metal

    Joined:
    Apr 4, 2020
    Posts:
    168
    Great, that's what i'm doing, so what about teleportation? (instantly change it's position)? :)
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    What about it?
     
  11. Goty-Metal

    Goty-Metal

    Joined:
    Apr 4, 2020
    Posts:
    168
    How should i do it? what's the "correct" form? because "Rigidbody2D.position = new position" does NOT move the gameobject instantly, i can see 3-4 frames moving really fast from the old position to the new one :(
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    Changing the Transform ONLY changes the transform. It does nothing else for any component. Sure, when you render, the renderers will read that then but so does the physics system except the physics system doesn't run by default per-frame. Changing the body pose doesn't instantly change the Transform either, it changes the body pose only.

    I really don't know your experience here but it just sounds like you should look at some tutorials on what physics does and when. A Rigidbody(2D) is for driving the Transform. It'll only do that during the simulation step which by default is during the FixedUpdate (by default at 50hz). You are free to run the 2D physics per-frame if you like too (either manually or via the Physics 2D Settings > Simulation Mode > Update). You're talking about frames which I presume are render frames. MovePosition doesn't instantly move there and then nor does anything else related to physics. You change the body pose and it does that but only during the simulation step does it write the body pose to the Transform.

    It sounds to me like you just want everything synchronous and per-frame. If that's so, run the physics per-frame. If you change the body position then when the simulation runs it'll write the body pose to the Transform.
     
  13. Develax

    Develax

    Joined:
    Nov 14, 2017
    Posts:
    67
    I ran into a similar problem as Goty-Metal

    What I can notice is that changing
    Rigidbody2D.position
    works the same way as
    Rigidbody2D.MovePosition()
    : they both interpolate through frames up to the next
    FixedUpdate()
    . I set
    Rigidbody2D.interpolation = RigidbodyInterpolation2D.Interpolate
    and
    Project Settings => Time = 0.01
    , and the interpolation can be observed clearly enough no matter whether it is
    Rigidbody2D.position
    or
    Rigidbody2D.MovePosition()
    that moves the object. Then I set
    Rigidbody2D.interpolation = RigidbodyInterpolation2D.None
    and non of those two make interpolation.

    So, I can't understand I guess the same thing as Goty-Metal: why interpolation works with
    Rigidbody2D.position
    (since it shouldn't) and how to move an object with a Rigidbody2D without interpolation?

    The only way it woks for me is turning interpolation off & on like this:
    Code (CSharp):
    1.  
    2. Rigidbody2D rb = player.GetComponent<Rigidbody2D>();
    3. RigidbodyInterpolation2D interpolation = rb.interpolation;
    4. rb.interpolation = RigidbodyInterpolation2D.Interpolate;
    5. rb.position += (Vector2)shift;
    6. rb.interpolation = interpolation;
    7.  
    but it seems like there should be an easier way to do this and I'm missing something.

    From docs:
    upload_2021-9-16_23-51-24.png
    But again, my experiments show that interpolation is applied in both cases. BTW nothing like this is said about Rigidbody2D:
    upload_2021-9-16_23-53-29.png

    I'm using Unity 2021.1.17f1
     
    Last edited: Sep 16, 2021
  14. Develax

    Develax

    Joined:
    Nov 14, 2017
    Posts:
    67
    I think you can find the answer to your question in this thread:
    https://forum.unity.com/threads/rig...t-with-the-interpolation-settings-on.1172240/