работа с камерой

Простое следование за объектом без поворотов камеры

using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    public Transform targetObject;
    private Vector3 initalOffset;
    private Vector3 cameraPosition;

    void Start()
    {
        initalOffset = transform.position - targetObject.position;
    }
    void FixedUpdate()
    {
        cameraPosition = targetObject.position + initalOffset;
        transform.position = cameraPosition;
    }
}

Поворачиваем камеру в сторону объекта(функцияLookAt()):

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

public class look : MonoBehaviour
{
   public Transform kubik;
   public Transform sphere;
    


    void Update()
    {
      if(Input.GetKeyDown(KeyCode.S)) transform.LookAt(kubik);
      if(Input.GetKeyDown(KeyCode.D)) transform.LookAt(sphere);  
    }
}

Слежение камеры за транспортом с обходом препятствий:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class SimpleCamera : MonoBehaviour
{
    //Цель
    public Transform target;
 
    //Скорость слежения
    public float speed = 4f;
 
    //Маска слоев препятствий
    public LayerMask maskObstacles;
 
    private Vector3 _position;
 
	void Start ()
    {
        _position = target.InverseTransformPoint(transform.position);
	}
	
	void Update ()
    {
   var oldRotation = target.rotation;
   target.rotation = Quaternion.Euler(0, oldRotation.eulerAngles.y, 0);
   var currentPosition = target.TransformPoint(_position);
   target.rotation = oldRotation;
 
transform.position = Vector3.Lerp(transform.position, currentPosition, speed * Time.deltaTime);
var currentRotation = Quaternion.LookRotation(target.position - transform.position);
transform.rotation = Quaternion.Lerp(transform.rotation, currentRotation, speed * Time.deltaTime);
 
        RaycastHit hit;
        if (Physics.Raycast(target.position, transform.position - target.position, out hit, Vector3.Distance(transform.position, target.position), maskObstacles))
        {
            transform.position = hit.point;
            transform.LookAt(target);
        }
	}
}

Слежение камеры за персонажем с фунциями:

  • слежение камеры за персонажем
  • вращение камеры при помощи мыши
  • реагирование на препятствия
  • реагирование на приближение к игроку
using System.Collections;
using UnityEngine;
 
public class PlayerCameraController : MonoBehaviour 
{
    public Camera cam;       //камера
    public Transform target; // цель слежения
    public float speedX = 360f; //скорость камеры по X
    public float speedy = 240f; //скорость камеры по Y
    public float limitY = 40f; // лимит поворота камеры по Y
    public float minDistance = 1.5f;// мин расстояние до цели
    public float hideDistance = 2f;// макс расстояние до цели
    public LayerMask obstacles; // слои с препятствиями
    public LayerMask noPlayer; // все слои кроме игрока
    private float _maxDistance;//макс расстояние между камерой и игр
    private Vector3 _localPosition;
    private float _currentYRotation;
    private LayerMask _camOrigin;
 
    private Vector3 _position
    {
        get { return transform.position; }
        set { transform.position = value; }
    }
 
	void Start () 
	{
        _localPosition = target.InverseTransformPoint(_position);
        _maxDistance = Vector3.Distance(_position, target.position);
        _camOrigin = cam.cullingMask;
	}
 
	void LateUpdate () 
	{
        _position = target.TransformPoint(_localPosition);
        CameraRotation();
        ObstaclesReact();
        PlayerReact();
 
        _localPosition = target.InverseTransformPoint(_position);
    }
 
    void CameraRotation()
    {
        var mx = Input.GetAxis("Mouse X");
        var my = Input.GetAxis("Mouse Y");
 
        if (my != 0)
        {
            var tmp = Mathf.Clamp(_currentYRotation + my * speedy * Time.deltaTime, -limitY, limitY);
            if (tmp != _currentYRotation)
            {
                var rot = tmp - _currentYRotation;
                transform.RotateAround(target.position, transform.right, rot);
                _currentYRotation = tmp;
            }
        }
        if (mx != 0)
        {
            transform.RotateAround(target.position, Vector3.up, mx * speedX * Time.deltaTime);
        }
 
        transform.LookAt(target);
    }
 
    void ObstaclesReact()
    {
        var distance = Vector3.Distance(_position, target.position);
        RaycastHit hit;
        if (Physics.Raycast(target.position, transform.position - target.position, out hit, _maxDistance, obstacles))
        {
            _position = hit.point;
        }
        else if (distance < _maxDistance && !Physics.Raycast(_position, -transform.forward, .1f, obstacles))
        {
            _position -= transform.forward * .05f;
        }
    }
 
    void PlayerReact() //реакция на приближение игрока
    {
        var distance = Vector3.Distance(_position, target.position);
        if (distance < hideDistance)
            cam.cullingMask = noPlayer;
        else
            cam.cullingMask = _camOrigin;
    }
}

узнаем расстояние от камеры до объекта, меняем объект в зависимости от расстояния до него:


using UnityEngine;
using System.Collections;

public class LOD : MonoBehaviour {
	
	public GameObject[] Models;	// Массив моделей
	public int[] dist;			// Массив дистанций
	public GameObject Cam;		// Ссылка на объект камеры
	private int NumModel;		// Номер текущей подгружаемой модели
	public float CamDist;		// Дистанция до камеры
	
	void Start () {
		int i;
		for(i=0; i < Models.Length; i++) {
			Models[i].SetActive(false);   //деактивируем все объекты на сцене
		}
		
	}
	
	void Update () {
		CamDist = Vector3.Distance(Cam.transform.position, transform.position);
		
		int LVL = -1;                    //-1 пустой объект, 0 -плохая прорисовка, 1 - хорошая прорисовка
		int i;
		for(i=0; i < dist.Length; i++) {
			if(CamDist < dist[i]) {
				LVL = i;
				i = dist.Length;
			}
		}
		if(LVL == -1) LVL = dist.Length - 1;
		if(NumModel != LVL) SetLOD(LVL); 
	}
	
	void SetLOD (int LVL) {
		Models[LVL].SetActive(true);               //активируем новую модель
		Models[NumModel].SetActive(false);         //деактивируем старую
		NumModel = LVL;                            //присваем номеру текущей модели значение LVL
	}
}