How can i move an object to a certain position while taking into account colliders ?

So, even though it’s a really simple task, I simply cannot do it. Basically, I have several cubes of scale (1, 1, 1) and with rigidbodies and colliders attached. I want to move them as if they were in a grid, meaning that I want to move them either left, right, up or down by exactly 1 square. Translated, it would be transform.position + Vector3.left/right/forward/back. However, I cannot find a way to move them while still colliding. I mean that, if I have cube A right to the left of cube B, and I want to move cube B to the left, no matter what I do it passes through cube A. And I don’t want to.

float speed = 7f;
target = transform.position + Vector3.left; //or right, or forward, or back, depending on the Input

void MoveTo(Vector3 target)
    {
        float t = 0;
        while (t <= 1)
        {
            t += Time.fixedDeltaTime / speed;
            rb.MovePosition(Vector3.Lerp(transform.position, target, t));
        }
    }

I tried with rigidbody.velocity, but can’t figure it out. ALso I think with translate doesn;t work, as translate i think ignores colliders. Please, anything that could work is highly appreciated, I am stuck :slight_smile:

Not tested.
If I were to do it I would do it like this (You call MoveTo() once every frame with the current destination and it will move there with ‘speed’ and stay, until another destination is passed). It returns true if the destination will be reached.

private bool MoveTo(Vector3 target)
{
    Vector3 current = rb.position;
    if(target == current) return true;
    
    Vector3 direction = (target - current);
    float l1 = direction.sqrMagnitude;
    direction.Normalize();
    Vector3 step = direction * speed * Time.fixedDeltaTime;
    float l2 = step.sqrMagnitude;
    Vector3 to = current + step;
    if (l2 > l1) to = target;
    
    //we need to check for collisions our self, and stop if we hit anything
    bool test = rb.SweepTest(direction, out RaycastHit hitInfo,
        Mathf.Sqrt(l1), QueryTriggerInteraction.UseGlobal);
    if(test) to = current + direction * hitInfo.distance;
    
    if(to == target) return true;
    rb.position = to;
    
    return false;
}