Unity第三人称摄像机控制方法

这里需

要注意的主要是作为子物体如何实现有延迟效果的追随父物体朝向的办法。

using UnityEngine;

public class ViewCtrlThirdPerson : MonoBehaviour
{
	public Transform trRotH;
	public Transform trRotV;
	public Transform trZoom;

	Vector3 rotVerticalMin = new Vector3(85, 0, 0);
	Vector3 rotVerticalMax = new Vector3(-30, 0, 0);
	Quaternion rotVMin;
	Quaternion rotVMax;

	float rotSpeedH = 0.5f;
	float rotSpeedV = 0.005f;
	float process = 0;

	float zoomMin = 1;
	float zoomMax = 15;
	float zoomSpeed = 2;

	Vector3 rotHPosPre;

	void Start()
	{
		rotVMin = Quaternion.Euler(rotVerticalMin);
		rotVMax = Quaternion.Euler(rotVerticalMax);
		process = (trRotV.localEulerAngles.x - rotVerticalMin.x) / (rotVerticalMax.x - rotVerticalMin.x);
		//
		MouseOperation.instance.onDrag += OnDrag;
		MouseOperation.instance.onRelease += OnRelease;
		MouseOperation.instance.onZoom += OnZoom;
		//
		rotHPosPre = trRotH.position;
	}

	void Update()
	{
		CheckCol();
	}

	Quaternion rotWorldH;
	void OnDrag(Vector3 deltaPos)
	{
		trRotH.Rotate(0, deltaPos.x * rotSpeedH, 0);
		rotWorldH = trRotH.rotation;
		//
		process += deltaPos.y * rotSpeedV;
		process = Mathf.Clamp01(process);
		trRotV.localRotation = Quaternion.Lerp(rotVMin, rotVMax, process);
		//
		rotHPosPre = trRotH.position;
	}

	void OnRelease(Vector3 mousePositon)
	{
		float m = (rotHPosPre - trRotH.position).magnitude;
		if (!Mathf.Approximately(m, 0))
		{
			rotWorldH = Quaternion.Lerp(rotWorldH, trRotH.parent.rotation, Time.deltaTime * 3);
			trRotH.rotation = rotWorldH;
		}
		rotHPosPre = trRotH.position;
	}

	float distTarget = 3.68f;
	void OnZoom(float scroll)
	{
		distTarget -= scroll * zoomSpeed;
		distTarget = Mathf.Clamp(distTarget, zoomMin, zoomMax);
	}

	void CheckCol()
	{
		Ray ray = new Ray(trRotV.position, -trRotV.forward);
		RaycastHit hit;
		if (Physics.Raycast(ray, out hit, distTarget, 1 << LayerMask.NameToLayer("Default") | 1 << LayerMask.NameToLayer("Picked")))
		{
			Vector3 pos = trZoom.localPosition;
			pos.z = -hit.distance;
			pos.z = Mathf.Clamp(pos.z, -zoomMax, -zoomMin);
			trZoom.localPosition = pos;
		}
		else
		{
			Vector3 pos = trZoom.localPosition;
			pos.z = Mathf.Lerp(pos.z, -distTarget, Time.deltaTime * 3);
			pos.z = Mathf.Clamp(pos.z, -zoomMax, -zoomMin);
			trZoom.localPosition = pos;
		}
	}
}

 用于产生鼠标事件的代码参考如下:

using UnityEngine;
using UnityEngine.Events;

public class MouseOperation : MonoBehaviour
{
	static public MouseOperation instance;

	void Awake()
	{
		instance = this;
	}

	bool isDrag = false;
	bool clickEnabled = false;
	Vector3 posMouseDown;

	public UnityAction onClick;
	public UnityAction onDrag; 
	public UnityAction onRelease;
	public UnityAction onZoom;

	Vector3 posMousePre;

	void Update()
	{
		if (Input.GetMouseButtonDown(0))
		{
			if (!UITool.instance.pointerOnUI)
			{
				isDrag = true;
				clickEnabled = true;
				posMouseDown = Input.mousePosition;
				posMousePre = posMouseDown;
			}
		}


		if (Input.GetMouseButtonUp(0))
		{
			isDrag = false;
			if (clickEnabled)
			{
				//产生一个点击事件
				onClick?.Invoke(Input.mousePosition);
			}
		}


		if (isDrag)
		{
			if ((Input.mousePosition - posMouseDown).sqrMagnitude > 9)
			{
				clickEnabled = false;
			}

			if (!clickEnabled)
			{
				//产生一个拖拽事件
				Vector3 deltaPos = Input.mousePosition - posMousePre;
				posMousePre = Input.mousePosition;

				onDrag?.Invoke(deltaPos);
			}
		}
		else
		{
			onRelease?.Invoke(Input.mousePosition);
		}

		float scroll = Input.GetAxis("Mouse ScrollWheel");
		if(!Mathf.Approximately(scroll,0))
		{
			if (!UITool.instance.pointerOnUI)
			{
				onZoom?.Invoke(scroll);
			}
		}
	}
}

你可能感兴趣的:(Unity,Unity)