Единство: поворот камеры по закону косинуса

Я делаю основные элементы управления для игры, ориентированной на мышь. Я хочу, чтобы камера следовала за игроком и вращалась вокруг него, используя закон косинуса, чтобы найти угол. Вот мой код:

//Move Camera
camX = player.transform.position.x;
camY = 15.5f;
camZ = player.transform.position.z;

//Rotate Camera
rotTriA = player.transform.position.x;
rotTriB = player.transform.position.z;
rotTriC = Mathf.Sqrt((rotTriA * rotTriA) + (rotTriB + rotTriB));

if(rotTriA > 0 && rotTriB > 0)
{
    getAngle = (Mathf.Acos(((rotTriA * rotTriA)
        + (rotTriB * rotTriB)
        - (rotTriC * rotTriC))
        / (2 * (rotTriA) * (rotTriB))) * Mathf.Rad2Deg);
}
else if(rotTriA > 0 && rotTriB < 0)
{
    getAngle = (Mathf.Acos(((rotTriA * rotTriA)
        + (rotTriB * rotTriB)
        - (rotTriC * rotTriC))
        / (2 * (rotTriA) * (rotTriB))) * Mathf.Rad2Deg) + 90;
}
else if(rotTriA < 0 && rotTriB < 0)
{
    getAngle = (Mathf.Acos(((rotTriA * rotTriA)
        + (rotTriB * rotTriB)
        - (rotTriC * rotTriC))
        / (2 * (rotTriA) * (rotTriB))) * Mathf.Rad2Deg) + 180;
}
else if(rotTriA < 0 && rotTriB > 0)
{
    getAngle = (Mathf.Acos(((rotTriA * rotTriA)
        + (rotTriB * rotTriB)
        - (rotTriC * rotTriC))
        / (2 * (rotTriA) * (rotTriB))) * Mathf.Rad2Deg) + 270;
}
else if(rotTriA == 0 && rotTriB > 0)
{
    getAngle = 90;
}
else if(rotTriA == 0 && rotTriB < 0)
{
    getAngle = 270;
}
else if(rotTriA > 0 && rotTriB == 0)
{
    getAngle = 0;
}
else if(rotTriA < 0 && rotTriB == 0)
{
    getAngle = 180;    
}
else
{
    getAngle = 0;
}

Debug.Log(getAngle);

if (camZ < 0)
{
    camZ = player.transform.position.z + 10.5f;
    transform.eulerAngles = new Vector3(135f, getAngle, 0.0f);
}
else
{
    camZ = player.transform.position.z - 10.5f;
    transform.eulerAngles = new Vector3(45f, getAngle, 0.0f);
}
camZ = player.transform.position.z - 15.5f;
cam = new Vector3(-camX, camY, camZ);
mainCamera.transform.position = cam;

Я знаю, как заставить камеру следовать за игроком, но я не знаю, как заставить камеру вращаться вокруг игрока, чтобы это не волновало.

Возможные причины, по которым это происходит: я использую raycasting для перемещения игрока, поэтому, когда я перемещаю мышь за пределы арены, движения не регистрируются, я могу неправильно выполнять закон косинуса, потому что я получаю значения до 400 ( что не должно быть возможным, учитывая окружность 360 градусов).


person Bradley William Elko    schedule 11.12.2017    source источник
comment
Вы делаете это просто ради этого? Потому что, если вы просто ищете простой способ заставить камеру вращаться вокруг объекта, это можно сделать с помощью некоторых дополнительных и базовых API-интерфейсов Unity.   -  person Foggzie    schedule 11.12.2017
comment
@Foggzie Я не мог придумать более простого способа сделать это.   -  person Bradley William Elko    schedule 11.12.2017
comment
@Foggzie Я просто хочу, чтобы он вращался вокруг игрока.   -  person Bradley William Elko    schedule 11.12.2017


Ответы (1)


Самый простой способ заставить камеру вращаться вокруг игрока - воспользоваться иерархией игровых объектов.

Сначала создайте пустой GameObject, а затем сделайте свою камеру его дочерним элементом:

EmptyObject
  > Camera

Теперь сориентируйте камеру, чтобы посмотреть на положение пустого объекта. Местоположение этого пустого объекта теперь находится там, где ваша камера «смотрит». Поскольку камера является дочерней, если вы повернете этот объект, камера будет вращаться вокруг него (при сохранении ориентации лицом к пустому объекту).

Простой скрипт для поворота пустого объекта, благодаря трансформации родительского элемента, заставит камеру "вращаться" вокруг него, глядя на него:

using UnityEngine;

public class CameraInput : MonoBehaviour
{
    [SerializeField] private float rotationAcceleration; // radians/(frame^2)
    [SerializeField] private float rotationSpeedMax; // radians/frame
    [SerializeField] private float rotationDamping; // 0.99

    private float rotationSpeed;

    private void Awake()
    {
        rotationSpeed = rotationSpeedMax / 4;
    }

    private void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            rotationSpeed += rotationAcceleration;
        }
        if (Input.GetKey(KeyCode.D))
        {
            rotationSpeed -= rotationAcceleration;
        }

        rotationSpeed = Mathf.Clamp(
            rotationSpeed, -rotationSpeedMax, rotationSpeedMax);

        transform.Rotate(0f, rotationSpeed, 0f);

        rotationSpeed *= rotationDamping;
    }
}

Присоединение чего-то подобного к объекту EmptyObject поможет. Теперь вам просто нужен этот пустой объект, чтобы следовать за вашим персонажем. Функции вращения принимают радианы в качестве аргументов, поэтому вы захотите использовать небольшие числа [0,00 ~ 0,01]. Кроме того, это покадровая реализация, поэтому она будет работать плавно только при плавной частоте кадров; вы захотите в конечном итоге включить в него Time.deltaTime фактор.

person Foggzie    schedule 11.12.2017
comment
Я хочу, чтобы камера вращалась в зависимости от того, где находится мышь от центра. - person Bradley William Elko; 11.12.2017
comment
@BradleyWilliamElko Вам понадобится рисунок или какой-нибудь наглядный материал, чтобы это объяснить; Я не понимаю, что вы имеете в виду. - person Foggzie; 11.12.2017
comment
@BradleyWilliamElko Хотя сценарий и логика легко переносимы; это решило задачу заставить камеру вращаться вокруг любого заданного объекта, вы можете изменить ввод, чтобы принять все, что хотите. - person Foggzie; 12.12.2017