TRANSFORM.TRANSLATE VS RIGIDBODY MOVEMENT IN UNITY

A side-by-side technical breakdown of kinematic vertex translation versus PhysX force integration, collision tunneling, and performance impacts.

1. High-Level Comparison Summary

Transform.Translate (Kinematic)
Mechanism: Instantly mutates 3D vertex coordinates.
Collision Behavior: Passes straight through walls unless manually raycasted. Ignores friction and mass.
Execution: Runs in Update() with Time.deltaTime.
Best For: Moving platforms, floating pickups, UI icons, and cutscene tracks.
Rigidbody.AddForce / MovePosition
Mechanism: Calculates acceleration vectors inside the PhysX solver.
Collision Behavior: Automatically pushes against solid colliders, respects gravity, angular torque, and friction.
Execution: Runs in FixedUpdate() with Time.fixedDeltaTime.
Best For: Vehicles, aircraft, ragdolls, and physics puzzle blocks.

2. Why Transform.Translate Passes Through Walls

When you execute transform.Translate(Vector3.forward * speed * Time.deltaTime) on a GameObject with a BoxCollider, Unity is effectively teleporting the mesh to a new point in space without sweeping the volume between the old and new positions.

If the translation distance exceeds the thickness of a solid wall, the object ends up on the other side without ever firing an OnCollisionEnter event!

If you must move a Rigidbody while maintaining kinematic control, use Rigidbody.MovePosition() instead. This sweeps the collider through 3D space, preventing tunneling:

using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
public class KinematicPlatform : MonoBehaviour
{
    [SerializeField] private Vector3 movementDirection = Vector3.up;
    [SerializeField] private float speed = 2f;
    
    private Rigidbody rb;

    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
        rb.isKinematic = true; // Kinematic allows script-driven physical sweeping!
    }

    private void FixedUpdate()
    {
        // ✅ Sweeps the physical platform and carries any player standing on top
        Vector3 newPos = rb.position + movementDirection * speed * Time.fixedDeltaTime;
        rb.MovePosition(newPos);
    }
}

3. Quick Decision Tree

  • Is it a player character that needs snappy, arcade platformer jumping? → CharacterController.Move()
  • Is it an aircraft, car, missile, or rolling boulder with mass? → Rigidbody.AddForce() / velocity
  • Is it an elevator or moving hazard that must push other objects? → Rigidbody.MovePosition() (isKinematic = true)
  • Is it a purely visual coin spinning in place or an off-screen UI element? → Transform.Rotate() / Transform.Translate()

Related Topics & Error Troubleshooting

Frequently Asked Questions

No, you should never mix them on a dynamic Rigidbody. Mutating transform.position while PhysX is simulating forces creates violent physics desynchronizations, causing the object to violently bounce, glitch through colliders, or trigger severe CPU spikes.
Yes, direct transform mutation involves almost zero computational overhead because it skips collision detection, solver matrix iterations, and friction calculations. However, without collision detection, it cannot interact with game geometry.