fix:代码提交
This commit is contained in:
237
Assets/Scripts/App/ControlMove.cs
Normal file
237
Assets/Scripts/App/ControlMove.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
public class ControlMove : MonoBehaviour
|
||||
{
|
||||
private float moveSpeed = 50f; // 右键平移速度
|
||||
|
||||
[Header("滚轮缩放速度系数")]
|
||||
public float zoomSpeed = 10f; // 滚轮缩放速度
|
||||
|
||||
[Header("相机与水库中心的最大距离")]
|
||||
public float maxDistance = 600f; // 最大缩放距离
|
||||
|
||||
[Header("相机的最大高度限制")]
|
||||
public float maxHeight = 220f; // 最大高度限制
|
||||
|
||||
[Header("右键平移速度衰减系数")]
|
||||
public float rightClickPanSpeed = 100f; // 右键平移速度除数
|
||||
|
||||
private Vector3 inScript; // 引用焦点脚本,提供 core
|
||||
|
||||
[Header("左键拖拽旋转灵敏度系数")]
|
||||
public float rotationSensitivity = 0.2f; // 左键拖拽旋转灵敏度
|
||||
|
||||
private Camera cam; // 主相机引用
|
||||
private bool isRotating = false; // 是否正在旋转标志
|
||||
private Vector2 lastMousePos; // 上次鼠标位置(用于旋转计算)
|
||||
|
||||
[Header("初始距离中心")]
|
||||
public Vector3 reservoirCenter; // 水库中心坐标
|
||||
|
||||
[Header("初始旋转中心")]
|
||||
public Vector3 startinScript; // 初始焦点位置
|
||||
|
||||
private Rigidbody rb; // 刚体组件(如需要物理模拟)
|
||||
private bool isCameraCtrl = true; // 相机是否可控制
|
||||
|
||||
//相机操作有效性判断
|
||||
private bool isClickUI = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
rb = GetComponent<Rigidbody>();
|
||||
cam = Camera.main;
|
||||
if (inScript == Vector3.zero)
|
||||
{
|
||||
GetInScriptCore();
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (isCameraCtrl)
|
||||
{
|
||||
//操作有效性判断
|
||||
if (EventSystem.current != null)
|
||||
{
|
||||
if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) || Input.GetMouseButtonDown(2))
|
||||
{
|
||||
isClickUI = EventSystem.current.IsPointerOverGameObject();
|
||||
}
|
||||
if (Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1) || Input.GetMouseButtonUp(2))
|
||||
{
|
||||
isClickUI = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isClickUI)
|
||||
{
|
||||
Vector3 core = inScript;
|
||||
// —— 右键平移 ——
|
||||
if (Input.GetMouseButton(1))
|
||||
{
|
||||
moveSpeed = Vector3.Distance(core, transform.position) / 2f;
|
||||
float mx = Input.GetAxis("Mouse X");
|
||||
float my = Input.GetAxis("Mouse Y");
|
||||
|
||||
// Vector3 desiredPosition = transform.position + (-transform.right * mx + -transform.up * my) * moveSpeed * Time.deltaTime;
|
||||
Vector3 desiredPosition = transform.position + (-transform.right * mx + -transform.up * my) * moveSpeed / rightClickPanSpeed;
|
||||
|
||||
// 判断是否与障碍物发生碰撞
|
||||
if (!WillCollideWithObstacle(desiredPosition))
|
||||
{
|
||||
// transform.position = Vector3.Lerp(transform.position, desiredPosition, moveSpeed * Time.deltaTime);
|
||||
transform.position = desiredPosition;
|
||||
}
|
||||
}
|
||||
|
||||
// —— 滚轮缩放 ——
|
||||
float scroll = Input.GetAxis("Mouse ScrollWheel");
|
||||
if (Mathf.Abs(scroll) > 0.001f)
|
||||
{
|
||||
Vector3 desiredPosition = transform.position + transform.forward * scroll * zoomSpeed;
|
||||
|
||||
// 判断是否与障碍物发生碰撞
|
||||
if (!WillCollideWithObstacle(desiredPosition))
|
||||
{
|
||||
transform.position = desiredPosition;
|
||||
}
|
||||
}
|
||||
|
||||
// —— 左键开始/结束旋转 ——
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
isRotating = true;
|
||||
lastMousePos = Input.mousePosition;
|
||||
}
|
||||
if (Input.GetMouseButtonUp(0))
|
||||
{
|
||||
isRotating = false;
|
||||
}
|
||||
|
||||
// —— 左键拖拽:RotateAround 实现 + 俯仰限制 ——
|
||||
if (isRotating && Input.GetMouseButton(0))
|
||||
{
|
||||
Vector2 curr = Input.mousePosition;
|
||||
Vector2 delta = (curr - lastMousePos) * rotationSensitivity;
|
||||
lastMousePos = curr;
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
// 1. 水平绕世界 Y 轴旋转
|
||||
//Vector3 desiredPosition = transform.position;
|
||||
//transform.RotateAround(core, Vector3.up, delta.x);
|
||||
|
||||
Vector3 localPosHorizonal = transform.position - core;
|
||||
Quaternion rotationHorizonal = Quaternion.AngleAxis(delta.x, Vector3.up);
|
||||
Vector3 newLocalPosHorizonal = rotationHorizonal * localPosHorizonal;
|
||||
Vector3 newPosHorizonal = core + newLocalPosHorizonal;
|
||||
|
||||
|
||||
// 检查旋转后是否发生碰撞
|
||||
if (!WillCollideWithObstacle(newPosHorizonal))
|
||||
{
|
||||
// 如果没有碰撞,执行旋转
|
||||
transform.RotateAround(core, Vector3.up, delta.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果碰撞了,撤销旋转,恢复到原来的位置
|
||||
|
||||
}
|
||||
|
||||
// 2. 俯仰旋转
|
||||
Vector3 dir = (transform.position - core).normalized;
|
||||
Vector3 flat = new Vector3(dir.x, 0f, dir.z).normalized;
|
||||
float selfFlatX = transform.forward.x;
|
||||
float selfFlatZ = transform.forward.z;
|
||||
Vector3 selfFlat = new Vector3(selfFlatX, 0f, selfFlatZ).normalized;
|
||||
float selfPitch = Vector3.SignedAngle(selfFlat, transform.forward, transform.right);
|
||||
|
||||
|
||||
|
||||
if (selfPitch <= 80f && selfPitch >= 0f)
|
||||
{
|
||||
|
||||
float pitchDelta = delta.y * -1f;
|
||||
|
||||
Vector3 localPosVertical = transform.position - core;
|
||||
Quaternion rotationVertical = Quaternion.AngleAxis(pitchDelta, transform.right);
|
||||
Vector3 newPosVertical = core + rotationVertical * localPosVertical;
|
||||
|
||||
|
||||
if (!WillCollideWithObstacle(newPosVertical))
|
||||
{
|
||||
transform.RotateAround(core, transform.right, pitchDelta);
|
||||
}
|
||||
|
||||
}
|
||||
else if (selfPitch > 80f)
|
||||
{
|
||||
float pitchDelta = delta.y * -1f;
|
||||
if (pitchDelta < 0f)
|
||||
{
|
||||
transform.RotateAround(core, transform.right, pitchDelta);
|
||||
}
|
||||
}
|
||||
else if (selfPitch < 0f)
|
||||
{
|
||||
float pitchDelta = delta.y * -1f;
|
||||
if (pitchDelta > 0f)
|
||||
{
|
||||
transform.RotateAround(core, transform.right, pitchDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 碰撞检测方法
|
||||
bool WillCollideWithObstacle(Vector3 targetPosition)
|
||||
{
|
||||
// 计算从当前位置到目标位置的方向和距离
|
||||
Vector3 moveDir = targetPosition - transform.position;
|
||||
float moveDist = moveDir.magnitude;
|
||||
|
||||
// 使用 SphereCast 检查即将到达的位置是否会与障碍物发生碰撞
|
||||
RaycastHit hit;
|
||||
if (Physics.SphereCast(transform.position, 0.5f, moveDir.normalized, out hit, moveDist, LayerMask.GetMask("Default"), QueryTriggerInteraction.Collide))
|
||||
{
|
||||
// 如果检测到碰撞,返回 true
|
||||
// Debug.Log("collider");
|
||||
return true;
|
||||
}
|
||||
else if (Vector3.Distance(targetPosition, reservoirCenter) < maxDistance && targetPosition.y < maxHeight)
|
||||
{
|
||||
// 如果在范围内,返回 false
|
||||
return false;
|
||||
}
|
||||
else
|
||||
// Debug.Log("outRange");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public void GetInScriptCore()
|
||||
{
|
||||
inScript = startinScript;
|
||||
}
|
||||
public void GetInScriptCore(Vector3 position)
|
||||
{
|
||||
inScript = position;
|
||||
}
|
||||
|
||||
public void StartCameraControl()
|
||||
{
|
||||
isCameraCtrl = true;
|
||||
isClickUI = false;
|
||||
}
|
||||
|
||||
//停止相机控制
|
||||
public void StopCameraControl()
|
||||
{
|
||||
isCameraCtrl = false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user