This commit is contained in:
李浩 2025-05-07 13:58:57 +08:00
commit 3d41210f5b
2 changed files with 94 additions and 93 deletions

View File

@ -1320,13 +1320,12 @@ MonoBehaviour:
rotateSpeed: 50 rotateSpeed: 50
moveSpeed: 0.15 moveSpeed: 0.15
distance: 2 distance: 2
distanceMin: 0.5 distanceMin: 0.1
distanceMax: 15 distanceMax: 15
pitchMinMax: {x: -80, y: 80} pitchMinMax: {x: -80, y: 80}
texture: {fileID: 8400000, guid: 187fba8368491cb428c8cbd324fa9bb4, type: 2} texture: {fileID: 8400000, guid: 187fba8368491cb428c8cbd324fa9bb4, type: 2}
lockMove: 0 lockMove: 0
type: 0 type: 0
zoomSmoothTime: 0.1
--- !u!1660057539 &9223372036854775807 --- !u!1660057539 &9223372036854775807
SceneRoots: SceneRoots:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -31,6 +31,8 @@ public class Show3DCamera : MonoBehaviour
private Vector2 mouseDownPosition; // 记录鼠标按下时的位置 private Vector2 mouseDownPosition; // 记录鼠标按下时的位置
private bool isDoubleTouching = false; // 记录双指操作状态
private bool isZooming = false; // 记录双指缩放状态
public enum RotationType public enum RotationType
{ {
@ -44,6 +46,10 @@ public class Show3DCamera : MonoBehaviour
Vector3 targetPosition; Vector3 targetPosition;
Vector3 targetRotate; Vector3 targetRotate;
private float prevTouchDistance; // 存储上一帧双指距离 private float prevTouchDistance; // 存储上一帧双指距离
// 新增:跟踪当前旋转状态
private Quaternion currentRotation;
private void Awake() private void Awake()
{ {
instance = this; instance = this;
@ -59,6 +65,7 @@ public class Show3DCamera : MonoBehaviour
gameObject.SetActive(false); gameObject.SetActive(false);
#endif #endif
} }
private void OnLockEvent(OnLock islock) private void OnLockEvent(OnLock islock)
{ {
this.lockMove = islock.isLock; this.lockMove = islock.isLock;
@ -77,16 +84,8 @@ public class Show3DCamera : MonoBehaviour
this.targetRotate = target.eulerAngles; this.targetRotate = target.eulerAngles;
yaw = 0; yaw = 0;
pitch = 0; pitch = 0;
// 初始化相机位置
this.inputRect = inputRect; this.inputRect = inputRect;
this.targetPos = target.transform.position; this.targetPos = target.transform.position;
//this.rotateSpeed = rotateSpeed;
//this.moveSpeed = moveSpeed;
//this.distance = distance;
//this.distanceMin = distanceMin;
//this.distanceMax = distanceMax;
//this.pitchMinMax = new Vector2(pitchMin, pitchMax);
// 初始化相机位置
offset = new Vector3(0, 0, -distance); offset = new Vector3(0, 0, -distance);
if (isRenderTexture) if (isRenderTexture)
@ -97,11 +96,12 @@ public class Show3DCamera : MonoBehaviour
{ {
self.targetTexture = null; self.targetTexture = null;
} }
// 初始化旋转状态
currentRotation = Quaternion.Euler(pitch, yaw, 0);
UpdateCameraPosition(moveTime); UpdateCameraPosition(moveTime);
} }
public void ResetCamera(Transform target, RectTransform inputRect = null, bool isRenderTexture = false) public void ResetCamera(Transform target, RectTransform inputRect = null, bool isRenderTexture = false)
{ {
if (target == null) if (target == null)
@ -114,10 +114,8 @@ public class Show3DCamera : MonoBehaviour
this.targetRotate = target.eulerAngles; this.targetRotate = target.eulerAngles;
yaw = 0; yaw = 0;
pitch = 0; pitch = 0;
// 初始化相机位置
this.inputRect = inputRect; this.inputRect = inputRect;
this.targetPos = target.transform.position; this.targetPos = target.transform.position;
// 初始化相机位置
offset = new Vector3(0, 0, -distance); offset = new Vector3(0, 0, -distance);
if (isRenderTexture) if (isRenderTexture)
@ -128,51 +126,76 @@ public class Show3DCamera : MonoBehaviour
{ {
self.targetTexture = null; self.targetTexture = null;
} }
// 重置旋转状态
currentRotation = Quaternion.Euler(pitch, yaw, 0);
UpdateCameraPosition(-1); UpdateCameraPosition(-1);
} }
void Update() void Update()
{ {
if (targetPos != null && lockMove == false && EventSystem.current.IsPointerOverGameObject() == false) if (targetPos != null && lockMove == false && EventSystem.current.IsPointerOverGameObject() == false)
{ {
// 优先处理三指操作 // 优先处理三指操作
if (HandleThreeFingerDrag()) return; if (HandleThreeFingerDrag()) return;
bool isTouching = Input.touchCount > 0; bool isTouching = Input.touchCount > 0;
// 新增:在旋转前先处理双指缩放 // 处理双指缩放
bool isZooming = false;
if (isTouching && Input.touchCount == 2) if (isTouching && Input.touchCount == 2)
{ {
HandleTouchZoom(); HandleTouchZoom();
isZooming = true; // 标记正在缩放 isZooming = true;
isDoubleTouching = true;
return;
}
else if (Input.touchCount == 0)
{
isDoubleTouching = false;
isZooming = false;
} }
bool shouldRotate = false;
// 处理触摸开始(排除双指情况) // 处理触摸开始(排除双指情况)
if (isTouching && Input.touchCount == 1) if (isTouching && Input.touchCount == 1 && !isDoubleTouching)
{ {
if (Input.GetTouch(0).phase == TouchPhase.Began) if (Input.GetTouch(0).phase == TouchPhase.Began)
{ {
mouseDownPosition = Input.GetTouch(0).position; mouseDownPosition = Input.GetTouch(0).position;
// 记录当前旋转状态
if (type == RotationType.Orbit)
{
currentRotation = Quaternion.Euler(pitch, yaw, 0);
}
}
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
float dragDistance = Vector2.Distance(Input.mousePosition, mouseDownPosition);
shouldRotate = dragDistance > DRAG_THRESHOLD;
} }
} }
// 处理鼠标按下 // 处理鼠标按下
else if (Input.GetMouseButtonDown(0)) else if (Input.GetMouseButtonDown(0) && !isDoubleTouching)
{ {
mouseDownPosition = Input.mousePosition; mouseDownPosition = Input.mousePosition;
// 记录当前旋转状态
if (type == RotationType.Orbit)
{
currentRotation = Quaternion.Euler(pitch, yaw, 0);
}
} }
bool shouldRotate = false; if (Input.GetMouseButton(0) && !isDoubleTouching)
if (Input.GetMouseButton(0))
{ {
// 使用现有参数计算拖拽距离
float dragDistance = Vector2.Distance(Input.mousePosition, mouseDownPosition); float dragDistance = Vector2.Distance(Input.mousePosition, mouseDownPosition);
shouldRotate = dragDistance > DRAG_THRESHOLD; shouldRotate = dragDistance > DRAG_THRESHOLD;
} }
// 修改后的旋转条件(排除缩放状态)
if (!isZooming && (isTouching ? (Input.GetTouch(0).phase == TouchPhase.Moved) : shouldRotate))
{
// 旋转相机
if (!isZooming && shouldRotate)
{
RotateCamera(); RotateCamera();
} }
@ -188,13 +211,15 @@ public class Show3DCamera : MonoBehaviour
{ {
MoveTarget(); MoveTarget();
} }
DetectHoveredObject(); DetectHoveredObject();
} }
} }
// 唯一的三指处理方法返回bool用于阻断其他操作 // 唯一的三指处理方法返回bool用于阻断其他操作
private bool HandleThreeFingerDrag() private bool HandleThreeFingerDrag()
{ {
if (Input.touchCount == 5) if (Input.touchCount == 3)
{ {
// 计算三个触点的平均移动量 // 计算三个触点的平均移动量
Vector2 totalDelta = Vector2.zero; Vector2 totalDelta = Vector2.zero;
@ -221,24 +246,13 @@ public class Show3DCamera : MonoBehaviour
return false; return false;
} }
// 双指缩放处理
// 新增双指缩放处理方法
// 类变量区添加
private float zoomSmoothVelocity; // 平滑速度缓存
[SerializeField] private float zoomSmoothTime = 0.1f; // 缩放平滑时间
private void HandleTouchZoom() private void HandleTouchZoom()
{ {
if (Input.touchCount == 2) if (Input.touchCount == 2)
{ {
Touch touch0 = Input.GetTouch(0); Touch touch0 = Input.GetTouch(0);
Touch touch1 = Input.GetTouch(1); Touch touch1 = Input.GetTouch(1);
// 当双指操作时重置旋转相关变量
if (touch0.phase == TouchPhase.Began || touch1.phase == TouchPhase.Began)
{
yaw = transform.eulerAngles.y; // 保持当前旋转角度
pitch = transform.eulerAngles.x;
mouseDownPosition = Vector2.zero;
}
Vector2 touch0Pos = touch0.position; Vector2 touch0Pos = touch0.position;
Vector2 touch1Pos = touch1.position; Vector2 touch1Pos = touch1.position;
@ -246,37 +260,26 @@ public class Show3DCamera : MonoBehaviour
// DPI自适应计算 // DPI自适应计算
float dpi = Screen.dpi == 0 ? 200 : Screen.dpi; float dpi = Screen.dpi == 0 ? 200 : Screen.dpi;
float zoomFactor = 0.01f * (200 / dpi); // 基准DPI为200 float zoomFactor = 0.01f * (200 / dpi);
if (touch0.phase == TouchPhase.Began || touch1.phase == TouchPhase.Began) if (touch0.phase == TouchPhase.Began || touch1.phase == TouchPhase.Began)
{ {
prevTouchDistance = currentDistance; prevTouchDistance = currentDistance;
zoomSmoothVelocity = 0; // 重置平滑速度
} }
else if (touch0.phase == TouchPhase.Moved || touch1.phase == TouchPhase.Moved) else if (touch0.phase == TouchPhase.Moved || touch1.phase == TouchPhase.Moved)
{ {
float deltaDistance = currentDistance - prevTouchDistance; float deltaDistance = currentDistance - prevTouchDistance;
// 添加判断:如果双指距离变化小于某个阈值,则不进行缩放操作
// 仅触摸缩放使用平滑 if (Mathf.Abs(deltaDistance) > 1f)
float targetDistance = distance - deltaDistance * zoomFactor; {
targetDistance = Mathf.Clamp(targetDistance, distanceMin, distanceMax); float scroll = deltaDistance * zoomFactor;
ZoomCamera(scroll);
distance = Mathf.SmoothDamp( }
distance,
targetDistance,
ref zoomSmoothVelocity,
zoomSmoothTime
);
offset = new Vector3(0, 0, -distance);
UpdateCameraPosition();
prevTouchDistance = currentDistance; prevTouchDistance = currentDistance;
} }
} }
} }
// 检测鼠标悬停的物体 // 检测鼠标悬停的物体
public void DetectHoveredObject() public void DetectHoveredObject()
{ {
@ -292,29 +295,21 @@ public class Show3DCamera : MonoBehaviour
RaycastHit raycastHit; RaycastHit raycastHit;
if (Physics.Raycast(ray, out raycastHit)) if (Physics.Raycast(ray, out raycastHit))
{ {
//Debug.Log(raycastHit.transform.name);
obj = raycastHit.transform.gameObject; obj = raycastHit.transform.gameObject;
// 如果击中的物体与上一次击中的物体不同,表示射线进入了新物体
if (obj != lastHitObject) if (obj != lastHitObject)
{ {
// 触发进入事件
OnMouseEnterObj(obj); OnMouseEnterObj(obj);
// 如果上一次击中的物体不为空,触发离开事件
if (lastHitObject != null && lastHitObject != obj) if (lastHitObject != null && lastHitObject != obj)
{ {
OnMouseExitObj(lastHitObject); OnMouseExitObj(lastHitObject);
// 更新上一次击中的物体
lastHitObject = obj; lastHitObject = obj;
} }
} }
} }
else else
{ {
// 如果射线没有击中任何物体,且上一次击中的物体不为空,触发离开事件
if (lastHitObject != null) if (lastHitObject != null)
{ {
OnMouseExitObj(lastHitObject); OnMouseExitObj(lastHitObject);
@ -323,13 +318,11 @@ public class Show3DCamera : MonoBehaviour
} }
} }
/// <summary> /// <summary>
/// 聚焦某个物体 /// 聚焦某个物体
/// </summary> /// </summary>
public void FocusObj(Vector3 target, float distance = 1f, float moveTime = -1) public void FocusObj(Vector3 target, float distance = 1f, float moveTime = -1)
{ {
// 可以根据需要调整这个距离
Vector3 cameraPos = target - transform.forward * distance; Vector3 cameraPos = target - transform.forward * distance;
targetPos = target; targetPos = target;
@ -361,13 +354,11 @@ public class Show3DCamera : MonoBehaviour
{ {
tip.OnExit(); tip.OnExit();
} }
} }
// 修改后的移动方法(统一处理输入源) // 修改后的移动方法(统一处理输入源)
private void MoveTarget(float mouseX = 0, float mouseY = 0) private void MoveTarget(float mouseX = 0, float mouseY = 0)
{ {
// 自动判断输入源
if (Mathf.Approximately(mouseX, 0) && Mathf.Approximately(mouseY, 0)) if (Mathf.Approximately(mouseX, 0) && Mathf.Approximately(mouseY, 0))
{ {
mouseX = Input.GetAxis("Mouse X") * moveSpeed; mouseX = Input.GetAxis("Mouse X") * moveSpeed;
@ -377,11 +368,12 @@ public class Show3DCamera : MonoBehaviour
transform.Translate(new Vector3(-mouseX, -mouseY, 0)); transform.Translate(new Vector3(-mouseX, -mouseY, 0));
targetPos += new Vector3(-mouseX, -mouseY, 0); targetPos += new Vector3(-mouseX, -mouseY, 0);
} }
// 缩放相机 // 缩放相机
private void ZoomCamera(float scroll) private void ZoomCamera(float scroll)
{ {
distance -= scroll * 5f; // 调整缩放速度 distance -= scroll * 5f;
distance = Mathf.Clamp(distance, distanceMin, distanceMax); // 限制距离范围 distance = Mathf.Clamp(distance, distanceMin, distanceMax);
offset = new Vector3(0, 0, -distance); offset = new Vector3(0, 0, -distance);
UpdateCameraPosition(); UpdateCameraPosition();
} }
@ -389,7 +381,6 @@ public class Show3DCamera : MonoBehaviour
// 修改RotateCamera方法 // 修改RotateCamera方法
private void RotateCamera() private void RotateCamera()
{ {
// 优先使用触摸输入
float deltaX = 0, deltaY = 0; float deltaX = 0, deltaY = 0;
// 触屏处理 // 触屏处理
@ -402,14 +393,13 @@ public class Show3DCamera : MonoBehaviour
// 鼠标处理 // 鼠标处理
else else
{ {
deltaX = Input.GetAxis("Mouse X") * 10; // 保持原有灵敏度 deltaX = Input.GetAxis("Mouse X") * 10;
deltaY = Input.GetAxis("Mouse Y") * 10; deltaY = Input.GetAxis("Mouse Y") * 10;
// 当累计移动量超过阈值时才生效
if (Mathf.Abs(deltaX) < DRAG_THRESHOLD && Mathf.Abs(deltaY) < DRAG_THRESHOLD) if (Mathf.Abs(deltaX) < DRAG_THRESHOLD && Mathf.Abs(deltaY) < DRAG_THRESHOLD)
return; return;
} }
// 应用DPI缩放(关键!) // 应用DPI缩放
float dpiScale = Screen.dpi == 0 ? 1 : Screen.dpi / 160f; float dpiScale = Screen.dpi == 0 ? 1 : Screen.dpi / 160f;
deltaX *= rotateSpeed * Time.deltaTime / dpiScale; deltaX *= rotateSpeed * Time.deltaTime / dpiScale;
deltaY *= rotateSpeed * Time.deltaTime / dpiScale; deltaY *= rotateSpeed * Time.deltaTime / dpiScale;
@ -440,24 +430,36 @@ public class Show3DCamera : MonoBehaviour
// 更新相机位置和朝向 // 更新相机位置和朝向
private void UpdateCameraPosition(float moveTime = -1) private void UpdateCameraPosition(float moveTime = -1)
{ {
// 计算旋转后的偏移量 if (type == RotationType.Orbit)
Quaternion rotation = Quaternion.Euler(pitch, yaw, 0);
Vector3 rotatedOffset = rotation * offset;
// 更新相机位置
if (moveTime != -1)
{ {
transform.DOMove(targetPos + rotatedOffset, moveTime).onUpdate = () => // 使用四元数计算旋转后的偏移量
// 相机始终朝向目标点 Quaternion rotation = Quaternion.Euler(pitch, yaw, 0);
transform.LookAt(targetPos); Vector3 rotatedOffset = rotation * offset;
}
else
{
transform.position = targetPos + rotatedOffset;
// 相机始终朝向目标点
transform.LookAt(targetPos);
}
if (moveTime != -1)
{
transform.DOMove(targetPos + rotatedOffset, moveTime).onUpdate = () =>
transform.LookAt(targetPos);
}
else
{
transform.position = targetPos + rotatedOffset;
transform.LookAt(targetPos);
}
}
else if (type == RotationType.Spherical)
{
// 球形模式下的相机跟随
if (moveTime != -1)
{
transform.DOMove(targetPos + offset, moveTime).onUpdate = () =>
transform.LookAt(targetPos);
}
else
{
transform.position = targetPos + offset;
transform.LookAt(targetPos);
}
}
} }
} }