配合插件LeanTouch插件,相机旋转、缩放、平移(惯性)等操作
using UnityEngine;
using Lean.Touch;
using System.Collections.Generic;
public class CameraOperation : MonoBehaviour
{
public enum CameraOperationType
{
Move,
Zoom,
Rotate,
None
}
public float Sensitivity = 1;
public float Zoom = 50;
public float MinZoom = 30;
public float MaxZoom = 90;
public float MoveSpeed = 0.8f;
public float RotateSpeed = 1f;
public float ZoomSpeed = 1f;
private Camera mCamera;
private CameraOperationType cameraOperationType = CameraOperationType.None;
float fMoveDeltaX = 0f;
float fMoveDeltaZ = 0f;
//惯性方向
Vector3 inertiaMoveDir = Vector3.zero;
//惯性速度
float inertiaMoveSpeed = 0f;
float velocity = 0f;
private void Awake()
{
mCamera = GetComponent<Camera>();
}
private void Start()
{
mCamera.fieldOfView = Zoom;
}
private void OnEnable()
{
//Touch_Manager.Instance.AddFingerUpEvent(OnFingerUpEvent);
Touch_Manager.Instance.AddDoubleFingerStartEvent(OnDoubleFingerStartEvent);
Touch_Manager.Instance.AddDoubleFingerEndEvent(OnDoubleFingerEndEvent);
Touch_Manager.Instance.AddOneFingerStartEvent(OnOneFingerStartEvent);
Touch_Manager.Instance.AddOneFingerEndEvent(OnOneFingerEndEvent);
}
private void OnDisable()
{
if (Touch_Manager.IsSingletonObjectDestroy == false)
{
Touch_Manager.Instance.RemoveDoubleFingerStartEvent(OnDoubleFingerStartEvent);
Touch_Manager.Instance.RemoveDoubleFingerEndEvent(OnDoubleFingerEndEvent);
Touch_Manager.Instance.RemoveOneFingerStartEvent(OnOneFingerStartEvent);
Touch_Manager.Instance.RemoveOneFingerEndEvent(OnOneFingerEndEvent);
}
}
//双指开始
void OnDoubleFingerStartEvent(List<LeanFinger> fingers)
{
cameraOperationType = CameraOperationType.None;
}
//双指结束:惯性?
void OnDoubleFingerEndEvent(List<LeanFinger> fingers)
{
//cameraDoubleOperationType = CameraOperationType.None;
}
//单指开始
void OnOneFingerStartEvent(LeanFinger finger)
{
cameraOperationType = CameraOperationType.None;
}
//单指结束:开始惯性移动
void OnOneFingerEndEvent(LeanFinger finger)
{
Vector2 delta = finger.GetSnapshotScaledDelta(CameraVarible.InertiaEndTime);
float moveTime = finger.Age > CameraVarible.InertiaEndTime ? CameraVarible.InertiaEndTime : finger.Age;
inertiaMoveSpeed = delta.magnitude / moveTime;
velocity = inertiaMoveSpeed;
inertiaMoveDir = new Vector3(-delta.x, 0, -delta.y).normalized;
}
/// <summary>
/// 相机移动:单指操作
/// </summary>
private void CameraMove(List<LeanFinger> fingers)
{
cameraOperationType = CameraOperationType.Move;
Vector3 lastScreenPoint = LeanGesture.GetLastScreenCenter(fingers);
Vector3 screenPoint = LeanGesture.GetScreenCenter(fingers);
Vector3 screenDelta = fingers[0].ScreenDelta;
fMoveDeltaX = -screenDelta.x * Time.deltaTime * CameraVarible.MoveSpeed;
fMoveDeltaZ = -screenDelta.y * Time.deltaTime * CameraVarible.MoveSpeed;
MoveCameraPlene();
//Vector3 newPos = transform.position;
//Vector3 forward = transform.forward;
//forward.y = 0;
//forward = forward.normalized;
//newPos -= (transform.right * screenDelta.x * Time.deltaTime * MoveSpeed);
//newPos -= (forward * screenDelta.y * Time.deltaTime * MoveSpeed);
//transform.position = newPos;
}
/// <summary>
/// 相机旋转:双指操作
/// </summary>
private void CameraRotate(List<LeanFinger> fingers)
{
if (!(cameraOperationType == CameraOperationType.None || cameraOperationType == CameraOperationType.Rotate))
return;
float twistDegrees = LeanGesture.GetTwistDegrees(fingers);
if (cameraOperationType == CameraOperationType.Rotate || UnityEngine.Mathf.Abs(twistDegrees) > 1f)
{
cameraOperationType = CameraOperationType.Rotate;
Vector3 screenCheckPoint = LeanGesture.GetScreenCenter(fingers);
Ray screenRay = mCamera.ScreenPointToRay(screenCheckPoint);
RaycastHit hitInfo;
if (Physics.Raycast(screenRay, out hitInfo, 1000))
{
Vector3 rotateCenter = hitInfo.point;
rotateCenter.y = mCamera.transform.position.y;
transform.RotateAround(rotateCenter, Vector3.up, twistDegrees * RotateSpeed);
}
}
}
/// <summary>
/// 相机镜头拉远拉近:双指操作
/// </summary>
/// <param name="fingers"></param>
private void CameraZoom(List<LeanFinger> fingers)
{
if (!(cameraOperationType == CameraOperationType.None || cameraOperationType == CameraOperationType.Zoom))
return;
float pinchRatio = LeanGesture.GetPinchRatio(fingers);
if (cameraOperationType == CameraOperationType.Zoom || UnityEngine.Mathf.Abs(pinchRatio - 1) > 0.02f)
{
cameraOperationType = CameraOperationType.Zoom;
Zoom *= pinchRatio * ZoomSpeed;
Zoom = Mathf.Clamp(Zoom, MinZoom, MaxZoom);
mCamera.fieldOfView = Zoom;
}
}
float SmoothDamp(float current, float target, float smoothTime)
{
float deltaV = (velocity - target) / smoothTime;
return current - Time.deltaTime * deltaV;
}
//相机惯性移动
bool InertiaCameraMove()
{
inertiaMoveSpeed = SmoothDamp(inertiaMoveSpeed, 0, 0.25f);
if (inertiaMoveSpeed > 0.01f)
{
Vector3 change = inertiaMoveDir * CameraVarible.InertiaMoveSpeed * Time.deltaTime * inertiaMoveSpeed;
fMoveDeltaX = change.x;
fMoveDeltaZ = change.z;
MoveCameraPlene();
return true;
}
return false;
}
/// <summary>
/// 相机水平移动
/// </summary>
void MoveCameraPlene()
{
if (fMoveDeltaX == 0f && fMoveDeltaZ == 0f)
return;
Vector3 newPos = transform.position;
Vector3 forward = transform.forward;
forward.y = 0;
forward = forward.normalized;
newPos += (transform.right * fMoveDeltaX);
newPos += (forward * fMoveDeltaZ);
transform.position = newPos;
}
private void LateUpdate()
{
FingerOperationType operationType = Touch_Manager.Instance.GetCurFingerOperationType();
//无手指操作
if (operationType == FingerOperationType.WatingOperation)
{
if (cameraOperationType == CameraOperationType.Move)
{
if (!InertiaCameraMove())
cameraOperationType = CameraOperationType.None;
}
return;
}
//手指操作
var fingers = LeanTouch.GetFingers(false, false, 0);
switch (operationType)
{
case FingerOperationType.OneFingerOperation:
CameraMove(fingers);
break;
case FingerOperationType.DoubleFingerOperation:
CameraRotate(fingers);
CameraZoom(fingers);
break;
default:
break;
}
}
}