There is a delay when changing [rigidbody2D.position]

Hello.
It might be basic, but I don’t know, so I’m going to ask you a question.

First of all, please understand that the sentence may be a little awkward because it was written using a translator.

bandicam 2024-09-08 23-45-15-281

If you look at the gif, there is no delay in the front.
However, there is a delay in movement after checking the inspector’s IsRgMove.

Below is the code.

public class TransformTest : MonoBehaviour
{
    public Rigidbody2D _rb2D;

    public bool isRgMove;

    private void OnEnable()
    {
        SetPosition(Vector2.down);

    }
    private void OnDisable()
    {
        SetPosition(Vector2.up*5);

    }
    protected void SetPosition(Vector2 position)
    {
        if (isRgMove)
        {
            _rb2D.position = position;
        }
        else
            transform.position = position;
    }

}

There’s also an Inspector setting in the latter part of the video. I’m a new subscriber, so I can only upload one image, so I’m sorry that the low quality gif was the best.

When you move a game object with a rigid body and a collider,
I knew that changing to [Rigidbody2D .position] is good for performance because changing to [transform.position] increases a lot of physical calculations.

However, there is a delay when using [Rigidbody.position] (like gif at the top)

Did I set something wrong? Or did I get it wrong?
Thank you for reading the long post.

Performance is not really relevant here. The difference is much more than that.

Using the transform bypasses the physics engine: if the Rigidbody2D is present, then it must catch up and will likely glitch.

Setting _rb2D.position directly is also bypassing and FORCING the position.

If you want to use the physics system, then use it. Call _rb2D.MovePosition()

Here’s more:

With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.

This means you may not change transform.position, transform.rotation, you may not call transform.Translate(), transform.Rotate() or other such methods, and also transform.localScale is off limits. You also cannot set rigidbody.position or rigidbody.rotation directly. These ALL bypass physics.

Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.

1 Like

Thank you so much for your response. I’ve read it really closely.
However, the delay is the same when using MovePosition(). I’ll have to find another way.

However, I learned that forcibly converting the position of an object with Rigidbody is a bad thing.
Thank you so much. :slight_smile:

I cannot see anything useful with the tiny gif, sorry.

The Transform/Rigidbody2D only sync-up when the simulation runs which isn’t per-frame, it’s during the fixed-update (50Hz). You control that in the Physics2D settings, see “Simulation Mode”.

When you disable the GameObject, you are also destroying the physics components behind the scene. That’s not a way to set this as this is likely what you’re getting confused over. Shouldn’t you be disabling the “TransformTest” component instead?

1 Like

Thank you for your advice.
The gif and the script I posted on the first question were made temporarily for testing.
Here’s a real game video that you might refer to. I just uploaded it to YouTube.

Game objects that look like [sheep] are spawn using [Object Pooling], and Despawn after walking to their destination.

And the [Sheep] GameObject enabled by [Object Pooling] is positioned on its own by the function below.

    protected void SetPosition(Vector2 position)
    {
        if (_rb2D != null)
        {
            _rb2D.MovePosition(position);
        }
        else
        {
            _transform.position = position;
        }
    }

===================

gameobject Enable → SetPosition

The above flow ran at the same time, so from the player’s point of view, the purpose was to make the game object look like it was Spawned in that position.

But in the game right now, there’s a delay in that part, so SetPositon is walking from the wrong place (up in the sky) without being done properly.

If you’re retrieving it from a pool i.e. an old object that is disabled then you should always set the position before you enable it. You should set the Transform then enable it. When it’s enabled, the Rigidbody2D creates the physics body at the current Transform pose and both will be at the same position.

By enabling it, you are creating it at the wrong position.

1 Like

Thank you for your wonderful response! I mean it.

Before the game object is enabled-
Are you saying I should enable the game object after changing the position to transform.position instead of rigidbody.MovePosition()?

I understand that there is a problem with changing transform.position while game objects with rigidbody and collider are enabled,

Is it okay to change transform.position with game object disabled?

That’s exactly what I said above, yes. :slight_smile:

1 Like

It helped me a lot. Thank you.
I need to work harder

1 Like