Простое следование за объектом без поворотов камеры
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
}
}