Камера от третьего лица. Контроль камеры от третьего лица

Камера от третьего лица. Контроль камеры от третьего лица

05.03.2019

Самый простой способ реализации, сделать камеру дочерней к игроку, тогда она всегда будет закреплена в установленной позиции. Но, такой вариант имеет ряд различных недостатков, в следствии наследования свойств родителя. Поэтому, будем делать контроль игрока и камеры, как отдельных объектов, которые будут связаны через скрипты. Итак, камера у нас должна иметь возможность вращаться вокруг игрока свободно. Возможность разместить камеру за плечо персонажа, слева или справа. Возможность наклона вверх или вниз, с ограничением углов. Отслеживание препятствий между персонажем и камерой. Разворот персонажа в сторону движения, относительно камеры. Регулировка плавности следования за персонажем.

Скрипт для персонажа PlayerControlTPS :

Using UnityEngine; using System.Collections; public class PlayerControlTPS: MonoBehaviour { public float speed = 1.5f; // макс. скорость public float acceleration = 100f; // ускорение public Transform rotate; // объект вращения (локальный) public KeyCode jumpButton = KeyCode.Space; // клавиша для прыжка public float jumpForce = 10; // сила прыжка public float jumpDistance = 1.2f; // расстояние от центра объекта, до поверхности private Vector3 direction; private float h, v; private int layerMask; private Rigidbody body; private float rotationY; private float rotationX; void Awake() { body = GetComponent(); body.freezeRotation = true; gameObject.tag = "Player"; // объекту должен быть присвоен отдельный слой, для работы прыжка layerMask = 1 << gameObject.layer | 1 << 2; layerMask = ~layerMask; } void FixedUpdate() { body.AddForce(direction.normalized * acceleration * body.mass * speed); // Ограничение скорости, иначе объект будет постоянно ускоряться if(Mathf.Abs(body.velocity.x) > speed) { body.velocity = new Vector3(Mathf.Sign(body.velocity.x) * speed, body.velocity.y, body.velocity.z); } if(Mathf.Abs(body.velocity.z) > speed) { body.velocity = new Vector3(body.velocity.x, body.velocity.y, Mathf.Sign(body.velocity.z) * speed); } } bool GetJump() // проверяем, есть ли коллайдер под ногами { bool result = false; RaycastHit hit; Ray ray = new Ray(transform.position, Vector3.down); if (Physics.Raycast(ray, out hit, jumpDistance, layerMask)) { result = true; } return result; } void Update() { h = Input.GetAxis("Horizontal"); v = Input.GetAxis("Vertical"); // вектор направления движения direction = new Vector3(h, 0, v); direction = Camera.main.transform.TransformDirection(direction); direction = new Vector3(direction.x, 0, direction.z); if(Mathf.Abs(v) > 0 || Mathf.Abs(h) > 0) // разворот тела по вектору движения { rotate.rotation = Quaternion.Lerp(rotate.rotation, Quaternion.LookRotation(direction), 10 * Time.deltaTime); } Debug.DrawRay(transform.position, Vector3.down * jumpDistance, Color.red); // подсветка, для визуальной настройки jumpDistance if(Input.GetKeyDown(jumpButton) && GetJump()) { body.velocity = new Vector2(0, jumpForce); } } }
Это немного переделанный скрипт, который мы ранее использовали для шутера от первого лица. Здесь вектор движения рассчитывается относительно камеры, а не поворота головы, как было ранее. А разворот по вектору происходит, если нажата одна из клавиш движения. При этом разворачиваем мы не сам объект на котором весит Rigidbody, а дочерние объекты, вращение самого Rigidbody заблокировано. В случаи, когда мы вращаем дочерние объекты, у нас больше вариантов, можно выбрать, какие трансформы будут вращаться, а какие будут всегда в исходном виде.

Скрипт для камеры CameraControlTPS :

Using UnityEngine; using System.Collections; public class CameraControlTPS: MonoBehaviour { public enum InversionX {Disabled = 0, Enabled = 1}; public enum InversionY {Disabled = 0, Enabled = 1}; public enum Smooth {Disabled = 0, Enabled = 1}; public float sensitivity = 2; // чувствительность мышки public float distance = 5; // расстояние между камерой и игроком public float height = 2.3f; // высота public float offsetPosition; // смешение камеры вправо или влево, 0 = центр public float minY = 15f; // ограничение углов при наклоне public float maxY = 15f; // инверсия осей public InversionX inversionX = InversionX.Disabled; public InversionY inversionY = InversionY.Disabled; public Smooth smooth = Smooth.Enabled; public float speed = 8; // скорость сглаживания private float rotationY; private int inversY, inversX; private Transform player; void Start() { player = GameObject.FindGameObjectWithTag("Player").transform; gameObject.tag = "MainCamera"; } // проверяем, если есть на пути луча, от игрока до камеры, какое-либо препятствие (коллайдер) Vector3 PositionCorrection(Vector3 target, Vector3 position) { RaycastHit hit; Debug.DrawLine(target, position, Color.blue); if(Physics.Linecast(target, position, out hit)) { float tempDistance = Vector3.Distance(target, hit.point); Vector3 pos = target - (transform.rotation * Vector3.forward * tempDistance); position = new Vector3(pos.x, position.y, pos.z); // сдвиг позиции в точку контакта } return position; } void LateUpdate() { if(player) { if(inversionX == InversionX.Disabled) inversX = 1; else inversX = -1; if(inversionY == InversionY.Disabled) inversY = -1; else inversY = 1; // вращение камеры вокруг игрока transform.RotateAround(player.position, Vector3.up, Input.GetAxis("Mouse X") * sensitivity * inversX); // определяем точку на указанной дистанции от игрока Vector3 position = player.position - (transform.rotation * Vector3.forward * distance); position = position + (transform.rotation * Vector3.right * offsetPosition); // сдвиг по горизонтали position = new Vector3(position.x, player.position.y + height, position.z); // корректировка высоты position = PositionCorrection(player.position, position); // находим текущую позицию, относительно игрока // поворот камеры по оси Х rotationY += Input.GetAxis("Mouse Y") * sensitivity; rotationY = Mathf.Clamp(rotationY, -Mathf.Abs(minY), Mathf.Abs(maxY)); transform.localEulerAngles = new Vector3(rotationY * inversY, transform.localEulerAngles.y, 0); if(smooth == Smooth.Disabled) transform.position = position; else transform.position = Vector3.Lerp(transform.position, position, speed * Time.deltaTime); } } }
Камера не должна быть дочерним объектом! Основные комментарии есть в коде. Стоит отметить, что настроить ее можно как по центру, относительно игрока. Так и сдвинуть к левому или правому плечу, часто такой вид используется при прицеливании.

Скачать демо сцену.

Еще один хороший способ избежать рвоты, использовать камеру от третьего лица. Теперь ничего игроку не мешает и ничего не мелькает, снижая вероятность приступа эпилепсии. Камера от третьего лица дает более широкий обзор, а также видения того, что происходит за вами. Обернись! За тобой скелет!

Камера от третьего лица имеет преимущества пере FPC. Во-превых, вы можете видеть вашего персонажа целиком. Но лица же не видно!? Игрок может развернутся и побежать навстречу камере. Главное, чтобы камера отодвигалась и игрок не вошел в нее. Стало ли управление более легким? И как восстановить исходное положение камеры? Это труднее, чем думал.

Работа с TPC может быть самой большой трудность при разработке игры. Обсудим некоторые моменты TPC.

Движение камеры. Когда я учился в школе, я часто снимал разные спортивные мероприятия. Смотря в камеру, я не видел ничего вокруг. Однажды я споткнулся и упал вместе с камерой, из за чего пропустил замечательный гол. Чтобы решить эту проблему я взял в друга в качестве наблюдателя, чтобы свести такие случаи к минимуму.

Этот опыт убедил меня, что у каждой камеры должен быть корректировщик. Настройте камеру таким образом, чтобы игрок видел куда идет. Можете также дать игроку самому возможность настроить камеру.

Камера-призрак. Этот эффект появляется, когда камера проходит сквозь персонажа или объекты. Ничто не разрушает иллюзию реальности быстрее, чем эффект камеры-призрака. Что еще хуже, камера может пройти сквозь фоновые слои, таки как небо или стена. Это выглядит ужасно и приложите большие усилия, чтобы этого не произошло в игре.

Вы можете избежать этого эффекта, например заставляя камеру приближаться к игроку, если она наткнулась на препятствие или изменять ракурс.

Управление. Продумайте, как ваша камера будет реагировать на передвижения игрока.

Края. Разработчики часто создают сложные сложные системы, чтобы камеры не проходили сквозь объекты и так далее. Но часто случается, что в углах камера пытается найти нормальное место, в соответствии с заданной ей системой, но не может и начинает бешено трестись. Вместо того, чтобы придумывать сложные системы камер, просто держите игроков подальше от углов, в первою очередь. Но иногда вместо этого создаются невидимые объекты (о, как я ненавижу их! О них поговорим немного позже).

Итак, вы не услышали меня. Если ваш игрок идет к углу, поднимайте вашу камеру вверх. Но не ставьте камеру полностью вертикально, это выглядит плохо.

Позиция. Темой бесконечных споров среди геймдизайнеров в мире является вопрос: должна ли камера строго следить за игроком, как будто прикреплена к нему тросом или должна быть более свободной и вращаться вокруг персонажа.

Может быть из за того, что я вырос в Южной Калифорнии, я за второй метод по следующим причинам: есть меньше шансов сломать камеру, время от времени вы можете увидеть лицо персонажа, можно делать динамичные сцены, такие как погони. Еще одним спорным вопросом является настройка и управление камерой.



© 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows