首先,在场景中导入人物模型,将其放在世界坐标的原点处。 创建一个名为CameraBase的空物体,把该物体移动至人物模型的上半身的中央处,世界坐标为(0, 1.35, 0),这个物体相当于是摄像机的基准点。随后我把摄像机设为CameraBase的子物体,把摄像机拖到人物模型的后方,局部坐标为(0, 0, -2)。然后再创建一个名为CameraFollow的空物体,设为人物模型的子物体,局部坐标为(0, 1.35, 0)。
把以下脚本挂载到CameraBase上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour {
private float CameraMoveSpeed = 120.0f;
public GameObject CameraFollowObj;
Vector3 FollowPOS;
public float ClampAngle = 80.0f;
public float InputSensitivity = 150.0f;
public GameObject CameraObj;
public GameObject PlayerObj;
public float camDistanceXtoPlayer;
public float camDistanceYtoPlayer;
public float camDistanceZtoPlayer;
public float mouseX;
public float mouseY;
public float finalInputX;
public float finalInputZ;
public float smoothX;
public float smoothY;
private float rotY = 0.0f;
private float rotX = 0.0f;
// Use this for initialization
void Start () {
Vector3 rot = transform.localRotation.eulerAngles;
rotY = rot.y;
rotX = rot.x;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
// Update is called once per frame
void Update () {
float inputX = Input.GetAxis("RightStickHorizontal");
float inputZ = Input.GetAxis("RightStickVertical");
mouseX = Input.GetAxis("Mouse X");
mouseY = Input.GetAxis("Mouse Y");
finalInputX = inputX + mouseX;
finalInputZ = inputZ + mouseY;
rotY += finalInputX * InputSensitivity * Time.deltaTime;
rotX += finalInputZ * InputSensitivity * Time.deltaTime;
rotX = Mathf.Clamp(rotX, -ClampAngle, ClampAngle);
Quaternion localRotation = Quaternion.Euler(rotX, rotY, 0.0f);
transform.rotation = localRotation;
}
void LateUpdate()
{
CameraUpdater();
}
void CameraUpdater()
{
Transform target = CameraFollowObj.transform;
float step = CameraMoveSpeed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}
将以下脚本挂载到摄像机上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraCollision : MonoBehaviour {
public float minDistance = 0.2f;
public float maxDistance = 2.0f;
public float smooth = 5.0f;
Vector3 dollyDir;
public Vector3 dollyDirAdjusted;
public float distance;
void Awake()
{
dollyDir = transform.localPosition.normalized;
distance = transform.localPosition.magnitude;
}
// Update is called once per frame
void Update () {
Vector3 desiredCameraPos = transform.parent.TransformPoint(dollyDir * maxDistance);
RaycastHit hit;
if (Physics.Linecast(transform.parent.position, desiredCameraPos, out hit))
{
distance = Mathf.Clamp(hit.distance * 0.85f, minDistance, maxDistance);
}
else
{
distance = maxDistance;
}
transform.localPosition = Vector3.Lerp(transform.localPosition, dollyDir * distance, Time.deltaTime * smooth);
}
}