用法:先在你的Player里新建一个空的Object重命名为CameraTarget(你起什么名字都行),然后将把脚本挂载到主摄像机上,将你新建的 CameraTarget 拖动到脚本的Target属性,运行你就可以看到效果了
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class cc : MonoBehaviour
{
public bool HideAndShowCursor = true;
public bool LockRotationWhenRightClick = false;
public bool UseBlurEffect = true;
public bool UseFogEffect = true;
public Transform target;//要控制的对象
public float targetHeight = 1.0f;
public float distance = 5.0f;
public float maxDistance = 20;
public float minDistance = 0.6f;
public float xSpeed = 250.0f;
public float ySpeed = 120.0f;
public int yMinLimit = -80;
public int yMaxLimit = 80;
public int zoomRate = 40;
public float rotationDampening = 3.0f;
public float zoomDampening = 10.0f;
private float x = 0.0f;
private float y = 0.0f;
private float currentDistance;
private float desiredDistance;
private float correctedDistance;
private bool grounded = false;
void Start()
{
Screen.lockCursor = true;
Vector3 angles = transform.eulerAngles;
x = angles.x;
y = angles.y;
currentDistance = distance;
desiredDistance = distance;
correctedDistance = distance - 0.2f;
// Make the rigid body not change rotation
if (GetComponent<Rigidbody>())
GetComponent<Rigidbody>().freezeRotation = true;
}
void LateUpdate()
{
// Don't do anything if target is not defined
if (!target)
{
GameObject go = GameObject.Find("Player");
target = go.transform;
transform.LookAt(target);
return;
}
// If either mouse buttons are down, let the mouse govern camera position
if (LockRotationWhenRightClick == false)
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
}
if (Input.GetMouseButton(0))
{
if (LockRotationWhenRightClick == false)
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
}
}
y = ClampAngle(y, yMinLimit, yMaxLimit);
// set camera rotation
Quaternion rotation = Quaternion.Euler(y, x, 0);
// calculate the desired distance
desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
correctedDistance = desiredDistance;
// calculate desired camera position
Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance + new Vector3(0, -targetHeight, 0));
// check for collision using the true target's desired registration point as set by user using height
RaycastHit collisionHit;
Vector3 trueTargetPosition = new Vector3(target.position.x, target.position.y + targetHeight, target.position.z);
// if there was a collision, correct the camera position and calculate the corrected distance
bool isCorrected = false;
if (Physics.Linecast(trueTargetPosition, position, out collisionHit))
{
if (collisionHit.transform.name != target.name)
{
position = collisionHit.point;
correctedDistance = Vector3.Distance(trueTargetPosition, position);
isCorrected = true;
}
}
// For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
// recalculate position based on the new currentDistance
position = target.position - (rotation * Vector3.forward * currentDistance + new Vector3(0, -targetHeight - 0.05f, 0));
transform.rotation = rotation;
transform.position = position;
}
private static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}