146 lines
4.8 KiB
C#
146 lines
4.8 KiB
C#
using UnityEngine;
|
||
|
||
public class CameraFollow : MonoBehaviour
|
||
{
|
||
[Header("拖动控制")]
|
||
public float keyboardDragSpeed = 10f; // WASD拖动速度(模拟手指拖动屏幕)
|
||
public float mouseDragSpeed = 0.5f; // 鼠标拖动速度
|
||
public float touchDragSpeed = 0.5f; // 触摸拖动速度
|
||
|
||
[Header("缩放控制(正交相机用orthographicSize,透视相机用fieldOfView)")]
|
||
public float zoomSpeed = 5f; // 缩放速度
|
||
public float minOrthographicSize = 5f; // 正交相机最小size
|
||
public float maxOrthographicSize = 20f; // 正交相机最大size
|
||
public float minFieldOfView = 30f; // 透视相机最小FOV
|
||
public float maxFieldOfView = 90f; // 透视相机最大FOV
|
||
|
||
[Header("边界限制")]
|
||
public bool enableBounds = true;
|
||
public float minX = -6f;
|
||
public float maxX = 6f;
|
||
public float minZ = -30f;
|
||
public float maxZ = 91f;
|
||
|
||
private Vector3 lastMousePosition;
|
||
private bool isDragging = false;
|
||
private Camera cam;
|
||
|
||
private void Start()
|
||
{
|
||
cam = GetComponent<Camera>();
|
||
if (cam == null)
|
||
{
|
||
Debug.LogError("CameraFollow需要挂载在Camera组件上");
|
||
}
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
HandleKeyboardDrag();
|
||
HandleMouseDrag();
|
||
HandleKeyboardZoom();
|
||
}
|
||
|
||
private void HandleKeyboardDrag()
|
||
{
|
||
float horizontal = 0f;
|
||
float vertical = 0f;
|
||
|
||
if (Input.GetKey(KeyCode.W)) vertical = 1f;
|
||
if (Input.GetKey(KeyCode.S)) vertical = -1f;
|
||
if (Input.GetKey(KeyCode.A)) horizontal = -1f;
|
||
if (Input.GetKey(KeyCode.D)) horizontal = 1f;
|
||
|
||
if (horizontal != 0f || vertical != 0f)
|
||
{
|
||
Vector3 movement = new Vector3(horizontal, 0, vertical) * keyboardDragSpeed * Time.deltaTime;
|
||
MoveCameraWithBounds(movement);
|
||
}
|
||
}
|
||
|
||
private void HandleMouseDrag()
|
||
{
|
||
// 鼠标拖动
|
||
if (Input.GetMouseButtonDown(0))
|
||
{
|
||
lastMousePosition = Input.mousePosition;
|
||
isDragging = true;
|
||
}
|
||
else if (Input.GetMouseButton(0) && isDragging)
|
||
{
|
||
Vector3 delta = Input.mousePosition - lastMousePosition;
|
||
Vector3 movement = new Vector3(-delta.x, 0, -delta.y) * mouseDragSpeed * Time.deltaTime;
|
||
MoveCameraWithBounds(movement);
|
||
lastMousePosition = Input.mousePosition;
|
||
}
|
||
else if (Input.GetMouseButtonUp(0))
|
||
{
|
||
isDragging = false;
|
||
}
|
||
|
||
// 触摸拖动(移动设备)
|
||
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
|
||
{
|
||
Vector2 touchDelta = Input.GetTouch(0).deltaPosition;
|
||
Vector3 movement = new Vector3(-touchDelta.x, 0, -touchDelta.y) * touchDragSpeed * Time.deltaTime;
|
||
MoveCameraWithBounds(movement);
|
||
}
|
||
}
|
||
|
||
private void HandleKeyboardZoom()
|
||
{
|
||
if (cam == null) return;
|
||
|
||
float zoomDelta = 0f;
|
||
|
||
// 上下键控制缩放
|
||
if (Input.GetKey(KeyCode.UpArrow)) zoomDelta = -1f; // 缩小(拉近)
|
||
if (Input.GetKey(KeyCode.DownArrow)) zoomDelta = 1f; // 放大(拉远)
|
||
|
||
// 触摸双指缩放
|
||
if (Input.touchCount == 2)
|
||
{
|
||
Touch touch0 = Input.GetTouch(0);
|
||
Touch touch1 = Input.GetTouch(1);
|
||
|
||
Vector2 touch0PrevPos = touch0.position - touch0.deltaPosition;
|
||
Vector2 touch1PrevPos = touch1.position - touch1.deltaPosition;
|
||
|
||
float prevMagnitude = (touch0PrevPos - touch1PrevPos).magnitude;
|
||
float currentMagnitude = (touch0.position - touch1.position).magnitude;
|
||
|
||
float difference = currentMagnitude - prevMagnitude;
|
||
zoomDelta = -difference * 0.01f; // 负号:手指分开=拉近,手指合拢=拉远
|
||
}
|
||
|
||
if (zoomDelta != 0f)
|
||
{
|
||
if (cam.orthographic)
|
||
{
|
||
// 正交相机:调整 orthographicSize
|
||
float newSize = cam.orthographicSize + zoomDelta * zoomSpeed * Time.deltaTime;
|
||
cam.orthographicSize = Mathf.Clamp(newSize, minOrthographicSize, maxOrthographicSize);
|
||
}
|
||
else
|
||
{
|
||
// 透视相机:调整 fieldOfView
|
||
float newFov = cam.fieldOfView + zoomDelta * zoomSpeed * Time.deltaTime;
|
||
cam.fieldOfView = Mathf.Clamp(newFov, minFieldOfView, maxFieldOfView);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void MoveCameraWithBounds(Vector3 movement)
|
||
{
|
||
Vector3 newPosition = transform.position + movement;
|
||
|
||
if (enableBounds)
|
||
{
|
||
newPosition.x = Mathf.Clamp(newPosition.x, minX, maxX);
|
||
newPosition.z = Mathf.Clamp(newPosition.z, minZ, maxZ);
|
||
}
|
||
|
||
transform.position = newPosition;
|
||
}
|
||
}
|