Transform.forward не указывает вперед после поворота

У меня есть человек GameObject, которым игрок может управлять с помощью клавиш со стрелками. Когда игрок нажимает left или right, я поворачиваю персонажа с помощью Transform.Rotate.

Однако я обнаружил неточность, которую не могу объяснить, пытаясь продвинуть персонажа вперед.

  • Если я установлю velocity на компоненте GameobjectRigidbody (нажав вверх), то персонаж будет двигаться в том направлении, в котором смотрит.
  • Однако если я использую Tranform.Translate в направлении transform.forward (нажимая W), то персонаж не будет двигаться в том направлении, в котором смотрит. Вместо этого они движутся в том направлении, в котором они смотрели бы, если бы к ним было применено это вращение дважды. Так, например, если я удержу left, пока они не повернутся на 45 градусов, а затем нажму W, персонаж переместится так, как если бы я повернул их на 90 градусов, а затем нажал Up.
void Start()
{
    m_Rigidbody = GetComponent<Rigidbody>();
    m_Speed = 1.0f;
}

void Update()
{
    if (Input.GetKey(KeyCode.UpArrow))
    {
        m_Rigidbody.velocity = transform.forward * m_Speed;
    }

    if (Input.GetKey(KeyCode.W))
    {
        transform.Translate(transform.forward * Time.deltaTime * m_Speed);
    }

    if (Input.GetKey(KeyCode.RightArrow))
    {
        transform.Rotate(new Vector3(0, 1, 0) * Time.deltaTime * m_Speed * 50, Space.Self);
    }

    if (Input.GetKey(KeyCode.LeftArrow))
    {
        transform.Rotate(new Vector3(0, -1, 0) * Time.deltaTime * m_Speed * 50, Space.Self);
    }
}

Я напечатал направление transform.forward, и кажется, что оно всегда указывает в том направлении, в котором смотрит персонаж. Тогда почему Transform.Translate в направлении transform.forward не перемещает персонажа в том направлении, в котором он смотрит?

Возможные параметры конфигурации, которые могут повлиять на ситуацию:

  • У персонажа есть convexMeshCollider
  • Rigidbody персонажа не является kinematic и ограничен вращением X и Z.
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Путаница связана с местными и мировыми координатами. Давайте разберемся:

transform.Translate(m_Speed * Time.deltaTime * transform.forward)

Если вы не укажете Space, Transform.Translate() переместит ваш объект в локальные координаты. Теперь transform.foward захватывает локальный forward вектор, но возвращает его в мировых координатах. Поэтому у вас есть два варианта:

  1. В местных координатах:

    transform.Translate(m_Speed * Time.deltaTime * Vector3.forward);
    
  2. В мировых координатах:

    transform.Translate(m_Speed * Time.deltaTime * transform.forward, Space.World);
    

Кстати: изменение порядка коэффициентов умножения может сыграть роль с точки зрения эффективности вычислений, поскольку скалярное умножение выполняется быстрее, чем векторное

Спасибо за ответ и за дополнительный совет об эффективности вычислений.

dshapiro 07.04.2024 21:17

Другие вопросы по теме