赞
踩
本章代码基于前两章。
1. 我们新建CameraController脚本,将其挂载到Camera上
2. 在角色Player下新建一个空物体,命名为cameraTargetPoint,并将该物体挂载至CameraController脚本中【注意代码中的这行:public Transform cameraTargetPoint;】,将该空物体放在人物头部附近位置
3.将PlayerController脚本绑定至CameraController中【public PlayerController playerController;】
4.本章代码的实现原理是让摄像机对准空物件,并保持一定距离
5. 具体代码如下
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraController : MonoBehaviour { private static float lower_upper_bound = 60f; public Transform cameraTargetPoint; public float cameraDistance = 5.0f; public Vector2 verticalRange = new Vector2(-lower_upper_bound, lower_upper_bound); public float cameraSensitivity = 120f; private Transform verticalObj; private Transform horizontalObj; private float horizontalValue; private float verticalValue; public PlayerController playerController; // Start is called before the first frame update void Start() { horizontalObj = new GameObject("Camera Horizontal").transform; horizontalObj.SetParent(cameraTargetPoint); horizontalObj.localPosition = Vector3.zero; horizontalObj.localRotation = Quaternion.identity; verticalObj = new GameObject("Camera Vertical").transform; verticalObj.SetParent(horizontalObj); verticalObj.localPosition = Vector3.zero; verticalObj.localRotation = Quaternion.identity; transform.SetParent(verticalObj); transform.localPosition = new Vector3(0,0,-cameraDistance); transform.localRotation = Quaternion.identity; } // Update is called once per frame void Update() { cameraMoving(); DoNotTouchTheGround(); } private void cameraMoving() { horizontalValue += Input.GetAxis("Mouse X") * Time.deltaTime * cameraSensitivity; horizontalObj.localRotation = Quaternion.Euler(new Vector3(0, horizontalValue, 0)); verticalValue += Input.GetAxis("Mouse Y") * Time.deltaTime * cameraSensitivity; verticalValue = Mathf.Clamp(verticalValue, verticalRange.x, verticalRange.y); verticalObj.localRotation = Quaternion.Euler(new Vector3(-verticalValue, 0, 0)); } private void DoNotTouchTheGround() // 摄像机与角色点中间有物体时,让摄像机处于物体前,避免遮挡 { Vector3 distanceVec = transform.position - cameraTargetPoint.position; float distance = distanceVec.magnitude; RaycastHit hit; if(Physics.Raycast(cameraTargetPoint.position,distanceVec, out hit,distance)) { if(hit.transform.tag != "Player") { transform.position = hit.point; } else { transform.localPosition = Vector3.Lerp(transform.localPosition, new Vector3(0, 0, -distance), 0.3f); } } else { transform.localPosition = Vector3.Lerp(transform.localPosition, new Vector3(0, 0, -distance), 0.3f); } } }
Tips:以上代码中,DoNotTouchTheGround()方法不是必须的,该方法是用于限制当摄像机与角色之间有障碍物时,把摄像机放在障碍物前方以避免视觉阻碍,可以看情况添加。
至此,我们可以实现摄像机跟随角色移动,并且鼠标能操控摄像机绕着角色转动,但仍有一个问题:当摄像机位于人物前方时,人物前进方向仍是我们的后方,这是由于参考坐标系的缘故,具体修复如下:
1. 在PlayerController脚本中,添加
public Transform cameraTargetPoint;
在Move方法中添加【moveingVec = cameraTargetPoint.TransformDirection(moveingVec);】:
private void Move()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 moveingVec = new Vector3(horizontalInput, 0f, verticalInput) * Time.deltaTime * speed;
moveingVec = cameraTargetPoint.TransformDirection(moveingVec);
transform.Translate(moveingVec);
}
2. 在CameraController脚本中的cameraMoving()方法中添加下句:
playerController.cameraTargetPoint = horizontalObj;
于是即可实现摄像头跟随鼠标,并围绕角色运动,并且角色运动方向【仅仅是方向,如果要人物转向,则还需其他修改,本系列其他章节会有涉及】可以自适应为当前摄像头的前方
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。