【相机】增加手感控制代码

main
马远征 2025-03-10 17:31:25 +08:00
parent 74924fd951
commit 7ac2dd3d22
4 changed files with 141 additions and 12 deletions

View File

@ -69,6 +69,7 @@
Level_OnClick,
Level_OnDrag,
Level_OnEndDrag,
//level Fight UI
LevelFightStartChange,
LevelFightUIStateChange,

View File

@ -22,6 +22,15 @@ public class CameraController : MonoBehaviour
//之前的缩放是6次滚轮从最小放到最大故每一次缩放的值为1/6f
private const float ZoomStep = 1 / 12f;
[Tooltip("控制缩放响应曲线")]
public float zoomSensitivity = 2.0f;
[Tooltip("缩放速度与当前缩放比例的关系系数")]
public float zoomScaleFactor = 0.75f;
[Tooltip("是否使用平滑缩放效果")]
public bool smoothZoom = true;
[ShowIf("smoothZoom")]
public float zoomSmoothTime = 0.2f;
public float leftMargin = 1.5f;
public float rightMargin = 1.5f;
@ -30,12 +39,24 @@ public class CameraController : MonoBehaviour
public float bottomMargin = 0.9f;
[Header("Camera Movement Settings")]
public float moveSpeedX = 0.19f;
public float moveSpeedY = 0.3f;
public float unitPerPixel = 0.01f;
[Tooltip("是否使用平滑移动效果")]
public bool smoothPanning = true;
[ShowIf("smoothPanning")]
[Tooltip("平移平滑时间,值越小响应越快")]
public float panSmoothTime = 0.08f;
[ShowIf("smoothPanning")]
[Tooltip("惯性系数,控制释放后继续滑动的距离")]
[Range(0, 1)]
public float panInertia = 0.8f;
[ShowIf("smoothPanning")]
[Tooltip("最大平移速度限制")]
public float maxPanSpeed = 3000f;
[ShowIf("isFightCamera")] public float CameraMinSize = 6;
[ShowIf("isFightCamera")] public float CameraMaxSize = 12;
@ -61,6 +82,14 @@ public class CameraController : MonoBehaviour
//Camera拖动控制
public static bool FingerMoveEnable = true;
private float targetZoomScale;
private float zoomVelocity;
private Vector3 targetPanPosition;
private Vector3 panVelocity;
private Vector2 lastDragDelta;
private float lastDragTime;
//size,将透视和正交相机的fov和orthographic size整合为统一数值
private float Size
{
@ -102,6 +131,8 @@ public class CameraController : MonoBehaviour
private void Awake()
{
mainCamera = GetComponent<Camera>();
targetZoomScale = ZoomScale;
targetPanPosition = transform.position;
if (isLegionFightCamera)
{
@ -151,6 +182,7 @@ public class CameraController : MonoBehaviour
{
//InputManager.Instance.OnFingerMove += OnFingerMove2;
EventManager.Instance.Register<PointerEventData>(EventManager.EventName.Level_OnDrag, _OnDragMove);
EventManager.Instance.Register<PointerEventData>(EventManager.EventName.Level_OnEndDrag, OnEndDrag);
InputManager.Instance.OnFingersMove += OnFingersMove;
}
}
@ -162,6 +194,7 @@ public class CameraController : MonoBehaviour
if (InputManager.Instance == null) return;
//InputManager.Instance.OnFingerMove -= OnFingerMove2;
EventManager.Instance.Unregister<PointerEventData>(EventManager.EventName.Level_OnDrag, _OnDragMove);
EventManager.Instance.Unregister<PointerEventData>(EventManager.EventName.Level_OnEndDrag, OnEndDrag);
InputManager.Instance.OnFingersMove -= OnFingersMove;
}
}
@ -171,18 +204,34 @@ public class CameraController : MonoBehaviour
if (!FingerMoveEnable)
return;
Vector3 newPosition;
var startPos = pointerData.pressPosition;
var delta = pointerData.delta;
// 记录拖动速度数据,用于惯性计算
lastDragDelta = delta;
lastDragTime = Time.time;
var oldRay = mainCamera.ScreenPointToRay(startPos);
var newRay = mainCamera.ScreenPointToRay( startPos + delta);
var newRay = mainCamera.ScreenPointToRay(startPos + delta);
var layerMask = 1 << LayerMask.NameToLayer("Ground");
if (Physics.Raycast(oldRay, out var oldHit, 1000, layerMask) &&
Physics.Raycast(newRay, out var newHit, 1000, layerMask))
{
var offset = oldHit.point - newHit.point;
transform.Translate(offset, Space.World);
// DebugUtil.LogG("delta: " + delta + " offset: " + offset);
if (smoothPanning)
{
// 在平滑模式下设置目标位置
targetPanPosition = transform.position + offset;
}
else
{
// 立即移动
transform.Translate(offset, Space.World);
AdjustSelf();
}
}
else
{
@ -199,9 +248,43 @@ public class CameraController : MonoBehaviour
moveX.y = 0;
moveX = moveX.normalized * cameraMove.x;
transform.Translate(moveX + moveY, Space.World);
if (smoothPanning)
{
// 在平滑模式下设置目标位置
targetPanPosition = transform.position + moveX + moveY;
}
else
{
// 立即移动
transform.Translate(moveX + moveY, Space.World);
AdjustSelf();
}
}
}
// 处理拖动结束时的惯性
public void OnEndDrag(PointerEventData pointerData)
{
if (smoothPanning && panInertia > 0 && Time.time - lastDragTime < 0.1f)
{
// 计算惯性位移
Vector2 touchDeltaPosition = -lastDragDelta * panInertia;
float ratio = Size * unitPerPixel;
Vector2 inertiaMove = new(touchDeltaPosition.x * moveSpeedX * ratio,
touchDeltaPosition.y * moveSpeedY * ratio);
var cameraTransform = transform;
var moveY = cameraTransform.up;
moveY.y = 0;
moveY = moveY.normalized * inertiaMove.y;
var moveX = cameraTransform.right;
moveX.y = 0;
moveX = moveX.normalized * inertiaMove.x;
// 应用惯性
targetPanPosition += moveX + moveY;
}
AdjustSelf();
}
private void OnFingersMove(float delta)
@ -214,11 +297,52 @@ public class CameraController : MonoBehaviour
if (GuideManager.Instance.IsGuiding) // 引导中禁止缩放
return;
// 缩放系数随当前缩放程度变化,缩放越小,缩放速度越慢,提供更精确的控制
float currentZoomFactor = ZoomStep * zoomSensitivity;
// 根据当前缩放比例调整缩放速度
if (zoomScaleFactor > 0)
{
float scaleModifier = Mathf.Lerp(0.5f, 1.5f, ZoomScale * zoomScaleFactor);
currentZoomFactor *= scaleModifier;
}
//delta小于0是缩小
var zoomDelta = delta < 0 ? -ZoomStep : ZoomStep;
//修改缩放值
ZoomScale += zoomDelta;
AdjustSelf();
var zoomDelta = delta < 0 ? -currentZoomFactor : currentZoomFactor;
//修改目标缩放值
if (smoothZoom)
{
targetZoomScale = Mathf.Clamp01(targetZoomScale + zoomDelta);
}
else
{
//直接缩放,无平滑效果
ZoomScale += zoomDelta;
AdjustSelf();
}
}
private void Update()
{
// 处理平滑缩放
if (smoothZoom && Math.Abs(ZoomScale - targetZoomScale) > 0.001f)
{
// 使用SmoothDamp实现平滑缩放效果
float newZoomScale = Mathf.SmoothDamp(ZoomScale, targetZoomScale, ref zoomVelocity, zoomSmoothTime);
ZoomScale = newZoomScale;
AdjustSelf();
}
// 处理平滑平移
if (smoothPanning && Vector3.Distance(transform.position, targetPanPosition) > 0.01f)
{
// 限制最大速度
Vector3 newPosition = Vector3.SmoothDamp(transform.position, targetPanPosition,
ref panVelocity, panSmoothTime, maxPanSpeed);
transform.position = newPosition;
AdjustSelf();
}
}
public void KeepCenter(Vector3 centerPos)

View File

@ -159,6 +159,10 @@ public class UIFightSceneTrigger: IUpdatable
return;
}
_curState = TriggerState.None;
if (eventData != null)
{
EventManager.Instance.Send(EventManager.EventName.Level_OnEndDrag, eventData);
}
}
private void _OnLongPress()

View File

@ -81,7 +81,7 @@ pipeline {
def remote = GetRemote();
echo "拉取分支:${remote}"
checkout scmGit(branches: [[name: "*/${remote}"]],
extensions: [checkoutOption(60), lfs(), cloneOption(noTags: false, reference: '', shallow: true, timeout: 120), submodule(recursiveSubmodules: true, reference: '', timeout: 1200)],
extensions: [checkoutOption(60), lfs(), cloneOption(noTags: false, reference: '', shallow: false, timeout: 120), submodule(recursiveSubmodules: true, reference: '', timeout: 1200)],
userRemoteConfigs: [[url: 'http://1.14.122.170:3000/PHXH/NLDClient.git']])
}
}