Как использовать «LookAt» в локальном пространстве? - PullRequest
1 голос
/ 08 апреля 2019

Я пытаюсь заставить руль указывать на мой контроллер в VR.Когда «автомобиль» поворачивается на 0 по оси Y, все работает нормально, но вращение рулевого колеса ухудшается, когда «автомобиль» GameObject вращается.Кажется, что «lookat» использует мировое пространство для перемещения рулевого колеса, хотя я могу ошибаться.У меня есть и контроллер и рулевое колесо родом из машины.Я повторил проблему в гораздо более простой сцене, которая представляет собой просто куб (routWheel) и сферу (followGO), соединенные с кубом большего размера., местное вращение и положение.Кажется, я не могу найти ничего, что работает.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class follow : MonoBehaviour
{

    public GameObject steeringWheel;
    public GameObject followGO;

    void Start()
    {

    }


    void Update()
    {
        steeringWheel.transform.LookAt(new Vector3(followGO.transform.position.x, followGO.transform.position.y, steeringWheel.transform.position.z), steeringWheel.transform.up);
    }
}

Это нормально, когда я нажимаю play, "колесо" указывает на шар на оси, которую я просил.

Нокак только я поверну родительский куб по оси Y ...

1 Ответ

2 голосов
/ 08 апреля 2019

Как вы правильно заметили LookAt ожидает координату Vector3 в мировом пространстве .

Ваш сценарий работает так, как ожидалось, если автомобиль невращался сам, потому что в этом случае разница в положении между контроллером и колесом (случайно) находится в направлении Z.

Но если автомобиль повернут против мира, вы не можете полагаться на простое использование

new Vector3(followGO.transform.position.x, followGO.transform.position.y, steeringWheel.transform.position.z)

, поскольку это не мировая разница Z, которую вы хотите больше устранить.


Вместо этого вы хотите устранить локальную разницу между контроллером и рулевым колесом в его локальном Yнаправление.Вы можете использовать Transform.InverseTransformPoint для преобразования мировой координаты в локальную пространственную координату и Transform.TransformPoint для преобразования локальной координаты в мировую космическую координату:

// I just directly used Transform here
// to save a bit of coding later
public Transform steeringWheel;
public Transform followGO;

private void Update()
{
    // returns the position of followGO relative to the steeringwheel
    // but in the local transform space of the steering wheel itself
    var relativePosition = steeringWheel.InverseTransformDirection(followGO.position);

    // you want to eliminate the local difference in Y direction
    relativePosition.y = 0;

    // since you are right and LookAt expects a world position after eliminating the local Y difference 
    // we convert it back to world space
    var targetPosition = steeringWheel.TransformPoint(relativePosition);

    steeringWheel.transform.LookAt(targetPosition, steeringWheel.transform.up);
}

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

enter image description here


Для сравнения, если хотите: example.unitypackage

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...