脚本效果:
1. 跟随目标物体
2. 通过滚轮调整距离,右键或Ctrl+左键旋转角度
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraControl : MonoBehaviour {
public Transform pivot; //摄像机跟随的目标物体
public Vector3 pivotOffset; //摄像机对于目标物体的初始偏移
public Transform target; // 后续用来检测遮挡
public float distance = 10.0f; //摄像机与角色的初始距离
public float minDistance = 3f; //摄像机最近距离
public float maxDistance = 15f; //摄像机最远距离
public float zoomSpeed = 1f; //摄像机拉近速度
public float xSpeed = 100.0f; //摄像机在水平方向的旋转速度
public float ySpeed = 120.0f; //摄像机在垂直方向的旋转速度
public bool allowYTilt = true; //是否允许摄像机在垂直方向的旋转
public float yMinLimit = 10f; //摄像机在垂直方向的旋转角度限制
public float yMaxLimit = 80f; //摄像机在垂直方向的旋转角度限制,90即头顶俯视视角
private float x = 0.0f;
private float y = 0.0f;
private float targetX = 0f;
private float targetY = 0f;
private float targetDistance = 0f;
private float xVelocity = 1f;
private float yVelocity = 1f;
private float zoomVelocity = 1f;
void Start()
{
var angles = transform.eulerAngles;
targetX = x = angles.x;
targetY = y = ClampAngle(angles.y, yMinLimit, yMaxLimit);
targetDistance = distance;
}
void LateUpdate()
{
if (pivot)
{
float scroll = Input.GetAxis("Mouse ScrollWheel");
if (scroll > 0.0f) targetDistance -= zoomSpeed;
else if (scroll < 0.0f) targetDistance += zoomSpeed;
targetDistance = Mathf.Clamp(targetDistance, minDistance, maxDistance);
// 右键或Ctrl+左键
if (Input.GetMouseButton(1) || (Input.GetMouseButton(0) && (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))))
{
targetX += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
if (allowYTilt)
{
targetY -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
targetY = ClampAngle(targetY, yMinLimit, yMaxLimit);
}
}
x = Mathf.SmoothDampAngle(x, targetX, ref xVelocity, 0.3f);
if (allowYTilt) y = Mathf.SmoothDampAngle(y, targetY, ref yVelocity, 0.3f);
else y = targetY;
Quaternion rotation = Quaternion.Euler(y, x, 0);
distance = Mathf.SmoothDamp(distance, targetDistance, ref zoomVelocity, 0.5f);
Vector3 position = rotation * new Vector3(0.0f, 0.0f, -distance) + pivot.position + pivotOffset;
transform.rotation = rotation;
transform.position = position;
}
}
private float ClampAngle(float angle, float min, float max)
{
if (angle < -360) angle += 360;
if (angle > 360) angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}