说明
实现了一个功能脚本,方便于摄像机围绕一个物体进行旋转和缩放,使用的方式也很简单,将脚本挂载到主摄像机中。【Unity安卓端手势控制摄像机的旋转和缩放】
这里还用到了DoTween
的插件和UniRx
,需要自己导入一下,如果不想使用插件,可以把以下代码简单修改一下。
using UnityEngine;
using DG.Tweening;
using UnityEngine.EventSystems;
using QFramework;
using UniRx;
using UniRx.Triggers;
/// <summary>
/// 摄像机控制管理
/// </summary>
public class CameraController : MonoBehaviour
{
static CameraController _instance;
public static CameraController Ins
{
get {
return _instance; }
}
Transform cam_TF;
// 是否可以控制摄像机
public bool isCanControlCam = true;
[Header("旋转的目标点:")]
public Transform rotTarget;
[Header("相机点击UI前进和返回的速度")]
public float cameraMoveSpeed = 400f;
[Header("旋转速度和缩放速度:")]
public float rotateSpeed = 1.25f;
public float wheelSpeed = 100f;
[Header("摄像机的最远距离和最近距离:")]
public float minDist = 3;
public float maxDist = 60;
[Header("最大俯仰角:")]
public float maxAngle;
[Header("最小俯仰角:")]
public float minAngle;
// 当前摄像机俯仰角
public float nowCamEulerX;
Vector3 initPos;
void Awake()
{
_instance = this;
cam_TF = Camera.main.transform;
}
void Start()
{
cam_TF.LookAt(rotTarget);
initPos = cam_TF.localPosition;
nowCamEulerX = cam_TF.localEulerAngles.x;
this.LateUpdateAsObservable().Subscribe(_ => {
if (!isCanControlCam)
return;
CameraRotate();
CameraFOV();
});
}
/// <summary>
/// 摄像机的初始位置
///可供外部调用 使摄像机位置初始化
/// </summary>
public void CamMoveInitPos()
{
if (!isCanControlCam)
return;
this.Sequence()
.Event(() =>
{
isCanControlCam = false;
mouseLerpPos = Vector2.zero;
cam_TF.DORotate(new Vector3(25, -44, 0), 1f);
cam_TF.DOMove(initPos, 1f);
})
.Delay(1.05f)
.Event(() =>
{
isCanControlCam = true;
nowCamEulerX = cam_TF.localEulerAngles.x;
})
.Begin();
}
#region 鼠标操作
Vector2 mousePos;
Vector2 mouseLerpPos;
/// <summary>
/// 摄像机旋转
/// </summary>
void CameraRotate()
{
mousePos.x = Input.GetAxis("Mouse X");
mousePos.y = Input.GetAxis("Mouse Y");
if (Input.GetMouseButton(0) && !EventSystem.current.IsPointerOverGameObject())
{
mouseLerpPos.x = Mathf.Lerp(mouseLerpPos.x, mousePos.x, 5 * Time.deltaTime);
mouseLerpPos.y = Mathf.Lerp(mouseLerpPos.y, mousePos.y, 5 * Time.deltaTime);
}
else
{
mouseLerpPos.x = Mathf.Lerp(mouseLerpPos.x, 0, 5 * Time.deltaTime);
mouseLerpPos.y = Mathf.Lerp(mouseLerpPos.y, 0, 5 * Time.deltaTime);
}
cam_TF.RotateAround(rotTarget.position, Vector3.up, mouseLerpPos.x * rotateSpeed);
nowCamEulerX -= mouseLerpPos.y * rotateSpeed;
if (nowCamEulerX > maxAngle || nowCamEulerX < minAngle)
{
nowCamEulerX += mouseLerpPos.y * rotateSpeed;
mouseLerpPos.y = 0;
return;
}
if (Mathf.Abs(-mouseLerpPos.y * rotateSpeed) < 0.02f)
return;
cam_TF.RotateAround(rotTarget.position, cam_TF.right, -mouseLerpPos.y * rotateSpeed * 0.5f);
}
float wheelValue;
float wheelTargetValue;
/// <summary>
/// 摄像机缩放
/// </summary>
void CameraFOV()
{
wheelValue = Input.GetAxis("Mouse ScrollWheel");
if (Vector3.Distance(cam_TF.position, rotTarget.position) < minDist && wheelValue > 0)
{
return;
}
if (Vector3.Distance(cam_TF.position, rotTarget.position) > maxDist && wheelValue < 0)
{
return;
}
if (wheelValue > 0)
wheelValue = 0.15f;
if (wheelValue < 0)
wheelValue = -0.15f;
wheelTargetValue = Mathf.Lerp(wheelTargetValue, wheelValue, 5 * Time.deltaTime);
cam_TF.Translate(Vector3.forward * wheelTargetValue * wheelSpeed);
}
#endregion
}