Страница 1 из 2

LookAt и

СообщениеДобавлено: 31 авг 2020, 23:31
MiniCat
Для обычной работы камеры использую:
m_MouseLook.LookRotation(transform, m_Camera.transform);
Но порой нужно обратить внимание игрока на определенный объект, тогда использую:
m_Camera.transform.LookAt(ObjectForView); Где ObjectForView - объект наблюдения.
Всё работает хорошо, но в момент, когда мне нужно переключиться обратно с объекта наблюдения на свободный обзор, происходит слишком резкий скачок на точку, которую наблюдал персонаж до начала работы LookAt.
Понятно, что мне нужно подсунуть последние координаты, где остановился взгляд персонажа до начала работы m_MouseLook.LookRotation, но как это сделать нормально, не могу понять.
Need Help!)

Re: LookAt и

СообщениеДобавлено: 31 авг 2020, 23:40
1max1
Запомни rotation в переменную, потом лерпай к нему.

Re: LookAt и

СообщениеДобавлено: 01 сен 2020, 00:12
MiniCat
1max1 писал(а):Запомни rotation в переменную, потом лерпай к нему.

Так я туплю и не понимаю, rotation именно чего нужно брать.
Ведь по идее после LookAt камера должна сохранить свое положение, а не дрыгать назад, в момент когда я заставил её смотреть в определенном положении.

Re: LookAt и

СообщениеДобавлено: 01 сен 2020, 01:13
MiniCat
Я может не совсем корректно объяснил что хочу.
Нужно чтобы после конца выполнения LookAt направление камеры не возвращалось к прежнему, а оставалось на месте.

Re: LookAt и

СообщениеДобавлено: 01 сен 2020, 06:12
MrDmitry
Чет теперь я не понял что вам нужно, в первом посте вы говорите что вам нужно убрать резкий скачек, а потом говорите что камера должна остаться на месте.


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


Я может не совсем корректно объяснил что хочу.
Нужно чтобы после конца выполнения LookAt направление камеры не возвращалось к прежнему, а оставалось на месте.


По моему тут какое то противоречие.

Re: LookAt и

СообщениеДобавлено: 01 сен 2020, 09:14
MiniCat
MrDmitry писал(а):Чет теперь я не понял что вам нужно, в первом посте вы говорите что вам нужно убрать резкий скачек, а потом говорите что камера должна остаться на месте.


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


Я может не совсем корректно объяснил что хочу.
Нужно чтобы после конца выполнения LookAt направление камеры не возвращалось к прежнему, а оставалось на месте.


По моему тут какое то противоречие.


Окей. Еще раз по порядку объясню проблему :D
Представим что игрок идет и наблюдает красоты террайна. Например на водопад слева по движению.
Игрок заходит в зону триггера и скрипт принудительно обращает внимание с помощью LookAt на нужный объект (например записка на земле). Это происходит резко, но мне так и нужно.
Игрок смотрит на записку условные 3 секунды. После этого управление переходит LookRotation . Камера резко возвращается на тот самый водопад, на который до этого смотрел игрок. А мне нужно чтобы камера осталась на записке.

Re: LookAt и

СообщениеДобавлено: 01 сен 2020, 10:04
1max1
Очень интересно посмотреть на этот код, потому что сама по себе она бы так не сделала и там явно где-то прописан тот самый возврат, который тебе надо ВИИИРИИИЗАТЬ!!!

Re: LookAt и

СообщениеДобавлено: 01 сен 2020, 10:30
waruiyume
Мауслук хранит поворот в углах Эйлера, выставляя в старте или авейке то значение, которое должно быть для начального поворота. Вам этот код нужно перед активаций мауслук вызвать.

Re: LookAt и

СообщениеДобавлено: 01 сен 2020, 21:27
MiniCat
1max1 писал(а):Очень интересно посмотреть на этот код, потому что сама по себе она бы так не сделала и там явно где-то прописан тот самый возврат, который тебе надо ВИИИРИИИЗАТЬ!!!

