transform.position
- это просто текущая позиция, Вы должны рассчитать новую позицию вручную.
transform.Translate()
- передвигает объект на заданное расстояние, здесь Вы указываете только расстояние.
И в том, и в другом случае они передвигают сам объект, не принимая в расчет его физическое описание. В результате ломается вообще вся физическая симуляция, так как на следующем вызове FixedUpdate()
, где рассчитывается физика, объект окажется вовсе не в той позиции, где это ожидается физическим движком.
rigidbody.velocity
- меняет физическое описание объекта. Впрочем, это тоже нарушает физику, хотя и в меньшей степени - объект получит только другую скорость. Часто это терпимо.
rigidbody.AddForce()
- это то, что реально нужно использовать для движения rigidbody. К сожалению, это мало где описано, а там есть множество нюансов.
Приведу один из вариантов кода для движения rigidbody
, он вычисляет разницу между текущим и желаемым значениями velocity
и применяет только эту разницу:
var velocityChange = desiredVelocity - _rigidbody.velocity;
_rigidbody.AddForce (velocityChange, ForceMode.VelocityChange);
При этом, реальная скорость объекта может отличаться от желаемой в результате физической симуляции (например, при движении под гору или в гору).
Еще есть специальный компонент CharacterController
. Двигать его нужно при помощи его собственных методов SimpleMove()
и Move()
.