Этот код работает. ↓
Код: Выделить всё
private void FixedUpdate()
{
Vector3 newPosition = new Vector3(0, 1, 0);
GetComponent().MovePosition(newPosition);
}
Код: Выделить всё
private void FixedUpdate()
{
Vector3 newPosition = new Vector3(0, 1, 0);
Vector3 oldPosition = transform.position;
transform.position = newPosition;
transform.position = oldPosition;
GetComponent().MovePosition(newPosition);
}
Итак, похоже, что Rigidbody.MovePosition() не будет работать, если только что изменилось Transform.position.
Почему это происходит?
Добавлено 2021.9.3
Я обнаружил, что можно использовать Physics.SyncTransforms() для решения проблемы.
Этот код работает. ↓
Код: Выделить всё
private void FixedUpdate()
{
Vector3 newPosition = new Vector3(0, 1, 0);
Vector3 oldPosition = transform.position;
transform.position = newPosition;
transform.position = oldPosition;
Physics.SyncTransforms(); //newly added
GetComponent().MovePosition(newPosition);
}
【Part1】
Прошло два года. Сейчас мне снова приходится иметь дело с физикой.
Я узнал, что Rigidbody.position лучше, чем Transform.position, если я хочу изменить положение напрямую.
И При правильном использовании Rigidbody.position не приведет к тому, что Rigidbody.MovePosition() не будет работать.
Как говорит @thekirmizi, перемещение объектов осуществляется как с помощью Transform.position, так и с помощью Rigidbody. MovePosition() далеко от лучшей практики.
Если я хочу переместить объект непрерывным/физическим способом, я могу использовать Rigidbody.velocity , Rigidbody.AddForce или Rigidbody.MovePosition.
Непрерывный/физический способ означает, что объект может столкнуться с другим RigidBody во время движения и затем не будет перемещен в пункт назначения.< /p>
Если я хочу переместить объект телепортирующимся способом, я могу использовать Transform.postion или Rigidbody.position.
By таким образом объект телепортируется (или прыгает) из одного места в другое.
Редко непрерывный способ и способ телепортации сочетаются вместе.
Если я знаком с Unity физической системы, мне следует выбрать один способ, прежде чем программировать.
(Конечно, я не знаком с физической системой 2 года назад, поэтому я пришел к неловкому варианту, который хочу использовать оба способа.)
【Part2】
Наконец, почему изменение Transform.position приводит к тому, что Rigidbody>.MovePosition не работает?
Я не могу быть уверен, но теперь могу кое-что предположить.
Внутреннее обновление физики В ExecutionOrder — это реальное место, где физика (например, физическое перемещение, столкновение и другие).
То есть, если я запущу Rigidbody.MovePosition, твердое тело не будет перемещаться напрямую, оно будет перемещено в обновлении внутренней физики. До обновления внутренней физики объект все еще находится в старой позиции, а после обновления внутренней физики он перемещается в новую позицию.
Думаю, если я запущу Rigidbody.MovePosition(newPosition ), Unity получает от меня команду переместить объект из oldPosition в newPosition. Важны как oldPosition, так и newPosition.
(На самом деле это предположение, не имеющее доказательств. У него есть прекрасная возможность ошибиться. Единственный плюс в том, что оно может помочь мне понять, почему Transform. move несовместимо с Rigidbody.MovePosition.)
В обновлении внутренней физики, когда Unity собирается выполнить Rigidbody.MovePosition, он проверяет, находится ли объект все еще в старой позиции. Приказано переместить его из oldPosition в newPosition. Если он больше не находится в oldPosition, Unity посчитает заказ устаревшим и не выполнит Rigidbody.MovePosition.
Позиции oldPosition и newPosition являются физическими позициями, то есть Rigidbody.position.
Итак, если код Rigidbody.MovePosition выполняется в time1, обновление внутренней физики действительно выполняет Rigidbody.MovePosition в время2. Rigidbody.position должна оставаться неизменной между временем 1 и временем 2.
Итак, Rigidbody.position = oldPosition2; Rigidbody.MovePosition(newPositon); //Обновление внутренней физики — это нормально, потому что Rigidbody.position изменяется раньше Rigidbody.MovePosition, и между временем time1 и time2 изменений не будет.
Но Rigidbody.MovePosition(newPositon); Rigidbody.position = oldPosition2; //Обновление внутренней физики приведет к тому, что MovePosition не будет работать. Rigidbody.position изменяется между временем 1 и временем 2.
Давайте поговорим о Transform.position = oldPosition2; Rigidbody.MovePosition(newPositon); //Обновление внутренней физики.
Код: Выделить всё
Transform.position = oldPosition2
Я думаю, что на первом этапе обновления внутренней физики Unity синхронизирует Transform.position и Rigidbody. позиция. Если Transform.position имеет более новое значение, Rigidbody.position будет присвоено более новое значение, которым в примере является oldPosition2.
Затем, когда он собирается выполнить MovePosition, Unity обнаруживает, что Rigidbody.position изменено, поэтому оно не выполняется.
Это означает Transform.position = oldPosition2; Rigidbody.MovePosition(newPositon); //Обновление внутренней физики равно Transform.position = oldPosition2; Rigidbody.MovePosition(newPositon); Rigidbody.position = Transform.position; //Слева от обновления внутренней физики.
Rigidbody.position изменяется между временем 1 и временем 2.
Код: Выделить всё
Transform.position = oldPosition2; Physics.SyncTransforms(); Rigidbody.MovePosition(newPositon);//Internal Physics Update
Rigidbody.position не имеет изменений между time1 и time2.
Таким образом, Physics.SyncTransforms() может помочь создать Transform.position и Rigidbody.MovePosition совместимо.
В заключение:
Код: Выделить всё
Rigidbody.position = oldPosition2; Rigidbody.MovePosition(newPositon);
Код: Выделить всё
Rigidbody.MovePosition(newPositon); Rigidbody.position = oldPosition2;
Код: Выделить всё
Transform.position = oldPosition2; Rigidbody.MovePosition(newPositon);
Код: Выделить всё
Transform.position = oldPosition2; Physics.SyncTransforms(); Rigidbody.MovePosition(newPositon);
Вот и все. Это мое предположение и мое понимание спустя 2 года.
Подробнее здесь: https://stackoverflow.com/questions/688 ... s-just-cha