一、固定相机跟随,这种相机有一个参考对象,它会保持与该参考对象固定的位置,跟随改参考对象发生移动
public class CameraFlow : MonoBehaviour
{
public Transform target;
private Vector3 offset;
void Start()
{
//设置相对偏移
offset = target.position - this.transform.position;
}
void FixedUpdate()
{
this.transform.position = target.position - offset;
}
}
二、固定相机跟随,带有角度旋转。这一种相机跟随是对第一种相机跟随的改进,在原有基础上面,添加了跟随角度的控制
public class CameriaTrack : MonoBehaviour
{
private Vector3 offset = new Vector3(0,5,4);//相机相对于玩家的位置
private Transform target;
private Vector3 pos;
public float speed = 2;
void Start ()
{
target = GameObject.FindGameObjectWithTag("Player").transform;
}
void FixedUpdate()
{
pos = target.position + offset;
this.transform.position = Vector3.Lerp(this.transform.position, pos, speed*Time.deltaTime);//调整相机与玩家之间的距离
Quaternion angel = Quaternion.LookRotation(target.position - this.transform.position);//获取旋转角度
this.transform.rotation = Quaternion.Slerp(this.transform.rotation, angel, speed * Time.deltaTime);
}
}
三、第三人称相机,这种相机跟随,是第三人称角度看向对象的,也就是一直看向对象的后面,如一直显示玩家的后背
public Transform target;
public float distanceUp = 10f;//相机与目标的竖直高度参数
public float distanceAway = 10f;//相机与目标的水平距离参数
public float smooth = 2f;//位置平滑移动插值参数值
public float camDepthSmooth = 20f;
void Update()
{
// 鼠标轴控制相机的远近
if ((Input.mouseScrollDelta.y < 0 && Camera.main.fieldOfView >= 3) || Input.mouseScrollDelta.y > 0 && Camera.main.fieldOfView <= 80)
{
Camera.main.fieldOfView += Input.mouseScrollDelta.y * camDepthSmooth * Time.deltaTime;
}
}
void LateUpdate()
{
//计算出相机的位置
Vector3 disPos = target.position + Vector3.up * distanceUp - target.forward * distanceAway;
transform.position = Vector3.Lerp(transform.position, disPos, Time.deltaTime * smooth);
//相机的角度
transform.LookAt(target.position);
}
四、相机跟随,鼠标控制移动和缩放。相机与观察对象保持一定距离,可以通过鼠标进行上下左右旋转,通过鼠标滚轮进行放大和缩小操作
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class target_control : MonoBehaviour {
public Transform _target;
public float distance = 50.0f;
public float xSpeed = 250.0f;
public float ySpeed = 120.0f;
public int yMinLimit = -20;
public int yMaxLimit = 80;
private bool orbit = false;
private bool pan = false;
private bool zoom = false;
private float zoomValue = 0;
public float orbitDampX = 0.0f;
public float orbitDampY = 0.0f;
float panDampX = 0.0f;
float panDampY = 0.0f;
public float zoomDamp = 0.0f;
public float dampingTime = 0.0f;
public float x = 180.0f;
public float y = 0.0f;
public int planFactor = 5;
public float zoomFactor = 2.0f;
public Vector2 distLimit;
public static Quaternion _rotation;
public static Vector3 _position;
public static target_control _target_control;
public float _z_distance;
private Vector3 angles;
private Vector2 oldPosition1;
private Vector2 oldPosition2;
public float _target_distance = 5;
private float target_x;
private float target_y;
private Vector3 _target_pos = Vector3.zero;
public bool change_distance()
{
distance = Mathf.Lerp(distance, _target_distance, 0.04f);
Debug.Log(distance + "/" + _target_distance);
updateCamera();
if (Mathf.Abs(distance - _target_distance) < 0.01f)
return false;
return true;
}
public bool change_distance(float _dis)
{
distance = Mathf.Lerp(distance, _dis, 0.004f);
updateCamera();
if (Mathf.Abs(distance - _dis) < 0.01f)
return false;
return true;
}
void Start()
{
_target_distance = distance;
_z_distance = distance;
angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
// Make the rigid body not change rotation
if (GetComponent())
GetComponent().freezeRotation = true;
}
// Update is called once per frame
void LateUpdate () {
if (EventSystem.current.IsPointerOverGameObject()||_target ==null)
{
return;
}
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
orbit = true;
}
else
{
orbit = false;
}
}
else
{
orbit = false;
}
if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
if (isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
zoomValue = 0.1f;
zoom = true;
}
else
{
zoomValue = -0.1f;
zoom = true;
}
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
else
{
zoom = false;
}
}
else
{
zoom = false;
}
}
else if (Application.platform == RuntimePlatform.Android)
{
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
orbit = true;
}
else
{
orbit = false;
}
}
else
{
orbit = false;
}
if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
if (isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
zoomValue = 0.1f;
zoom = true;
}
else
{
zoomValue = -0.1f;
zoom = true;
}
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
else
{
zoom = false;
}
}
else
{
zoom = false;
}
}
else
{
if (Input.GetMouseButton(1))
{
orbit = true;
}
else
{
orbit = false;
}
if (Input.GetAxisRaw("Mouse ScrollWheel") != null)
{
zoomValue = Input.GetAxisRaw("Mouse ScrollWheel");
zoom = true;
}
else
{
zoom = false;
}
}
if (orbit)
{
orbitDampX = Mathf.Lerp(orbitDampX, Input.GetAxis("Mouse X"), dampingTime * Time.deltaTime);
orbitDampY = Mathf.Lerp(orbitDampY, Input.GetAxis("Mouse Y"), dampingTime * Time.deltaTime);
}
else
{
orbitDampX = Mathf.Lerp(orbitDampX, 0, dampingTime * Time.deltaTime);
orbitDampY = Mathf.Lerp(orbitDampY, 0, dampingTime * Time.deltaTime);
}
if (zoom)
{
zoomDamp = Mathf.Lerp(zoomDamp, zoomValue, dampingTime * Time.deltaTime);
}
else
{
zoomDamp = Mathf.Lerp(zoomDamp, 0, dampingTime * Time.deltaTime);
}
if (!checkLerp(orbitDampX, 0) || !checkLerp(orbitDampY, 0))
{
doOrbit();
}
if (!checkLerp(zoomDamp, 0))
{
doZoom();
}
}
bool isEnlarge(Vector2 oP1,Vector2 oP2 , Vector2 nP1, Vector2 nP2 )
{
var leng1 =Mathf.Sqrt((oP1.x-oP2.x)*(oP1.x-oP2.x)+(oP1.y-oP2.y)*(oP1.y-oP2.y));
var leng2 =Mathf.Sqrt((nP1.x-nP2.x)*(nP1.x-nP2.x)+(nP1.y-nP2.y)*(nP1.y-nP2.y));
if(leng1
//big
return true;
}else
{
//small
return false;
}
}
bool checkLerp(float a,float b)
{
if (Mathf.Approximately(a, b))
{
return true;
}
return false;
}
void doOrbit()
{
if (_target)
{
x += orbitDampX * xSpeed * 0.02f;
y -= orbitDampY * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
updateCamera();
}
}
void doZoom()
{
distance -= zoomDamp * zoomFactor;
distance = Mathf.Clamp(distance, -distLimit.x, distLimit.y);
updateCamera();
}
void updateCamera()
{
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * new Vector3(0.0f, 0.0f, -distance) + _target.position;
transform.rotation = rotation;
transform.position = position;
}
static float ClampAngle (float angle,float min,float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}



