897 lines
32 KiB
C#
897 lines
32 KiB
C#
using com.fpnn.livedata;
|
||
using UnityEngine;
|
||
|
||
namespace HexGrid
|
||
{
|
||
|
||
public class CompleteCameraMove : MonoBehaviour
|
||
{
|
||
[Header("移动设置")]
|
||
[SerializeField] private float moveSpeed = 10f;
|
||
[SerializeField] private float dragSpeed = 4f;
|
||
|
||
[Header("缩放设置")]
|
||
[SerializeField] private float zoomSpeed = 20f;
|
||
[SerializeField] private float minZoom = 5f;
|
||
[SerializeField] private float maxZoom = 20f;
|
||
[SerializeField] private bool smoothZoom = true;
|
||
[SerializeField] private float zoomSmoothSpeed = 10f;
|
||
[SerializeField] private float touchZoomFactor = 0.025f;
|
||
|
||
[Header("旋转设置")]
|
||
public float rotationSpeed = 2f;
|
||
public float touchRotationSpeed = 1f;
|
||
public float minRotationY = -60f;
|
||
public float maxRotationY = 60f;
|
||
|
||
|
||
[Header("调试")] [SerializeField] private bool showDebugInfo = false;
|
||
|
||
// 拖拽相关变量
|
||
private bool isDragging = false;
|
||
private Vector3 lastMousePosition;
|
||
private Vector3 lastTouchPosition;
|
||
|
||
// 移动的值,
|
||
private Vector3 _moveValue;
|
||
// 旋转最终的值,注意是直接改变位置
|
||
private Vector3 _rotateCameraPos;
|
||
// 缩放偏移值
|
||
private Vector3 _rotateDelta;
|
||
// 缩放的偏移值
|
||
private Vector3 _zoomDelta;
|
||
|
||
// 缩放相关变量
|
||
private float currentZoomDistance;
|
||
private float targetZoomDistance;
|
||
private Camera cam;
|
||
private Vector3 fixedLookDirection; // 固定的观察方向
|
||
|
||
// 旋转的值
|
||
private bool isRotating = false;
|
||
private Vector3 targetPosition;
|
||
private float distanceCameraToTarget;
|
||
private float currentYaw = 0f;
|
||
private float currentPitch = 0f;
|
||
private bool initialized = false;
|
||
|
||
// 触摸旋转相关
|
||
// private Vector2 lastTouchPosition;
|
||
// private bool isTouchRotating = false;
|
||
|
||
private enum InputState
|
||
{
|
||
None,
|
||
KeyboardMove,
|
||
MouseDrag,
|
||
MouseRotate,
|
||
MouseZoom,
|
||
TouchMove,
|
||
TouchZoomRotate
|
||
}
|
||
private InputState currentState = InputState.None;
|
||
|
||
// 输入状态
|
||
// private Vector3 lastMousePosition;
|
||
private Vector2 lastTouchCenter;
|
||
private float lastTouchDistance;
|
||
private bool wasTwoFingerActive = false;
|
||
|
||
|
||
|
||
void Start()
|
||
{
|
||
// 初始化相机和缩放
|
||
cam = GetComponent<Camera>();
|
||
if (cam == null)
|
||
{
|
||
cam = Camera.main;
|
||
}
|
||
if (cam != null)
|
||
{
|
||
// 记录初始的观察方向(从相机指向目标的方向)
|
||
fixedLookDirection = transform.forward;
|
||
InitializeRotation();
|
||
targetZoomDistance = distanceCameraToTarget;
|
||
currentZoomDistance = targetZoomDistance;
|
||
Log($"相机控制器初始化完成 - 初始缩放距离: {targetZoomDistance}");
|
||
Log($"固定观察方向: {fixedLookDirection}");
|
||
}
|
||
}
|
||
|
||
void InitializeRotation()
|
||
{
|
||
UpdateRotation();
|
||
initialized = true;
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
// HandleKeyboardInput();
|
||
// HandleMouseInput();
|
||
// HandleTouchInput();
|
||
// HandleZoomInput();
|
||
// UpdateZoom();
|
||
// UpdateRotation();
|
||
//
|
||
// if (!isDragging)
|
||
// {
|
||
// // 触摸输入优先
|
||
// HandleMouseRotation();
|
||
// }
|
||
|
||
UpdateInputState();
|
||
HandleCurrentInput();
|
||
UpdateCameraTransform();
|
||
|
||
if (showDebugInfo && Input.GetKeyDown(KeyCode.F1))
|
||
{
|
||
Log($"相机位置: {transform.position}, 当前缩放: {currentZoomDistance}");
|
||
Log($"观察方向: {transform.forward}");
|
||
}
|
||
}
|
||
|
||
|
||
void UpdateInputState()
|
||
{
|
||
InputState newState = InputState.None;
|
||
// 触摸输入优先级最高
|
||
if (Input.touchCount > 0)
|
||
{
|
||
newState = Input.touchCount == 1 ? InputState.TouchMove : InputState.TouchZoomRotate;
|
||
}
|
||
// 鼠标输入次之
|
||
else if (Input.GetMouseButton(1))
|
||
{
|
||
newState = InputState.MouseRotate;
|
||
}
|
||
else if (Input.GetMouseButton(0))
|
||
{
|
||
newState = InputState.MouseDrag;
|
||
}
|
||
else if (Mathf.Abs(Input.GetAxis("Mouse ScrollWheel")) > 0.01f)
|
||
{
|
||
newState = InputState.MouseZoom;
|
||
}
|
||
// 键盘输入最后
|
||
else if (IsAnyMovementKeyPressed())
|
||
{
|
||
newState = InputState.KeyboardMove;
|
||
}
|
||
|
||
if (newState != currentState)
|
||
{
|
||
OnInputStateChanged(currentState, newState);
|
||
currentState = newState;
|
||
}
|
||
}
|
||
|
||
void HandleCurrentInput()
|
||
{
|
||
switch (currentState)
|
||
{
|
||
case InputState.KeyboardMove:
|
||
HandleKeyboardInput();
|
||
break;
|
||
|
||
case InputState.MouseDrag:
|
||
HandleMouseDrag();
|
||
break;
|
||
|
||
case InputState.MouseRotate:
|
||
HandleMouseRotation();
|
||
break;
|
||
case InputState.MouseZoom:
|
||
HandleMouseZoom();
|
||
break;
|
||
|
||
case InputState.TouchMove:
|
||
HandleSingleTouchMove();
|
||
break;
|
||
|
||
case InputState.TouchZoomRotate:
|
||
HandleTwoFingerGestures();
|
||
break;
|
||
}
|
||
}
|
||
private void UpdateCameraTransform()
|
||
{
|
||
// 移动的值
|
||
if (_moveValue != Vector3.zero)
|
||
{
|
||
transform.position += _moveValue;
|
||
_rotateCameraPos = transform.position;
|
||
_moveValue = Vector3.zero;
|
||
// CalcTargetPosition(); // 更新
|
||
}
|
||
// else
|
||
// {
|
||
if (_rotateDelta != Vector3.zero)
|
||
{
|
||
transform.position += _rotateDelta;
|
||
_rotateDelta = Vector3.zero;
|
||
transform.LookAt(targetPosition);
|
||
}
|
||
//
|
||
if (_zoomDelta != Vector3.zero)
|
||
{
|
||
transform.position += _zoomDelta;
|
||
_zoomDelta = Vector3.zero;
|
||
transform.LookAt(targetPosition);
|
||
}
|
||
|
||
// }
|
||
UpdateRotation();
|
||
}
|
||
|
||
void OnInputStateChanged(InputState oldState, InputState newState)
|
||
{
|
||
if (showDebugInfo)
|
||
{
|
||
Log($"🎮 输入状态变化: {oldState} → {newState}");
|
||
}
|
||
|
||
// 开始旋转时锁定旋转中心
|
||
if (newState == InputState.MouseRotate || newState == InputState.TouchZoomRotate)
|
||
{
|
||
// 锁定当前的旋转中心
|
||
// currentRotationCenter = CalculateViewportCenter();
|
||
// currentDistanceToCenter = Vector3.Distance(transform.position, currentRotationCenter);
|
||
// targetDistanceToCenter = currentDistanceToCenter;
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log($"🔒 锁定旋转中心: {currentRotationCenter}, 距离: {currentDistanceToCenter:F2}");
|
||
// }
|
||
// UpdateRotation();
|
||
}
|
||
|
||
// 状态特定的初始化
|
||
switch (newState)
|
||
{
|
||
case InputState.MouseRotate:
|
||
lastMousePosition = Input.mousePosition;
|
||
Cursor.lockState = CursorLockMode.Locked;
|
||
break;
|
||
|
||
case InputState.TouchZoomRotate:
|
||
if (Input.touchCount >= 2)
|
||
{
|
||
InitializeTwoFingerGesture();
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
// 退出状态的清理
|
||
if (oldState == InputState.MouseRotate)
|
||
{
|
||
Cursor.lockState = CursorLockMode.None;
|
||
}
|
||
}
|
||
|
||
|
||
void InitializeTwoFingerGesture()
|
||
{
|
||
if (Input.touchCount >= 2)
|
||
{
|
||
Touch touch1 = Input.GetTouch(0);
|
||
Touch touch2 = Input.GetTouch(1);
|
||
|
||
lastTouchCenter = (touch1.position + touch2.position) * 0.5f;
|
||
lastTouchDistance = Vector2.Distance(touch1.position, touch2.position);
|
||
wasTwoFingerActive = true;
|
||
}
|
||
}
|
||
|
||
bool IsAnyMovementKeyPressed()
|
||
{
|
||
return Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S) ||
|
||
Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D);
|
||
}
|
||
|
||
// 键盘移动(保持原来的逻辑)
|
||
void HandleKeyboardInput()
|
||
{
|
||
Vector3 move = Vector3.zero;
|
||
|
||
if (Input.GetKey(KeyCode.W)) move.z += 1;
|
||
if (Input.GetKey(KeyCode.S)) move.z -= 1;
|
||
if (Input.GetKey(KeyCode.A)) move.x -= 1;
|
||
if (Input.GetKey(KeyCode.D)) move.x += 1;
|
||
|
||
if (move != Vector3.zero)
|
||
{
|
||
// 基于当前相机方向进行移动
|
||
Vector3 forward = transform.forward;
|
||
Vector3 right = transform.right;
|
||
|
||
// 计算移动方向(保持在水平面)
|
||
Vector3 moveDirection = (forward * move.z + right * move.x).normalized;
|
||
moveDirection.y = 0; // 确保只在水平面移动
|
||
//transform.position += moveDirection * moveSpeed * Time.deltaTime;
|
||
|
||
_moveValue = moveDirection * moveSpeed * Time.deltaTime;
|
||
}
|
||
}
|
||
|
||
void HandleMouseDrag()
|
||
{
|
||
if (Input.GetMouseButtonDown(0))
|
||
{
|
||
lastMousePosition = Input.mousePosition;
|
||
}
|
||
else if (Input.GetMouseButton(0))
|
||
{
|
||
Vector3 currentMousePos = Input.mousePosition;
|
||
Vector3 mouseDelta = lastMousePosition - currentMousePos;
|
||
Vector3 worldDelta = ScreenToWorldDelta(mouseDelta);
|
||
// transform.position += worldDelta * dragSpeed * Time.deltaTime;
|
||
_moveValue = worldDelta * dragSpeed * Time.deltaTime;
|
||
|
||
// 移动后重新计算距离
|
||
// currentDistanceToCenter = Vector3.Distance(transform.position, currentRotationCenter);
|
||
// targetDistanceToCenter = currentDistanceToCenter;
|
||
lastMousePosition = currentMousePos;
|
||
}
|
||
}
|
||
|
||
// 鼠标拖拽移动
|
||
// void HandleMouseInput()
|
||
// {
|
||
// // 忽略触摸输入时的鼠标输入
|
||
// if (Input.touchCount > 0) return;
|
||
// if (Input.GetMouseButtonDown(0))
|
||
// {
|
||
// isDragging = true;
|
||
// lastMousePosition = Input.mousePosition;
|
||
//
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log("开始鼠标拖拽");
|
||
// }
|
||
// }
|
||
// else if (Input.GetMouseButtonUp(0))
|
||
// {
|
||
// isDragging = false;
|
||
//
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log("结束鼠标拖拽");
|
||
// }
|
||
// }
|
||
// if (isDragging)
|
||
// {
|
||
// Vector3 currentMousePosition = Input.mousePosition;
|
||
// Vector3 deltaScreenPosition = lastMousePosition - currentMousePosition;
|
||
//
|
||
// // 将屏幕空间的移动转换为世界空间
|
||
// Vector3 worldDelta = ScreenToWorldDelta(deltaScreenPosition);
|
||
//
|
||
// // 移动相机(保持观察角度)
|
||
// transform.position += worldDelta * dragSpeed * Time.deltaTime;
|
||
//
|
||
// // 更新记录位置
|
||
// lastMousePosition = currentMousePosition;
|
||
//
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log($"鼠标拖拽移动: {worldDelta}");
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// 触摸拖拽移动
|
||
// void HandleTouchInput()
|
||
// {
|
||
// if (Input.touchCount == 1)
|
||
// {
|
||
// var touch = Input.GetTouch(0);
|
||
// if (touch.phase == TouchPhase.Began)
|
||
// {
|
||
// isDragging = true;
|
||
// lastTouchPosition = touch.position;
|
||
//
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log("开始触摸拖拽");
|
||
// }
|
||
// }
|
||
// else if (touch.phase == TouchPhase.Ended)
|
||
// {
|
||
// isDragging = false;
|
||
//
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log("结束触摸拖拽");
|
||
// }
|
||
// }
|
||
// else if (touch.phase == TouchPhase.Moved && isDragging)
|
||
// {
|
||
// Vector3 currentTouchPosition = touch.position;
|
||
// Vector3 deltaScreenPosition = lastTouchPosition - currentTouchPosition;
|
||
//
|
||
// // Vector2 deltaPosition = touch.deltaPosition;
|
||
// // 将屏幕空间的移动转换为世界空间
|
||
// Vector3 worldDelta = ScreenToWorldDelta(deltaScreenPosition);
|
||
// // 移动相机(保持观察角度)
|
||
// transform.position += worldDelta * dragSpeed * Time.deltaTime;
|
||
//
|
||
// // 更新记录位置
|
||
// lastTouchPosition = currentTouchPosition;
|
||
//
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log($"触摸拖拽移动: {worldDelta}");
|
||
// }
|
||
// }
|
||
// }
|
||
// else if (Input.touchCount == 2)
|
||
// {
|
||
// // 双指捏合缩放
|
||
// HandlePinchZoom();
|
||
// HandleTouchRotation();
|
||
// isDragging = false; // 停止拖拽
|
||
// }
|
||
// else if (Input.touchCount > 2)
|
||
// {
|
||
// // 多点触控时停止所有操作
|
||
// isDragging = false;
|
||
// }
|
||
// }
|
||
|
||
// 处理缩放输入(鼠标滚轮 + 双指捏合)
|
||
// void HandleZoomInput()
|
||
// {
|
||
// // 鼠标滚轮缩放
|
||
// float scrollInput = Input.GetAxis("Mouse ScrollWheel");
|
||
// if (scrollInput != 0)
|
||
// {
|
||
// var zoomChange = -scrollInput * zoomSpeed; // 负号使滚轮向上为放大
|
||
// targetZoomDistance = Mathf.Clamp(targetZoomDistance + zoomChange, minZoom, maxZoom);
|
||
//
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log($"滚轮缩放: {scrollInput} -> 目标缩放距离: {targetZoomDistance}");
|
||
// }
|
||
// }
|
||
//
|
||
// // 键盘缩放(备选)
|
||
// if (Input.GetKey(KeyCode.Q))
|
||
// {
|
||
// targetZoomDistance = Mathf.Clamp(targetZoomDistance - zoomSpeed * Time.deltaTime, minZoom, maxZoom);
|
||
// }
|
||
//
|
||
// if (Input.GetKey(KeyCode.E))
|
||
// {
|
||
// targetZoomDistance = Mathf.Clamp(targetZoomDistance + zoomSpeed * Time.deltaTime, minZoom, maxZoom);
|
||
// }
|
||
// }
|
||
|
||
void HandleTwoFingerRotation(Vector2 currentCenter)
|
||
{
|
||
Vector2 centerDelta = currentCenter - lastTouchCenter;
|
||
if (centerDelta.magnitude > 3f)
|
||
{
|
||
float deltaX = centerDelta.x * 0.2f;
|
||
float deltaY = centerDelta.y * 0.2f;
|
||
ApplyRotationDelta(deltaX, deltaY,touchRotationSpeed);
|
||
}
|
||
}
|
||
|
||
void HandlePinchZoom(float currentTouchDistance)
|
||
{
|
||
float distanceDelta = currentTouchDistance - lastTouchDistance;
|
||
if (Mathf.Abs(distanceDelta) > 5f)
|
||
{
|
||
float zoomDelta = -distanceDelta * zoomSpeed * touchZoomFactor;
|
||
targetZoomDistance = Mathf.Clamp(targetZoomDistance + zoomDelta, minZoom, maxZoom);
|
||
}
|
||
ApplyZoom();
|
||
}
|
||
|
||
// 双指捏合缩放
|
||
// void HandlePinchZoom()
|
||
// {
|
||
// Log("HandePinchZoom");
|
||
//
|
||
// Touch touch1 = Input.GetTouch(0);
|
||
// Touch touch2 = Input.GetTouch(1);
|
||
//
|
||
// // 计算当前两指距离
|
||
// float currentDistance = Vector2.Distance(touch1.position, touch2.position);
|
||
//
|
||
// // 计算上一帧两指距离
|
||
// Vector2 touch1PrevPos = touch1.position - touch1.deltaPosition;
|
||
// Vector2 touch2PrevPos = touch2.position - touch2.deltaPosition;
|
||
// float prevDistance = Vector2.Distance(touch1PrevPos, touch2PrevPos);
|
||
//
|
||
// // 计算缩放变化
|
||
// if (prevDistance > 0)
|
||
// {
|
||
// float deltaDistance = currentDistance - prevDistance;
|
||
// float zoomChange = deltaDistance * zoomSpeed * 0.01f; // 调整灵敏度
|
||
// targetZoomDistance = Mathf.Clamp(targetZoomDistance - zoomChange, minZoom, maxZoom); // 注意符号
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log($"捏合缩放: 距离变化={deltaDistance} -> 目标缩放距离: {targetZoomDistance}");
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
//
|
||
private void Log(string t)
|
||
{
|
||
Debug.Log($"<color=yellow> CompleteCameraMove: {t} </color>");
|
||
}
|
||
|
||
// 更新旋转
|
||
void UpdateRotation()
|
||
{
|
||
CalcTargetPosition();
|
||
// 计算初始参数
|
||
Vector3 direction = transform.position - targetPosition;
|
||
distanceCameraToTarget = direction.magnitude;
|
||
currentYaw = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
|
||
currentPitch = Mathf.Asin(direction.y / distanceCameraToTarget) * Mathf.Rad2Deg;
|
||
_rotateCameraPos = transform.position;
|
||
}
|
||
|
||
private void CalcTargetPosition()
|
||
{
|
||
Ray ray = new Ray(transform.position, transform.forward);
|
||
float groundHeight = 0f;
|
||
Plane groundPlane = new Plane(Vector3.up, new Vector3(0, groundHeight, 0));
|
||
if (groundPlane.Raycast(ray, out float enter) )
|
||
{
|
||
Vector3 hitPoint = ray.GetPoint(enter);
|
||
// Log($"数学检测到地面点: {hitPoint} {enter}");
|
||
targetPosition = hitPoint;
|
||
}
|
||
}
|
||
|
||
// 更新缩放效果(关键修改:保持视角方向不变)
|
||
void ApplyZoom()
|
||
{
|
||
if (cam == null) return;
|
||
if (Mathf.Abs(currentZoomDistance - targetZoomDistance) > 0.01f)
|
||
{
|
||
if (smoothZoom)
|
||
{
|
||
// 平滑缩放
|
||
currentZoomDistance = Mathf.Lerp(currentZoomDistance, targetZoomDistance,
|
||
zoomSmoothSpeed * Time.deltaTime);
|
||
}
|
||
else
|
||
{
|
||
// 直接缩放
|
||
currentZoomDistance = targetZoomDistance;
|
||
}
|
||
|
||
ApplyPerspectiveZoom(currentZoomDistance);
|
||
}
|
||
}
|
||
|
||
// 透视相机缩放的具体实现
|
||
void ApplyPerspectiveZoom(float zoomDistance)
|
||
{
|
||
var targetPoint = targetPosition;
|
||
// 计算从目标点到相机的方向(当前观察方向的反向)
|
||
Vector3 directionToCamera = -transform.forward;
|
||
// 根据缩放距离重新定位相机
|
||
Vector3 newPosition = targetPoint + directionToCamera * zoomDistance;
|
||
// 只更新位置,保持旋转不变
|
||
// transform.position = newPosition;
|
||
_rotateCameraPos = newPosition;
|
||
// _zoomDelta = directionToCamera * zoomDistance;
|
||
_zoomDelta = newPosition - transform.position;
|
||
|
||
// if (showDebugInfo)
|
||
// {
|
||
// Log($"透视缩放 - 目标点: {targetPoint}, 新位置: {newPosition}, 距离: {zoomDistance}");
|
||
// }
|
||
}
|
||
|
||
Vector3 ScreenTargetPoint()
|
||
{
|
||
Vector3 screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, 0);
|
||
Ray ray = cam.ScreenPointToRay(screenCenter);
|
||
// 假设地面在Y=0,计算射线与地面的交点
|
||
Vector3 targetPoint = Vector3.zero;
|
||
if (ray.direction.y != 0)
|
||
{
|
||
float t = -ray.origin.y / ray.direction.y;
|
||
if (t > 0)
|
||
{
|
||
targetPoint = ray.origin + ray.direction * t;
|
||
}
|
||
}
|
||
return targetPoint;
|
||
}
|
||
|
||
// 将屏幕空间的移动差值转换为世界空间
|
||
Vector3 ScreenToWorldDelta(Vector3 screenDelta)
|
||
{
|
||
// 根据当前缩放级别调整移动灵敏度
|
||
float scaleFactor = currentZoomDistance * 0.01f;
|
||
|
||
// 基于相机的当前方向向量进行转换
|
||
Vector3 right = transform.right;
|
||
Vector3 forward = transform.forward;
|
||
|
||
// 计算世界空间移动(保持在水平面)
|
||
Vector3 worldDelta = (right * screenDelta.x + forward * screenDelta.y) * scaleFactor;
|
||
worldDelta.y = 0; // 确保只在水平面移动
|
||
|
||
return worldDelta;
|
||
}
|
||
|
||
// 公共接口
|
||
public void SetZoom(float zoom)
|
||
{
|
||
targetZoomDistance = Mathf.Clamp(zoom, minZoom, maxZoom);
|
||
}
|
||
|
||
public float GetZoom()
|
||
{
|
||
return currentZoomDistance;
|
||
}
|
||
|
||
public void ZoomIn(float amount = 1f)
|
||
{
|
||
targetZoomDistance = Mathf.Clamp(targetZoomDistance - amount, minZoom, maxZoom);
|
||
}
|
||
|
||
public void ZoomOut(float amount = 1f)
|
||
{
|
||
targetZoomDistance = Mathf.Clamp(targetZoomDistance + amount, minZoom, maxZoom);
|
||
}
|
||
|
||
// 重置观察方向(如果需要的话)
|
||
public void SetLookDirection(Vector3 direction)
|
||
{
|
||
fixedLookDirection = direction.normalized;
|
||
transform.forward = fixedLookDirection;
|
||
}
|
||
|
||
|
||
void HandleMouseRotation()
|
||
{
|
||
float deltaX = Input.GetAxis("Mouse X");
|
||
float deltaY = Input.GetAxis("Mouse Y");
|
||
ApplyRotationDelta(deltaX,deltaY,rotationSpeed);
|
||
}
|
||
|
||
void HandleMouseZoom()
|
||
{
|
||
float scrollInput = Input.GetAxis("Mouse ScrollWheel");
|
||
if (scrollInput != 0)
|
||
{
|
||
var zoomChange = -scrollInput * zoomSpeed; // 负号使滚轮向上为放大
|
||
targetZoomDistance = Mathf.Clamp(targetZoomDistance + zoomChange, minZoom, maxZoom);
|
||
if (showDebugInfo)
|
||
{
|
||
Log($"滚轮缩放: {scrollInput} -> 目标缩放距离: {targetZoomDistance}");
|
||
}
|
||
}
|
||
ApplyZoom();
|
||
}
|
||
|
||
void HandleSingleTouchMove()
|
||
{
|
||
Touch touch = Input.GetTouch(0);
|
||
|
||
if (touch.phase == TouchPhase.Began)
|
||
{
|
||
lastTouchCenter = touch.position;
|
||
wasTwoFingerActive = false;
|
||
}
|
||
else if (touch.phase == TouchPhase.Moved)
|
||
{
|
||
// Vector2 touchDelta = lastTouchCenter - touch.position;
|
||
// Vector3 worldDelta = CalculateWorldDragDirection(touchDelta);
|
||
// transform.position += worldDelta * dragSpeed * Time.deltaTime;
|
||
// Vector3 currentMousePos = lastTouchCenter;
|
||
// Vector3 mouseDelta = lastMousePosition - currentMousePos;
|
||
if (!wasTwoFingerActive)
|
||
{
|
||
Vector2 touchDelta = lastTouchCenter - touch.position;
|
||
Vector3 worldDelta = ScreenToWorldDelta(touchDelta);
|
||
// transform.position += worldDelta * dragSpeed * Time.deltaTime;
|
||
_moveValue = worldDelta * dragSpeed * Time.deltaTime;
|
||
}
|
||
|
||
// 移动后重新计算距离
|
||
// currentDistanceToCenter = Vector3.Distance(transform.position, currentRotationCenter);
|
||
// targetDistanceToCenter = currentDistanceToCenter;
|
||
// lastMousePosition = currentMousePos;
|
||
// 移动后重新计算距离
|
||
// currentDistanceToCenter = Vector3.Distance(transform.position, currentRotationCenter);
|
||
// targetDistanceToCenter = currentDistanceToCenter;
|
||
|
||
lastTouchCenter = touch.position;
|
||
}
|
||
}
|
||
|
||
void HandleTwoFingerGestures()
|
||
{
|
||
if (Input.touchCount < 2) return;
|
||
|
||
Touch touch1 = Input.GetTouch(0);
|
||
Touch touch2 = Input.GetTouch(1);
|
||
|
||
Vector2 currentCenter = (touch1.position + touch2.position) * 0.5f;
|
||
float currentDistance = Vector2.Distance(touch1.position, touch2.position);
|
||
|
||
if (wasTwoFingerActive)
|
||
{
|
||
// HandleTwoFingerRotation(currentCenter);
|
||
HandlePinchZoom(currentDistance);
|
||
}
|
||
|
||
lastTouchCenter = currentCenter;
|
||
lastTouchDistance = currentDistance;
|
||
wasTwoFingerActive = true;
|
||
}
|
||
// void HandleTouchRotation()
|
||
// {
|
||
// if (Input.touchCount == 2)
|
||
// {
|
||
// Touch touch1 = Input.GetTouch(0);
|
||
// Touch touch2 = Input.GetTouch(1);
|
||
// // 只在两个手指都在移动时旋转
|
||
// if (touch1.phase == TouchPhase.Moved && touch2.phase == TouchPhase.Moved)
|
||
// {
|
||
// // 取两个手指移动的平均值
|
||
// Vector2 avgDelta = (touch1.deltaPosition + touch2.deltaPosition) * 0.5f;
|
||
// float deltaX = avgDelta.x * 0.01f * touchRotationSpeed;
|
||
// float deltaY = -avgDelta.y * 0.01f * touchRotationSpeed;
|
||
// RotateCamera(deltaX, deltaY,touchRotationSpeed);
|
||
// }
|
||
// }
|
||
// else
|
||
// {
|
||
// isTouchRotating = false;
|
||
// }
|
||
// }
|
||
|
||
void ApplyRotationDelta(float deltaX, float deltaY, float speed)
|
||
{
|
||
Log($"ApplyRotationDelta -> {deltaX} {deltaY} {speed}");
|
||
// 更新角度
|
||
currentYaw += deltaX * speed;
|
||
currentPitch -= deltaY * speed;
|
||
// 限制垂直角度
|
||
currentPitch = Mathf.Clamp(currentPitch, minRotationY, maxRotationY);
|
||
|
||
// Log($"UpdateRotationDelta -> {currentPitch}");
|
||
// 计算新位置
|
||
float yawRad = currentYaw * Mathf.Deg2Rad;
|
||
float pitchRad = currentPitch * Mathf.Deg2Rad;
|
||
|
||
float x = distanceCameraToTarget * Mathf.Cos(pitchRad) * Mathf.Sin(yawRad);
|
||
float y = distanceCameraToTarget * Mathf.Sin(pitchRad);
|
||
float z = distanceCameraToTarget * Mathf.Cos(pitchRad) * Mathf.Cos(yawRad);
|
||
|
||
var newPosition = targetPosition + new Vector3(x, y, z);
|
||
_rotateDelta = newPosition - transform.position;
|
||
|
||
Log($"UpdateRotationDelta ->{distanceCameraToTarget} {currentPitch} {_rotateDelta}");
|
||
}
|
||
|
||
// void RotateCamera(float deltaX, float deltaY, float speed)
|
||
// {
|
||
// Log($"RotateCamera ->{deltaX} {deltaY} {speed}");
|
||
//
|
||
// if (!initialized) return;
|
||
//
|
||
// // 更新角度
|
||
// currentYaw += deltaX * speed;
|
||
// currentPitch -= deltaY * speed;
|
||
//
|
||
// // 限制垂直角度
|
||
// currentPitch = Mathf.Clamp(currentPitch, -80f, 80f);
|
||
//
|
||
// // 计算新位置
|
||
// float yawRad = currentYaw * Mathf.Deg2Rad;
|
||
// float pitchRad = currentPitch * Mathf.Deg2Rad;
|
||
//
|
||
// float x = distanceCameraToTarget * Mathf.Cos(pitchRad) * Mathf.Sin(yawRad);
|
||
// float y = distanceCameraToTarget * Mathf.Sin(pitchRad);
|
||
// float z = distanceCameraToTarget * Mathf.Cos(pitchRad) * Mathf.Cos(yawRad);
|
||
//
|
||
// // 更新相机位置和朝向
|
||
// transform.position = targetPosition + new Vector3(x, y, z);
|
||
// transform.LookAt(targetPosition);
|
||
// }
|
||
|
||
Color GetStateColor(InputState state)
|
||
{
|
||
switch (state)
|
||
{
|
||
case InputState.None: return Color.gray;
|
||
case InputState.KeyboardMove: return Color.green;
|
||
case InputState.MouseDrag: return Color.blue;
|
||
case InputState.MouseRotate: return Color.red;
|
||
case InputState.TouchMove: return Color.cyan;
|
||
case InputState.TouchZoomRotate: return Color.magenta;
|
||
default: return Color.white;
|
||
}
|
||
}
|
||
|
||
void OnGUI()
|
||
{
|
||
if (!showDebugInfo || !Application.isEditor) return;
|
||
|
||
GUI.backgroundColor = new Color(0, 0, 0, 0.8f);
|
||
GUI.Box(new Rect(10, 10, 450, 220), "");
|
||
GUI.backgroundColor = Color.white;
|
||
|
||
GUI.color = Color.yellow;
|
||
GUI.Label(new Rect(20, 20, 430, 25), "🎯 视口中心旋转相机控制器",
|
||
new GUIStyle(GUI.skin.label) { fontSize = 14, fontStyle = FontStyle.Bold });
|
||
GUI.color = Color.white;
|
||
|
||
GUI.color = Color.white;
|
||
var labelStyle = new GUIStyle(GUI.skin.label) { fontSize = 12 };
|
||
|
||
int yPos = 50;
|
||
GUI.color = GetStateColor(currentState);
|
||
GUI.Label(new Rect(20, yPos, 430, 20), $"🎮 输入状态: {currentState}", labelStyle);
|
||
yPos += 20;
|
||
GUI.color = Color.cyan;
|
||
GUI.Label(new Rect(20, yPos, 430, 20),
|
||
$"📏 距离旋转中心: {targetPosition:F2} → {distanceCameraToTarget:F2} {currentZoomDistance}", labelStyle);
|
||
yPos += 20;
|
||
GUI.color = Color.cyan;
|
||
GUI.Label(new Rect(20, yPos, 430, 20),
|
||
$"📏 移动旋转缩放: {_moveValue:F2} → {_rotateDelta:F2} {_zoomDelta}", labelStyle);
|
||
// yPos += 20;
|
||
|
||
|
||
|
||
|
||
|
||
// var labelStyle = new GUIStyle(GUI.skin.label) { fontSize = 11 };
|
||
}
|
||
// 调试可视化
|
||
void OnDrawGizmos()
|
||
{
|
||
if (Application.isPlaying && cam != null)
|
||
{
|
||
// 绘制当前观察方向
|
||
Gizmos.color = Color.red;
|
||
Gizmos.DrawRay(transform.position, transform.forward * 5f);
|
||
|
||
// 绘制缩放中心点
|
||
// Vector3 screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, 0);
|
||
// Ray ray = cam.ScreenPointToRay(screenCenter);
|
||
// if (ray.direction.y != 0)
|
||
{
|
||
// float t = -ray.origin.y / ray.direction.y;
|
||
// if (t > 0)
|
||
{
|
||
// Vector3 targetPoint = ray.origin + ray.direction * t;
|
||
var targetPoint = targetPosition;
|
||
Gizmos.color = Color.green;
|
||
Gizmos.DrawWireSphere(targetPoint, 1f);
|
||
|
||
// 连线显示缩放关系
|
||
Gizmos.color = Color.yellow;
|
||
Gizmos.DrawLine(transform.position, targetPoint);
|
||
}
|
||
}
|
||
|
||
// if (initialized)
|
||
// {
|
||
// Gizmos.color = Color.red;
|
||
// Gizmos.DrawWireSphere(targetPosition, 1f);
|
||
// }
|
||
// 缩放信息
|
||
#if UNITY_EDITOR
|
||
UnityEditor.Handles.Label(transform.position + Vector3.up * 2,
|
||
$"缩放: {currentZoomDistance:F1} (目标: {targetZoomDistance:F1})");
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
} |