Unity 6. Камера от третьего лица.


Камера от третьего лица в Unity 6 — это система, которая позволяет управлять камерой так, чтобы она следовала за персонажем, а также могла вращаться и изменять положение относительно него. Здесь рассмотрим как это реализовать с помощью скриптов C#.

Сразу условимся, что камера будет дочерним элементом самого игрока, а также добавим условие, что она не должна выходить за стены, при приближении к ним. Чтобы камера от третьего лица в Unity 6 не проходила сквозь стены, лучше всего использовать Raycast: он «прощупывает» пространство между игроком и желаемой позицией камеры и при обнаружении препятствия подтягивает камеру ближе.

1. В редакторе Unity создадим некое подобие дома, состоящего из пола и стен, и поместим в него нашего игрока (Player).

2. В разделе Hierarhy, необходимо мышкой перетащить Main Camera на нашего персонажа Player, таким образом мы камеру сделаем дочерним элементом нашего персонажа.

3. Создадим слой "Stena". Для этого переходим в меню Edit - Project Settings. Там находим Tags and Layers и в свободном поле пишем "Stena".

4. В Hiearhy необходимо выбрать все стены и в Inspector в поле Layer выбрать из списка слой "Stena"

5. Теперь напишем скрипт (Camera) и перетащим его мышкой на Main Camera. Раз камера обязательно дочерняя к игроку, решением будет динамически менять её localPosition.z через Raycast — «подтягивать» камеру ближе к игроку, когда позади стена.

 

using UnityEngine;

public class Camera : MonoBehaviour
{
    [Header("Ссылки")]
    public Transform player;

    [Header("Настройки дистанции и высоты")]
    public float defaultDistance = 5f;          // Дистанция от игрока (Z)
    public float defaultHeight = 2f;             // Высота камеры над игроком (Y)
    public float minDistance = 1f;              // Минимальная дистанция до игрока
    public float smoothSpeed = 12f;         // Скорость сглаживания

    [Header("Слои и геометрия")]
    public LayerMask collisionMask;         // Слои стен/препятствий
    public float sphereRadius = 0.3f;         // Радиус проверки (чтобы камера не прилипала к стене)

    private float _currentDistance;

    void Start()
    {
        _currentDistance = defaultDistance;
    }

    void LateUpdate()
    {
        if (player == null) return;

        // Желаемая позиция камеры в мировых координатах
        Vector3 origin = player.position;
        
        // Локальное смещение: (0, высота, -дистанция)
        Vector3 desiredLocalPos = new Vector3(0f, defaultHeight, -defaultDistance);
        
        // Переводим в мировые координаты с учётом поворота игрока
        Vector3 desiredWorldDir = player.rotation * desiredLocalPos;
        Vector3 desiredWorldPos = origin + desiredWorldDir;

        Vector3 dirToCamera = desiredWorldPos - origin;
        float maxRayLength = dirToCamera.magnitude;

        float targetDistance = defaultDistance;

        // SphereCast от игрока к желаемой позиции камеры
        if (Physics.SphereCast(
            origin,
            sphereRadius,
            dirToCamera.normalized,
            out RaycastHit hit,
            maxRayLength,
            collisionMask))
        {
            // Нашли стену — уменьшаем дистанцию, чтобы не было пересечения
            float safeDist = hit.distance - sphereRadius;
            targetDistance = Mathf.Max(safeDist, minDistance);
        }

        // Плавно меняем дистанцию
        _currentDistance = Mathf.Lerp(_currentDistance, targetDistance, Time.deltaTime * smoothSpeed);

        // Формируем итоговую локальную позицию: высота не меняется, дистанция меняется
        Vector3 localOffset = new Vector3(0f, defaultHeight, -_currentDistance);

        // Плавно двигаем камеру по localPosition
        transform.localPosition = Vector3.Lerp(
            transform.localPosition,
            localOffset,
            Time.deltaTime * smoothSpeed
        );

        // Камера смотрит на игрока
        transform.rotation = Quaternion.LookRotation(player.position - transform.position, Vector3.up);
    }
}

 

Настройка в редакторе:


- Камера (Main Camera) уже дочерняя к игроку — оставляем как есть.
- Повесьте скрипт на саму камеру.
- В поле Player перетащите игрока.
- Collision Mask — выберите слои, на которых у вас стены, пол, потолок (создайте слой Walls, если его нет, и назначьте стенам).
- Default Distance — то расстояние, на котором камера должна быть в норме (например, 5).
- Sphere Radius — «толщина» камеры, чтобы она не прилипала вплотную к стене (0.2–0.5 обычно достаточно).

 

Как это работает:


Каждый кадр скрипт пускает SphereCast от игрока назад — туда, где камера «хотела бы» быть.
Если луч натыкается на стену, камера подтягивается к игроку ровно настолько, чтобы не пересечь стену.
Если стены нет — камера плавно возвращается на defaultDistance.
Всё это делается через localPosition.z, так что камера остаётся полноценным дочерним объектом игрока и двигается вместе с ним.
Подводные камни
Игрок не должен быть в Collision Mask, иначе Raycast упрётся в коллайдер игрока и камера «схлопнется». Вынесите игрока на отдельный слой и исключите его из маски.
Поворот камеры — в скрипте камера поворачивается, чтобы смотреть на игрока через Quaternion.LookAt. Если вы уже управляете вращением камеры отдельно (например, через Cinemachine или мышкой), уберите последнюю строку с transform.rotation и оставьте только корректировку позиции.
LateUpdate — обязателен, иначе камера будет дёргаться, так как обновляется до перемещения игрока.

Вот и всё, теперь наша камера настроена для игры от третьего лица, при этом избегает выхода за стены.



Вернуться назад