(关于其他几种角色移动的控制在我之前的博客有写到)
首先我们需要先理解一下第三人称相机控制的原理:
我们要实现的效果就是:获取鼠标的移动输入,转化成角色以及相机的旋转,通过鼠标输入Input.GetAxis(“Mouse X”)让相机围绕目标角色旋转(transform.RotateAround)角色通过相机改变的角度改变自身方向(Quaternion.Euler)。
那么先介绍一下transform.RotateAround(目标物体位置,轴,旋转角度)方法,这个方法是让自身围绕目标物体旋转,所以我们用
float inputX = Input.GetAxis("Mouse X");
float inputY = Input.GetAxis("Mouse Y");
transform.RotateAround(CameraPivot.transform.position, Vector3.up, rotateSpeed * inputX);
transform.RotateAround(CameraPivot.transform.position, TargetBody.transform.right, -rotateSpeed * inputY);
CameraPivot是相机的焦点物体(最好是设置角色的头部);
然后 我们将相机的这个旋转角度记录下来(transform.localEulerAngles),并且用Quaternion.Euler改变角色的面向;
Quaternion TargetBodyCurrentRotation = TargetBody.transform.rotation;
TargetBody.transform.rotation = Quaternion.Lerp(TargetBodyCurrentRotation, Quaternion.Euler(new Vector3(TargetBody.transform.localEulerAngles.x, transform.localEulerAngles.y, TargetBody.transform.localEulerAngles.z)), TargetBodyRotateLerp);
为了方便理解,给大家画一个示意图:
下面给大家简单操作一下!
还是先创建一个新的场景,里面添加一个plane和一个cube并且调整一下相机位置:
然后上代码!把代码加载摄像机上:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cameraFollow : MonoBehaviour {
[Header("相机距离")]
public float freeDistance = 2;
[Header("相机最近距离")]
public float minDistance = 0.5f;
[Header("相机最远距离")]
public float maxDistance = 3;
[Header("是否可控制相机距离(鼠标中键)")]
public bool canControlDistance=true;
[Header("更改相机距离的速度")]
public float distanceSpeed = 1;
[Header("视角灵敏度")]
public float rotateSpeed = 1;
[Header("物体转向插值(灵敏度,取值为0到1)")]
public float TargetBodyRotateLerp = 0.3f;
[Header("需要转向的物体")]
public GameObject TargetBody;//此脚本能操作转向的物体
[Header("相机焦点物体")]
public GameObject CameraPivot;//相机焦点物体
[Header("是否可控制物体转向")]
public bool CanControlDirection = true;
private Vector3 offset;//偏移
// Use this for initialization
void Start () {
//获取目标与相机之间的差值
offset = transform.position - CameraPivot.transform.position;
}
void FreeCamera()
{
offset = offset.normalized * freeDistance;
transform.position = Vector3.Lerp(transform.position,CameraPivot.transform.position + offset,1f) ;//更新位置
if (CanControlDirection)//控制角色方向开关
{
Quaternion TargetBodyCurrentRotation = TargetBody.transform.rotation;
TargetBody.transform.rotation = Quaternion.Lerp(TargetBodyCurrentRotation, Quaternion.Euler(new Vector3(TargetBody.transform.localEulerAngles.x, transform.localEulerAngles.y, TargetBody.transform.localEulerAngles.z)), TargetBodyRotateLerp);
}
//限制相机距离
if(canControlDistance)//控制距离开关
{
freeDistance -= Input.GetAxis("Mouse ScrollWheel") * distanceSpeed;
}
freeDistance = Mathf.Clamp(freeDistance, minDistance, maxDistance);
//保证相机的注视
transform.LookAt(CameraPivot.transform.position);
//控制相机随鼠标的旋转
float inputY = Input.GetAxis("Mouse Y");
float inputX = Input.GetAxis("Mouse X");
transform.RotateAround(CameraPivot.transform.position, Vector3.up, rotateSpeed * inputX);
transform.RotateAround(CameraPivot.transform.position, TargetBody.transform.right, -rotateSpeed * inputY);
//旋转之后以上方向发生了变化,需要更新方向向量
offset = transform.position - CameraPivot.transform.position;
offset = offset.normalized * freeDistance;
transform.position = CameraPivot.transform.position + offset;
}
// Update is called once per frame
void FixedUpdate () {
FreeCamera();
}
private void Update()
{
}
}
稍微配置一下参数:
之后 就有相机的初步效果了:
给cube添加上移动的代码 就完成啦!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Control : MonoBehaviour {
float ver = 0;
float hor = 0;
public float turnspeed = 10f;
public float speed = 6f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
hor = Input.GetAxis ("Horizontal");
ver = Input.GetAxis ("Vertical");
}
void move (float hor, float ver) {
transform.Translate (hor * speed * Time.deltaTime, 0, ver * speed * Time.deltaTime);
}
void FixedUpdate () {
if (hor != 0 || ver != 0) {
//转身
move (hor, ver);
}
}
}
完成!