Unity3D相机围绕物体自由旋转

写了一个相机围绕物体360°自由旋转的脚本,比较实用,分享出来给大家使用,配置如下:

Hierarchy界面

 LookPovit:为物体Auto Aircraft的中心空对象;

AroundPovit:用于相机的空对象,作为父类,主要作用是为了保持与被观察物体的位置一致,可防止Auto Aircraft出现抖动而影响相机的抖动;

相机Inspector界面:

相机代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UAroundCamera : MonoBehaviour 
{
	[Header("围绕目标")]
	public Transform aroundTargetTrans = null;
	public Transform aroundPovitTrans = null;
	[Header("纵向旋转最小/最大角度")]
	private int VMinAngle = -90;
	private int VMaxAngle = 90;
	[Header("横向旋转最小/最大角度")]
	private int HMaxAngle = -360;
	private int HMinAngle = 360;
	[Header("缩放最近/最远距离")]
	public float minDistance = 20.0f;
	public float maxDistance = 50.0f;

	[Header("旋转横向、旋转纵向、缩放速度最大/最小值")]
	public const float minSpeed = 10f;
	public const float maxSpeed = 200f;
	[Header("旋转横向、旋转纵向、缩放速度")]
	[Range(minSpeed, maxSpeed)]
	public float hSpeed = maxSpeed;
	[Range(minSpeed, maxSpeed)]
	public float vSpeed = maxSpeed;
	[Range(minSpeed, maxSpeed)]
	public float zSpeed = maxSpeed;	

	[Header("横向角度、纵向角度、缩放值")]
	private float hAngle = 0.0f;
	private float vAngle = 0.0f;
	private float zoomValue = 0.0f;

	/// <summary>
	/// 当前角度
	/// </summary>
	private Quaternion curRotation;
	/// <summary>
	/// 当前距离
	/// </summary>
	private float curDistance;
	[Tooltip("插值率")]
	public float lerpRate = 1.0f;

	[Header("相机初始位置和角度")]
	public Vector3 initPosition;
	public Vector3 initAngle;

	// Use this for initialization
	void Start () 
	{
		// 初始化
		curDistance = maxDistance;
		transform.position = initPosition;
		transform.eulerAngles = initAngle;
		vAngle = initAngle.x;
		hAngle = initAngle.y;
	}

	void OnEnable()
	{

	}

    private void Update()
    {
		// 检查旋转角度
		if (Input.GetMouseButton(1))
		{
			Cursor.visible = false;
			hAngle += Input.GetAxis("Mouse X") * (hSpeed) * Time.deltaTime;
			vAngle -= Input.GetAxis("Mouse Y") * (vSpeed) * Time.deltaTime;
		}
		if (Input.GetMouseButtonUp(1))
		{
			Cursor.visible = true;
		}
		vAngle = ClampAngle(vAngle, VMinAngle, VMaxAngle);
		hAngle = ClampAngle(hAngle, HMaxAngle, HMinAngle);

		// 检查缩放
		zoomValue = Input.GetAxis("Mouse ScrollWheel") * zSpeed * Time.deltaTime;		
	}
	private void FixedUpdate()
	{
		// 更新围绕中心的位置为目标的中心位置
		aroundPovitTrans.position = aroundTargetTrans.position;		
	}

	// Update is called once per frame
	private void LateUpdate()
    {
		// 旋转
		curRotation = Quaternion.Euler(vAngle, hAngle, 0);
		Quaternion rotation = Quaternion.Lerp(transform.rotation, curRotation, Time.deltaTime * lerpRate);
		transform.rotation = rotation;

		// 缩放
		float distance = curDistance - zoomValue * Mathf.Abs(curDistance); // 当前
		distance = Mathf.Clamp(distance, minDistance, maxDistance);
        curDistance = Mathf.Lerp(curDistance, distance, Time.deltaTime * lerpRate);

		// 更新相机的位置
		Vector3 position = aroundPovitTrans.position - (rotation * Vector3.forward * curDistance);
        transform.position = position;

		// 根据当前距离中心的位置来调整缩放和旋转速率
		float scaleValue = GetDistanceScale(curDistance);
		hSpeed = scaleValue * (maxSpeed - minSpeed) + minSpeed;
		hSpeed = Mathf.Clamp(hSpeed, minSpeed, maxSpeed);

		vSpeed = scaleValue * (maxSpeed - minSpeed) + minSpeed;
		hSpeed = Mathf.Clamp(vSpeed, minSpeed, maxSpeed);

		zSpeed = scaleValue * (maxSpeed - minSpeed) + minSpeed;
		hSpeed = Mathf.Clamp(zSpeed, minSpeed, maxSpeed);
	}
	/// <summary>
	/// 界面编辑
	/// </summary>
    private void OnValidate()
    {
		transform.position = initPosition;
		transform.eulerAngles = initAngle;
		vAngle = initAngle.x;
		hAngle = initAngle.y;
	}
    /// <summary>
    /// 限制角度
    /// </summary>
    /// <param name="angle"></param>
    /// <param name="min"></param>
    /// <param name="max"></param>
    /// <returns></returns>
    private static float ClampAngle(float angle, float min, float max)
	{
		if (Mathf.Abs(angle) > 360)
		{
			angle = 0;
		}
		return Mathf.Clamp (angle, min, max);
	}
	/// <summary>
	/// 获取当前的距离比率值
	/// </summary>
	/// <param name="dis">当前距离</param>
	/// <returns></returns>
	private float GetDistanceScale(float dis)
	{
		return (dis - minDistance) / (maxDistance - minDistance);
	}
}

 温馨提示:该相机脚本实用与飞行器的相机,飞行器在飞行过程中,可360°观察状态^o^!

猜你喜欢

转载自blog.csdn.net/weixin_39638287/article/details/128373707