Код на основе стандартного FPS контроллера. Оставил только то, что касается проблемы.
Не понимаю как в m_MouseLook подсунуть нужные сохранённые углы(
m_MouseLook.Init(transform, m_Camera.transform); не помогает.

подсовывать
m_MouseLook.m_CameraTargetRot.SetEulerRotation(m_Camera.transform.rotation.x, m_Camera.transform.rotation.y, m_Camera.transform.rotation.z);
тоже

Синтаксис:
Используется csharp
private Camera m_Camera;
[SerializeField] Transform ObjectForView;
public bool NeedToView;
 


Синтаксис:
Используется csharp

private void RotateView()
{
     m_MouseLook.LookRotation(transform, m_Camera.transform);
}

private void Update()
{
     if (NeedToView) //нужно посмотреть на объект
          m_Camera.transform.LookAt(ObjectForView);
     else
          RotateView();
}
 


Понятно только что мне сюда нужно подсунуть нужные углы...

Синтаксис:
Используется csharp
 public void LookRotation(Transform character, Transform camera)
        {
            float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
            float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;

            m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f);
            m_CameraTargetRot *= Quaternion.Euler (-xRot, 0f, 0f);

            if(clampVerticalRotation)
                m_CameraTargetRot = ClampRotationAroundXAxis (m_CameraTargetRot);

            if(smooth)
            {
                character.localRotation = Quaternion.Slerp (character.localRotation, m_CharacterTargetRot,
                    smoothTime * Time.deltaTime);
                camera.localRotation = Quaternion.Slerp (camera.localRotation, m_CameraTargetRot,
                    smoothTime * Time.deltaTime);
            }
            else
            {
                character.localRotation = m_CharacterTargetRot;
                camera.localRotation = m_CameraTargetRot;
            }

          //  UpdateCursorLock();
        }

Re: LookAt и

СообщениеДобавлено: 02 сен 2020, 18:45
waruiyume
waruiyume писал(а):Мауслук хранит поворот в углах Эйлера, выставляя в старте или авейке то значение, которое должно быть для начального поворота. Вам этот код нужно перед активаций мауслук вызвать.

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

Re: LookAt и

СообщениеДобавлено: 02 сен 2020, 19:28
MiniCat
waruiyume писал(а):
waruiyume писал(а):Мауслук хранит поворот в углах Эйлера, выставляя в старте или авейке то значение, которое должно быть для начального поворота. Вам этот код нужно перед активаций мауслук вызвать.

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


Вот весь код. Не хватало только ClampRotationAroundXAxis.

Синтаксис:
Используется csharp
namespace UnityStandardAssets.Characters.FirstPerson
{
    [Serializable]
    public class MouseLook
    {
        public float XSensitivity = 2f;
        public float YSensitivity = 2f;
        public bool clampVerticalRotation = true;
        public float MinimumX = -90F;
        public float MaximumX = 90F;
        public bool smooth;
        public float smoothTime = 5f;
        public bool lockCursor = true;
        private string GOname;

        public Quaternion m_CharacterTargetRot;
        public Quaternion m_CameraTargetRot;
        private bool m_cursorIsLocked = true;

        public float yRot, xRot;


        public void Init(Transform character, Transform camera)
        {
            m_CharacterTargetRot = character.localRotation;
            m_CameraTargetRot = camera.localRotation;
        }


        public void LookRotation(Transform character, Transform camera)
        {
            yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
            xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;

            m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f);
            m_CameraTargetRot *= Quaternion.Euler (-xRot, 0f, 0f);

            if (clampVerticalRotation)
                m_CameraTargetRot = ClampRotationAroundXAxis (m_CameraTargetRot);

            if(smooth)
            {
                character.localRotation = Quaternion.Slerp (character.localRotation, m_CharacterTargetRot,
                    smoothTime * Time.deltaTime);
                camera.localRotation = Quaternion.Slerp (camera.localRotation, m_CameraTargetRot,
                    smoothTime * Time.deltaTime);
            }
            else
            {
                character.localRotation = m_CharacterTargetRot;
                camera.localRotation = m_CameraTargetRot;
            }

          //  UpdateCursorLock();
        }

        Quaternion ClampRotationAroundXAxis(Quaternion q)
        {
            q.x /= q.w;
            q.y /= q.w;
            q.z /= q.w;
            q.w = 1.0f;

            float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan (q.x);

            angleX = Mathf.Clamp (angleX, MinimumX, MaximumX);

            q.x = Mathf.Tan (0.5f * Mathf.Deg2Rad * angleX);

            return q;
        }

    }
}

