2025-02-14 13:20:54 +08:00
|
|
|
|
using DG.Tweening;
|
2025-03-25 13:23:47 +08:00
|
|
|
|
using QFramework;
|
|
|
|
|
|
using System;
|
2025-02-08 16:22:00 +08:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.EventSystems;
|
|
|
|
|
|
|
|
|
|
|
|
public class Show3DCamera : MonoBehaviour
|
|
|
|
|
|
{
|
2025-02-10 10:54:47 +08:00
|
|
|
|
public Vector3 targetPos; // Χ<><CEA7><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>
|
2025-03-17 17:21:06 +08:00
|
|
|
|
public float rotateSpeed; // <20><>ת<EFBFBD>ٶ<EFBFBD>
|
2025-03-11 13:04:58 +08:00
|
|
|
|
public float moveSpeed; // <20>ƶ<EFBFBD><C6B6>ٶ<EFBFBD>
|
|
|
|
|
|
public float distance; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD>
|
2025-03-17 17:21:06 +08:00
|
|
|
|
public float distanceMin;
|
|
|
|
|
|
public float distanceMax;
|
2025-03-11 13:04:58 +08:00
|
|
|
|
public Vector2 pitchMinMax/* = new Vector2(-20, 80)*/; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Χ
|
2025-02-08 16:22:00 +08:00
|
|
|
|
|
|
|
|
|
|
private Vector3 offset; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
|
|
|
|
|
|
private float yaw = 0f; // ƫ<><C6AB><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
|
|
|
|
|
|
private float pitch = 0f; // <20><><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
|
|
|
|
|
|
|
|
|
|
|
|
public static Show3DCamera instance;
|
|
|
|
|
|
|
2025-02-10 10:54:47 +08:00
|
|
|
|
RectTransform inputRect;
|
2025-02-08 16:22:00 +08:00
|
|
|
|
Camera self;
|
|
|
|
|
|
|
2025-02-10 10:54:47 +08:00
|
|
|
|
private GameObject lastHitObject = null;
|
|
|
|
|
|
|
2025-02-13 17:21:18 +08:00
|
|
|
|
public RenderTexture texture;
|
|
|
|
|
|
public bool lockMove = false;
|
2025-03-26 16:27:45 +08:00
|
|
|
|
private const float DRAG_THRESHOLD = 1f; // <20><>ק<EFBFBD><D7A7>ֵ
|
2025-02-14 13:20:54 +08:00
|
|
|
|
|
|
|
|
|
|
private Vector2 mouseDownPosition; // <20><>¼<EFBFBD><C2BC><EFBFBD>갴<EFBFBD><EAB0B4>ʱ<EFBFBD><CAB1>λ<EFBFBD><CEBB>
|
|
|
|
|
|
|
2025-05-07 11:51:21 +08:00
|
|
|
|
private bool isDoubleTouching = false; // <20><>¼˫ָ<CBAB><D6B8><EFBFBD><EFBFBD>״̬
|
|
|
|
|
|
private bool isZooming = false; // <20><>¼˫ָ<CBAB><D6B8><EFBFBD><EFBFBD>״̬
|
2025-03-17 17:21:06 +08:00
|
|
|
|
|
|
|
|
|
|
public enum RotationType
|
|
|
|
|
|
{
|
|
|
|
|
|
Orbit, // ԭ<><D4AD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD>ת
|
|
|
|
|
|
Spherical // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public RotationType type = RotationType.Orbit;
|
|
|
|
|
|
|
|
|
|
|
|
Transform target;
|
|
|
|
|
|
Vector3 targetPosition;
|
|
|
|
|
|
Vector3 targetRotate;
|
2025-03-25 15:22:32 +08:00
|
|
|
|
private float prevTouchDistance; // <20>洢<EFBFBD><E6B4A2>һ֡˫ָ<CBAB><D6B8><EFBFBD><EFBFBD>
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٵ<EFBFBD>ǰ<EFBFBD><C7B0>ת״̬
|
|
|
|
|
|
private Quaternion currentRotation;
|
|
|
|
|
|
|
2025-02-08 16:22:00 +08:00
|
|
|
|
private void Awake()
|
|
|
|
|
|
{
|
|
|
|
|
|
instance = this;
|
|
|
|
|
|
self = transform.GetComponent<Camera>();
|
|
|
|
|
|
DontDestroyOnLoad(this);
|
2025-02-08 17:33:21 +08:00
|
|
|
|
gameObject.SetActive(false);
|
2025-03-25 13:23:47 +08:00
|
|
|
|
TypeEventSystem.Global.Register<OnLock>(OnLockEvent).UnRegisterWhenDisabled(this);
|
2025-02-08 16:22:00 +08:00
|
|
|
|
}
|
2025-02-13 17:21:18 +08:00
|
|
|
|
|
2025-03-26 11:39:49 +08:00
|
|
|
|
private void OnEnable()
|
|
|
|
|
|
{
|
|
|
|
|
|
#if Turing
|
|
|
|
|
|
gameObject.SetActive(false);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
2025-03-25 13:23:47 +08:00
|
|
|
|
private void OnLockEvent(OnLock islock)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.lockMove = islock.isLock;
|
|
|
|
|
|
}
|
2025-02-13 17:21:18 +08:00
|
|
|
|
|
2025-02-14 13:20:54 +08:00
|
|
|
|
public void Set(Transform target, float rotateSpeed = 10, float moveSpeed = 0.1f, float distance = 0.1f, float pitchMin = -20, float pitchMax = 80, float distanceMin = 0.2f, float distanceMax = 20f, RectTransform inputRect = null, bool isRenderTexture = true, float moveTime = -1)
|
2025-02-08 16:22:00 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (target == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError("Target is not assigned!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-02-10 10:54:47 +08:00
|
|
|
|
|
2025-03-17 17:21:06 +08:00
|
|
|
|
this.target = target;
|
|
|
|
|
|
this.targetPosition = target.position;
|
|
|
|
|
|
this.targetRotate = target.eulerAngles;
|
2025-02-08 16:22:00 +08:00
|
|
|
|
yaw = 0;
|
|
|
|
|
|
pitch = 0;
|
2025-02-10 10:54:47 +08:00
|
|
|
|
this.inputRect = inputRect;
|
|
|
|
|
|
this.targetPos = target.transform.position;
|
2025-02-08 16:22:00 +08:00
|
|
|
|
offset = new Vector3(0, 0, -distance);
|
2025-02-13 17:21:18 +08:00
|
|
|
|
|
|
|
|
|
|
if (isRenderTexture)
|
|
|
|
|
|
{
|
|
|
|
|
|
self.targetTexture = texture;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
self.targetTexture = null;
|
|
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ת״̬
|
|
|
|
|
|
currentRotation = Quaternion.Euler(pitch, yaw, 0);
|
2025-02-14 13:20:54 +08:00
|
|
|
|
UpdateCameraPosition(moveTime);
|
2025-02-08 16:22:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-11 14:37:17 +08:00
|
|
|
|
public void ResetCamera(Transform target, RectTransform inputRect = null, bool isRenderTexture = false)
|
2025-03-11 13:59:38 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (target == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError("Target is not assigned!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-03-17 17:21:06 +08:00
|
|
|
|
this.target = target;
|
|
|
|
|
|
this.targetPosition = target.position;
|
|
|
|
|
|
this.targetRotate = target.eulerAngles;
|
2025-03-11 13:59:38 +08:00
|
|
|
|
yaw = 0;
|
|
|
|
|
|
pitch = 0;
|
|
|
|
|
|
this.inputRect = inputRect;
|
|
|
|
|
|
this.targetPos = target.transform.position;
|
|
|
|
|
|
offset = new Vector3(0, 0, -distance);
|
|
|
|
|
|
|
|
|
|
|
|
if (isRenderTexture)
|
|
|
|
|
|
{
|
|
|
|
|
|
self.targetTexture = texture;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
self.targetTexture = null;
|
|
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת״̬
|
|
|
|
|
|
currentRotation = Quaternion.Euler(pitch, yaw, 0);
|
2025-03-11 13:59:38 +08:00
|
|
|
|
UpdateCameraPosition(-1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-08 16:22:00 +08:00
|
|
|
|
void Update()
|
|
|
|
|
|
{
|
2025-02-14 13:20:54 +08:00
|
|
|
|
if (targetPos != null && lockMove == false && EventSystem.current.IsPointerOverGameObject() == false)
|
2025-02-08 16:22:00 +08:00
|
|
|
|
{
|
2025-03-25 15:22:32 +08:00
|
|
|
|
// <20><><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (HandleThreeFingerDrag()) return;
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
2025-03-25 15:22:32 +08:00
|
|
|
|
bool isTouching = Input.touchCount > 0;
|
2025-03-17 17:21:06 +08:00
|
|
|
|
|
2025-05-07 11:51:21 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>˫ָ<CBAB><D6B8><EFBFBD><EFBFBD>
|
2025-03-25 15:22:32 +08:00
|
|
|
|
if (isTouching && Input.touchCount == 2)
|
2025-02-14 13:20:54 +08:00
|
|
|
|
{
|
2025-03-25 15:22:32 +08:00
|
|
|
|
HandleTouchZoom();
|
2025-05-07 11:51:21 +08:00
|
|
|
|
isZooming = true;
|
|
|
|
|
|
isDoubleTouching = true;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (Input.touchCount == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
isDoubleTouching = false;
|
|
|
|
|
|
isZooming = false;
|
2025-02-14 13:20:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 11:51:21 +08:00
|
|
|
|
bool shouldRotate = false;
|
2025-03-25 15:22:32 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ų<EFBFBD>˫ָ<CBAB><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2025-05-07 11:51:21 +08:00
|
|
|
|
if (isTouching && Input.touchCount == 1 && !isDoubleTouching)
|
2025-02-08 16:22:00 +08:00
|
|
|
|
{
|
2025-03-25 15:22:32 +08:00
|
|
|
|
if (Input.GetTouch(0).phase == TouchPhase.Began)
|
2025-02-14 13:20:54 +08:00
|
|
|
|
{
|
2025-03-25 15:22:32 +08:00
|
|
|
|
mouseDownPosition = Input.GetTouch(0).position;
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><>¼<EFBFBD><C2BC>ǰ<EFBFBD><C7B0>ת״̬
|
|
|
|
|
|
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;
|
2025-02-14 13:20:54 +08:00
|
|
|
|
}
|
2025-02-08 16:22:00 +08:00
|
|
|
|
}
|
2025-03-25 15:22:32 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>갴<EFBFBD><EAB0B4>
|
2025-05-07 11:51:21 +08:00
|
|
|
|
else if (Input.GetMouseButtonDown(0) && !isDoubleTouching)
|
2025-03-25 15:22:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
mouseDownPosition = Input.mousePosition;
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><>¼<EFBFBD><C2BC>ǰ<EFBFBD><C7B0>ת״̬
|
|
|
|
|
|
if (type == RotationType.Orbit)
|
|
|
|
|
|
{
|
|
|
|
|
|
currentRotation = Quaternion.Euler(pitch, yaw, 0);
|
|
|
|
|
|
}
|
2025-03-25 15:22:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 11:51:21 +08:00
|
|
|
|
if (Input.GetMouseButton(0) && !isDoubleTouching)
|
2025-03-26 16:27:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
float dragDistance = Vector2.Distance(Input.mousePosition, mouseDownPosition);
|
|
|
|
|
|
shouldRotate = dragDistance > DRAG_THRESHOLD;
|
|
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (!isZooming && shouldRotate)
|
2025-03-25 15:22:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
RotateCamera();
|
|
|
|
|
|
}
|
2025-02-08 16:22:00 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
float scroll = Input.GetAxis("Mouse ScrollWheel");
|
|
|
|
|
|
if (scroll != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
ZoomCamera(scroll);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>ס<EFBFBD><D7A1><EFBFBD><EFBFBD><EFBFBD>Ҽ<EFBFBD>ʱ<EFBFBD>ƶ<EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (Input.GetMouseButton(1))
|
|
|
|
|
|
{
|
|
|
|
|
|
MoveTarget();
|
|
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
2025-02-08 16:22:00 +08:00
|
|
|
|
DetectHoveredObject();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
2025-03-25 15:22:32 +08:00
|
|
|
|
// Ψһ<CEA8><D2BB><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bool<6F><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
private bool HandleThreeFingerDrag()
|
|
|
|
|
|
{
|
2025-05-07 11:51:21 +08:00
|
|
|
|
if (Input.touchCount == 3)
|
2025-03-25 15:22:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>
|
|
|
|
|
|
Vector2 totalDelta = Vector2.zero;
|
|
|
|
|
|
foreach (Touch t in Input.touches)
|
|
|
|
|
|
{
|
|
|
|
|
|
totalDelta += t.deltaPosition;
|
|
|
|
|
|
}
|
|
|
|
|
|
Vector2 delta = totalDelta / 3f;
|
|
|
|
|
|
|
|
|
|
|
|
// DPI<50><49><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
|
|
|
|
|
|
float dpiScale = Screen.dpi == 0 ? 1 : Screen.dpi / 160f;
|
|
|
|
|
|
float sensitivity = moveSpeed * 0.1f / dpiScale;
|
|
|
|
|
|
|
|
|
|
|
|
// Ӧ<><D3A6><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>ֵ<EFBFBD><D6B5>2<EFBFBD><32><EFBFBD>أ<EFBFBD>
|
|
|
|
|
|
if (delta.magnitude > 2f)
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ĺ<DEB8><C4BA><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
MoveTarget(delta.x * sensitivity, delta.y * sensitivity);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 11:51:21 +08:00
|
|
|
|
// ˫ָ<CBAB><D6B8><EFBFBD>Ŵ<EFBFBD><C5B4><EFBFBD>
|
2025-03-25 15:22:32 +08:00
|
|
|
|
private void HandleTouchZoom()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Input.touchCount == 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
Touch touch0 = Input.GetTouch(0);
|
|
|
|
|
|
Touch touch1 = Input.GetTouch(1);
|
|
|
|
|
|
|
|
|
|
|
|
Vector2 touch0Pos = touch0.position;
|
|
|
|
|
|
Vector2 touch1Pos = touch1.position;
|
|
|
|
|
|
float currentDistance = Vector2.Distance(touch0Pos, touch1Pos);
|
|
|
|
|
|
|
|
|
|
|
|
// DPI<50><49><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
|
|
|
|
|
|
float dpi = Screen.dpi == 0 ? 200 : Screen.dpi;
|
2025-05-07 11:51:21 +08:00
|
|
|
|
float zoomFactor = 0.01f * (200 / dpi);
|
2025-03-25 15:22:32 +08:00
|
|
|
|
|
|
|
|
|
|
if (touch0.phase == TouchPhase.Began || touch1.phase == TouchPhase.Began)
|
|
|
|
|
|
{
|
|
|
|
|
|
prevTouchDistance = currentDistance;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (touch0.phase == TouchPhase.Moved || touch1.phase == TouchPhase.Moved)
|
|
|
|
|
|
{
|
|
|
|
|
|
float deltaDistance = currentDistance - prevTouchDistance;
|
2025-05-07 11:51:21 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>жϣ<D0B6><CFA3><EFBFBD><EFBFBD><EFBFBD>˫ָ<CBAB><D6B8><EFBFBD><EFBFBD><EFBFBD>仯С<E4BBAF><D0A1>ij<EFBFBD><C4B3><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><F2B2BBBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD><C5B2><EFBFBD>
|
|
|
|
|
|
if (Mathf.Abs(deltaDistance) > 1f)
|
|
|
|
|
|
{
|
|
|
|
|
|
float scroll = deltaDistance * zoomFactor;
|
|
|
|
|
|
ZoomCamera(scroll);
|
|
|
|
|
|
}
|
2025-03-25 15:22:32 +08:00
|
|
|
|
prevTouchDistance = currentDistance;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-08 16:22:00 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2025-02-10 10:54:47 +08:00
|
|
|
|
public void DetectHoveredObject()
|
2025-02-08 16:22:00 +08:00
|
|
|
|
{
|
2025-02-10 10:54:47 +08:00
|
|
|
|
GameObject obj = null;
|
|
|
|
|
|
Vector2 mousePosition = Input.mousePosition;
|
|
|
|
|
|
if (inputRect != null)
|
2025-02-08 16:22:00 +08:00
|
|
|
|
{
|
2025-02-10 10:54:47 +08:00
|
|
|
|
var pos = (mousePosition - (Vector2)inputRect.position) / inputRect.lossyScale - inputRect.rect.position;
|
|
|
|
|
|
mousePosition = pos / inputRect.rect.size;
|
2025-02-08 16:22:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-10 10:54:47 +08:00
|
|
|
|
var ray = self.ViewportPointToRay(mousePosition);
|
|
|
|
|
|
RaycastHit raycastHit;
|
|
|
|
|
|
if (Physics.Raycast(ray, out raycastHit))
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = raycastHit.transform.gameObject;
|
2025-02-08 16:22:00 +08:00
|
|
|
|
|
2025-02-10 10:54:47 +08:00
|
|
|
|
if (obj != lastHitObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnMouseEnterObj(obj);
|
2025-02-08 16:22:00 +08:00
|
|
|
|
|
2025-02-10 10:54:47 +08:00
|
|
|
|
if (lastHitObject != null && lastHitObject != obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnMouseExitObj(lastHitObject);
|
|
|
|
|
|
lastHitObject = obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (lastHitObject != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnMouseExitObj(lastHitObject);
|
|
|
|
|
|
lastHitObject = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-02-08 16:22:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-14 13:20:54 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// <20>۽<EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
/// </summary>
|
2025-02-14 17:09:41 +08:00
|
|
|
|
public void FocusObj(Vector3 target, float distance = 1f, float moveTime = -1)
|
2025-02-14 13:20:54 +08:00
|
|
|
|
{
|
|
|
|
|
|
Vector3 cameraPos = target - transform.forward * distance;
|
|
|
|
|
|
|
|
|
|
|
|
targetPos = target;
|
|
|
|
|
|
this.distance = distance;
|
|
|
|
|
|
offset = new Vector3(0, 0, -distance);
|
2025-02-17 15:14:40 +08:00
|
|
|
|
if (moveTime != -1)
|
2025-02-14 17:09:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
transform.DOMove(cameraPos, moveTime);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.position = cameraPos;
|
|
|
|
|
|
}
|
2025-02-14 13:20:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-10 10:54:47 +08:00
|
|
|
|
public void OnMouseEnterObj(GameObject obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
TipItem tip = obj.GetComponent<TipItem>();
|
|
|
|
|
|
if (tip != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
tip.OnEnter();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void OnMouseExitObj(GameObject obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
TipItem tip = obj.GetComponent<TipItem>();
|
|
|
|
|
|
if (tip != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
tip.OnExit();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-25 15:22:32 +08:00
|
|
|
|
// <20>ĺ<DEB8><C4BA><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>
|
|
|
|
|
|
private void MoveTarget(float mouseX = 0, float mouseY = 0)
|
2025-02-08 16:22:00 +08:00
|
|
|
|
{
|
2025-03-25 15:22:32 +08:00
|
|
|
|
if (Mathf.Approximately(mouseX, 0) && Mathf.Approximately(mouseY, 0))
|
|
|
|
|
|
{
|
|
|
|
|
|
mouseX = Input.GetAxis("Mouse X") * moveSpeed;
|
|
|
|
|
|
mouseY = Input.GetAxis("Mouse Y") * moveSpeed;
|
|
|
|
|
|
}
|
2025-02-08 16:22:00 +08:00
|
|
|
|
|
|
|
|
|
|
transform.Translate(new Vector3(-mouseX, -mouseY, 0));
|
2025-02-17 15:14:40 +08:00
|
|
|
|
targetPos += new Vector3(-mouseX, -mouseY, 0);
|
2025-02-08 16:22:00 +08:00
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
|
2025-02-08 16:22:00 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
private void ZoomCamera(float scroll)
|
|
|
|
|
|
{
|
2025-05-07 11:51:21 +08:00
|
|
|
|
distance -= scroll * 5f;
|
|
|
|
|
|
distance = Mathf.Clamp(distance, distanceMin, distanceMax);
|
2025-02-08 16:22:00 +08:00
|
|
|
|
offset = new Vector3(0, 0, -distance);
|
|
|
|
|
|
UpdateCameraPosition();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-25 15:22:32 +08:00
|
|
|
|
// <20><EFBFBD>RotateCamera<72><61><EFBFBD><EFBFBD>
|
2025-02-08 16:22:00 +08:00
|
|
|
|
private void RotateCamera()
|
|
|
|
|
|
{
|
2025-03-25 15:22:32 +08:00
|
|
|
|
float deltaX = 0, deltaY = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (Input.touchCount == 1)
|
2025-03-17 17:21:06 +08:00
|
|
|
|
{
|
2025-03-25 15:22:32 +08:00
|
|
|
|
Touch touch = Input.GetTouch(0);
|
|
|
|
|
|
deltaX = touch.deltaPosition.x;
|
|
|
|
|
|
deltaY = touch.deltaPosition.y;
|
|
|
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD>괦<EFBFBD><EAB4A6>
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-05-07 11:51:21 +08:00
|
|
|
|
deltaX = Input.GetAxis("Mouse X") * 10;
|
2025-03-25 15:22:32 +08:00
|
|
|
|
deltaY = Input.GetAxis("Mouse Y") * 10;
|
2025-03-26 16:27:45 +08:00
|
|
|
|
if (Mathf.Abs(deltaX) < DRAG_THRESHOLD && Mathf.Abs(deltaY) < DRAG_THRESHOLD)
|
|
|
|
|
|
return;
|
2025-03-25 15:22:32 +08:00
|
|
|
|
}
|
2025-03-17 17:21:06 +08:00
|
|
|
|
|
2025-05-07 11:51:21 +08:00
|
|
|
|
// Ӧ<><D3A6>DPI<50><49><EFBFBD><EFBFBD>
|
2025-03-25 15:22:32 +08:00
|
|
|
|
float dpiScale = Screen.dpi == 0 ? 1 : Screen.dpi / 160f;
|
|
|
|
|
|
deltaX *= rotateSpeed * Time.deltaTime / dpiScale;
|
|
|
|
|
|
deltaY *= rotateSpeed * Time.deltaTime / dpiScale;
|
2025-03-17 17:21:06 +08:00
|
|
|
|
|
2025-03-25 15:22:32 +08:00
|
|
|
|
switch (type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case RotationType.Orbit:
|
|
|
|
|
|
yaw += deltaX;
|
|
|
|
|
|
pitch -= deltaY;
|
|
|
|
|
|
pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y);
|
2025-03-17 17:21:06 +08:00
|
|
|
|
UpdateCameraPosition();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RotationType.Spherical:
|
2025-03-25 15:22:32 +08:00
|
|
|
|
target.Rotate(Vector3.up, deltaX, Space.World);
|
|
|
|
|
|
target.Rotate(Vector3.right, -deltaY, Space.Self);
|
2025-03-17 17:21:06 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-02-08 16:22:00 +08:00
|
|
|
|
|
2025-03-17 17:21:06 +08:00
|
|
|
|
public void ChangeMode(RotationType type)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.type = type;
|
|
|
|
|
|
target.position = targetPosition;
|
|
|
|
|
|
target.eulerAngles = targetRotate;
|
|
|
|
|
|
ResetCamera(this.target);
|
2025-02-08 16:22:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>úͳ<C3BA><CDB3><EFBFBD>
|
2025-02-14 13:20:54 +08:00
|
|
|
|
private void UpdateCameraPosition(float moveTime = -1)
|
2025-02-08 16:22:00 +08:00
|
|
|
|
{
|
2025-05-07 11:51:21 +08:00
|
|
|
|
if (type == RotationType.Orbit)
|
2025-02-14 13:20:54 +08:00
|
|
|
|
{
|
2025-05-07 11:51:21 +08:00
|
|
|
|
// ʹ<><CAB9><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
|
|
|
|
|
|
Quaternion rotation = Quaternion.Euler(pitch, yaw, 0);
|
|
|
|
|
|
Vector3 rotatedOffset = rotation * offset;
|
|
|
|
|
|
|
|
|
|
|
|
if (moveTime != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.DOMove(targetPos + rotatedOffset, moveTime).onUpdate = () =>
|
|
|
|
|
|
transform.LookAt(targetPos);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.position = targetPos + rotatedOffset;
|
|
|
|
|
|
transform.LookAt(targetPos);
|
|
|
|
|
|
}
|
2025-02-14 13:20:54 +08:00
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
else if (type == RotationType.Spherical)
|
2025-02-14 13:20:54 +08:00
|
|
|
|
{
|
2025-05-07 11:51:21 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>ģʽ<C4A3>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (moveTime != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.DOMove(targetPos + offset, moveTime).onUpdate = () =>
|
|
|
|
|
|
transform.LookAt(targetPos);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.position = targetPos + offset;
|
|
|
|
|
|
transform.LookAt(targetPos);
|
|
|
|
|
|
}
|
2025-02-14 13:20:54 +08:00
|
|
|
|
}
|
2025-02-08 16:22:00 +08:00
|
|
|
|
}
|
2025-05-07 11:51:21 +08:00
|
|
|
|
}
|