
如上节所说,这节将会解决旋转视角同时旋转模型的问题,还有制造出一种相机追赶模型的效果。
第一个问题不难,只需一个临时变量就能迎刃而解,在每一帧旋转相机前(即Update()每刷新一次),我们可以用这个临时变量来暂存当前模型的欧拉角,在相机旋转完后,再把暂存的欧拉角再返还给当前模型。每一帧都如此,那么整个旋转相机的时间段里,模型的欧拉角都不会被改变。当然我们首先要获取模型:
private GameObject model;
void Awake () {
...
model = playerHandle.GetComponent<ActorController>().model; //获取模型
...
}
void Update () {
Vector3 tempModelEuler = model.transform.eulerAngles;
playerHandle.transform.Rotate (Vector3.up, pi.CRight * horizontalSpeed * Time.deltaTime);
tempEuler = Mathf.Clamp (tempEuler, -20, 30);
tempEuler += pi.CUp * -verticalSpeed * Time.deltaTime;
cameraHandle.transform.localEulerAngles = new Vector3 (tempEuler, 0, 0);
model.transform.eulerAngles = tempModelEuler;
}
现在操纵相机,角色不为所动:

一般的Arpg的相机都会有追赶的效果,就是人物先动,相机紧跟其后的感觉,我们来试试看怎么实现这种效果。
我们可以create a empty来代替当前相机的层级关系,我们把这个empty命名为cameraPos,而Camera在层级关系的哪里都可以,因为我们想要的是想用cameraPos实现刚才Camera所做的,而Camera要做的仅仅是获取cameraPos的位置然后平滑移动过去就行了。

然后把我们刚才在Camera上写好的组件(CameraController.cs)给移除,放在cameraPos上:


现在我们要做的是Camera去追赶CameraPos,我想这个要在cameraPos的CameraContorller.cs里完成,所以要在里面新增点东西。
首先就要获得Camera这个GameObject。
private GameObject _camera;
void Awake () {
...
_camera = Camera.main.gameObject; //获取主要摄像头(Tag为MainCamera)
...
}
要注意的是,要把你想要给_camera
的相机的Tag标明为MainCamera,不然_camera
会获取不到。

其次在每次(每一帧)完成对cameraPos的旋转后,Camera都要获得cameraPos的位置和欧拉角并且跟上它。
private Vector3 cameraDampVelocity;
public float cameraDampValue = 0.3f;
void Update () {
Vector3 tempModelEuler = model.transform.eulerAngles;
playerHandle.transform.Rotate (Vector3.up, pi.CRight * horizontalSpeed * Time.deltaTime);
//cameraHandle.transform.Rotate (Vector3.right, pi.CUp * verticalSpeed * Time.deltaTime);
tempEuler = Mathf.Clamp (tempEuler, -20, 30);
tempEuler += pi.CUp * -verticalSpeed * Time.deltaTime;
cameraHandle.transform.localEulerAngles = new Vector3 (tempEuler, 0, 0);
model.transform.eulerAngles = tempModelEuler;
//camera.transform.position = transform.position; //对position做平滑处理
camera.transform.position = Vector3.SmoothDamp(camera.transform.position, transform.position,ref cameraDampVelocity,cameraDampValue);
camera.transform.eulerAngles = transform.eulerAngles;
}
另外,我对Camera追赶cameraPos位置这个过程做了平滑处理Vector3.SmoothDamp()
。cameraDampValue
表示达到目标值大约需要的时间,我设0.3只是为了让效果明显一点(如图),其实0.1效果的最好的。

网友评论