Re: LookAt и

СообщениеДобавлено: 02 сен 2020, 22:56
waruiyume
m_Camera.transform.LookAt(ObjectForView)

Так делать нельзя, т.к. мауслук вращает 2 объекта: камеру по X и её родителя(видимо), по Y, поэтому и наводиться на объект интереса нужно двумя объектами.
Для тушки обнуляете Y компонент вектора направленного на цель, а потом используете Quaternion.LookRotation.
Для камеры вектор сначала нужно перевести в систему координат тушки, потом обнулить X, вернуть в мировую систему и уже потом использовать Quaternion.LookRotation.
По идеее, потом останется вызвать Init, а затем включить мауслук.

Re: LookAt и

СообщениеДобавлено: 04 сен 2020, 00:37
MiniCat
waruiyume писал(а):
m_Camera.transform.LookAt(ObjectForView)

Так делать нельзя, т.к. мауслук вращает 2 объекта: камеру по X и её родителя(видимо), по Y, поэтому и наводиться на объект интереса нужно двумя объектами.
Для тушки обнуляете Y компонент вектора направленного на цель, а потом используете Quaternion.LookRotation.
Для камеры вектор сначала нужно перевести в систему координат тушки, потом обнулить X, вернуть в мировую систему и уже потом использовать Quaternion.LookRotation.
По идеее, потом останется вызвать Init, а затем включить мауслук.


На основе ваших рекомендаций получился следующий код: (но к сожалению я где-то затупил с математикой и код срабатывает не всегда корректно, порой наблюдается некоторый перекос камеры после инициализации). Не могли бы вы указать на ошибку?

Синтаксис:
Используется csharp
private Camera m_Camera;
[SerializeField] Transform ObjectForView;
public bool NeedToView,CutSceneInit,NeedLoadRotation;
 


Синтаксис:
Используется csharp

private void RotateView()
{
     if (NeedLoadRotation) //после фокуса на объект, заново инициируем камеру
     {
         m_MouseLook.Init(transform,m_Camera.transform);
        NeedLoadRotation = false;
         CutSceneInit = false;
     }
     m_MouseLook.LookRotation(transform, m_Camera.transform);
}

private void Update()
{
     if (NeedToView) //нужно посмотреть на объект
          {
                    if (!CutSceneInit) //заходим сюда единожды, далее работают скрипты наводки на объект, а это разовая инициализация
                    {
                        //обнуляем координату у контроллера
                        transform.localRotation = Quaternion.Euler(transform.localRotation.x, 0f, transform.localRotation.z);
                        //переводим камеру в координаты контроллера
                        Vector3 cameraRelative = m_Camera.transform.InverseTransformPoint(transform.position);
                        m_Camera.transform.localEulerAngles = cameraRelative;
                        //обнуляем х камеры
                        m_Camera.transform.localRotation = Quaternion.Euler(0f, transform.localRotation.y, transform.localRotation.z);
                        //переводим в глобальную
                        Vector3 relativePoint = m_Camera.transform.TransformPoint(0, 0, 0);
                        m_Camera.transform.eulerAngles = cameraRelative;
                        //инициализируем 1 раз
                        CutSceneInit = true;
                     }
                    //следим за объектом контроллером
                    transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(ObjectsForView.transform.position - transform.position), 5f * Time.deltaTime);
                    //следим за объектом камерой
                    m_Camera.transform.rotation = Quaternion.Slerp(m_Camera.transform.rotation, Quaternion.LookRotation(ObjectsForView.transform.position - m_Camera.transform.position), 5f * Time.deltaTime);
                    //выставляем флаг чтобы камеру проинитить и контроллер (transform это он)
                    NeedLoadRotation = true;
          }
     else
          RotateView();
}
 

Re: LookAt и

СообщениеДобавлено: 06 сен 2020, 15:50
MiniCat
Help me pls :(

Re: LookAt и

СообщениеДобавлено: 06 сен 2020, 19:10
waruiyume
Описанное мной должно происходить либо каждый кадр, перед переключением на мауслук.