257 lines
7.1 KiB
C#
Raw Normal View History

2025-02-14 13:20:54 +08:00
using DG.Tweening;
2025-02-10 10:54:47 +08:00
using GCSeries.Core;
using System;
using Unity.Burst.CompilerServices;
2025-02-08 16:22:00 +08:00
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
2025-02-10 10:54:47 +08:00
using UnityEngine.UIElements;
2025-02-08 16:22:00 +08:00
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-02-08 16:22:00 +08:00
public float rotateSpeed = 10f; // <20><>ת<EFBFBD>ٶ<EFBFBD>
public float moveSpeed = 10f; // <20>ƶ<EFBFBD><C6B6>ٶ<EFBFBD>
public float distance = 10f; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD>
2025-02-10 10:54:47 +08:00
public float distanceMin = 0.2f;
public float distanceMax = 20f;
2025-02-08 16:22:00 +08:00
public Vector2 pitchMinMax = new Vector2(-20, 80); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Χ
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;
public RenderTexture texture;
public bool lockMove = false;
2025-02-14 13:20:54 +08:00
private Vector2 mouseDownPosition; // <20><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EAB0B4>ʱ<EFBFBD><CAB1>λ<EFBFBD><CEBB>
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-02-08 16:22:00 +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-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
this.rotateSpeed = rotateSpeed;
this.moveSpeed = moveSpeed;
this.distance = distance;
2025-02-10 10:54:47 +08:00
this.distanceMin = distanceMin;
this.distanceMax = distanceMax;
2025-02-08 16:22:00 +08:00
this.pitchMinMax = new Vector2(pitchMin, pitchMax);
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
offset = new Vector3(0, 0, -distance);
if (isRenderTexture)
{
self.targetTexture = texture;
}
else
{
self.targetTexture = null;
}
2025-02-14 13:20:54 +08:00
UpdateCameraPosition(moveTime);
2025-02-08 16:22:00 +08:00
}
2025-02-10 10:54:47 +08:00
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-02-14 13:20:54 +08:00
if (Input.GetMouseButtonDown(0))
{
// <20><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EAB0B4>ʱ<EFBFBD><CAB1>λ<EFBFBD><CEBB>
mouseDownPosition = Input.mousePosition;
}
2025-02-08 16:22:00 +08:00
// <20><>ס<EFBFBD><D7A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
if (Input.GetMouseButton(0))
{
2025-02-14 13:20:54 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>º<EFBFBD>̧<EFBFBD><CCA7>λ<EFBFBD><CEBB>֮<EFBFBD><D6AE><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD>
float distance = Vector2.Distance(mouseDownPosition, Input.mousePosition);
if (distance > 1f)
{
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();
}
DetectHoveredObject();
}
}
// <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))
{
//Debug.Log(raycastHit.transform.name);
obj = raycastHit.transform.gameObject;
2025-02-08 16:22:00 +08:00
2025-02-10 10:54:47 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD><CEBB>е<EFBFBD><D0B5><EFBFBD><EFBFBD>岻ͬ<E5B2BB><CDAC><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (obj != lastHitObject)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
OnMouseEnterObj(obj);
2025-02-08 16:22:00 +08:00
2025-02-10 10:54:47 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD><CEBB>е<EFBFBD><D0B5><EFBFBD><EFBFBD>岻Ϊ<E5B2BB>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
if (lastHitObject != null && lastHitObject != obj)
{
OnMouseExitObj(lastHitObject);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD><CEBB>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
lastHitObject = obj;
}
2025-02-08 16:22:00 +08:00
2025-02-10 10:54:47 +08:00
}
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><E5A3AC><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD><CEBB>е<EFBFBD><D0B5><EFBFBD><EFBFBD>岻Ϊ<E5B2BB>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
if (lastHitObject != null)
{
OnMouseExitObj(lastHitObject);
lastHitObject = null;
}
}
Debug.DrawLine(ray.origin, raycastHit.point, Color.red);
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>
public void FocusObj(Vector3 target, float distance = 1f)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD>ΪCube<62><65>Ŀ<EFBFBD><C4BF>λ<EFBFBD><CEBB>
// <20><><EFBFBD>Ը<EFBFBD><D4B8><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Vector3 cameraPos = target - transform.forward * distance;
targetPos = target;
this.distance = distance;
offset = new Vector3(0, 0, -distance);
transform.position = cameraPos;
}
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-02-08 16:22:00 +08:00
// <20>ƶ<EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>
private void MoveTarget()
{
float mouseX = Input.GetAxis("Mouse X") * moveSpeed;
float mouseY = Input.GetAxis("Mouse Y") * moveSpeed;
transform.Translate(new Vector3(-mouseX, -mouseY, 0));
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private void ZoomCamera(float scroll)
{
distance -= scroll * 5f; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>
2025-02-10 10:54:47 +08:00
distance = Mathf.Clamp(distance, distanceMin, distanceMax); // <20><><EFBFBD>ƾ<EFBFBD><C6BE>Χ
2025-02-08 16:22:00 +08:00
offset = new Vector3(0, 0, -distance);
UpdateCameraPosition();
}
// <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
private void RotateCamera()
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>
float mouseX = Input.GetAxis("Mouse X") * rotateSpeed;
float mouseY = Input.GetAxis("Mouse Y") * rotateSpeed;
// <20><><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD>Ǻ͸<C7BA><CDB8><EFBFBD><EFBFBD><EFBFBD>
yaw += mouseX;
pitch -= mouseY; // ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD> Y <20><><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBB8A9><EFBFBD><EFBFBD><EFBFBD>
pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y); // <20><><EFBFBD>Ƹ<EFBFBD><C6B8><EFBFBD><EFBFBD>Ƿ<EFBFBD>Χ
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
UpdateCameraPosition();
}
// <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
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
Quaternion rotation = Quaternion.Euler(pitch, yaw, 0);
Vector3 rotatedOffset = rotation * offset;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
2025-02-14 13:20:54 +08:00
if (moveTime != -1)
{
transform.DOMove(targetPos + rotatedOffset, moveTime).onUpdate = () =>
// <20><><EFBFBD><EFBFBD>ʼ<EFBFBD>ճ<EFBFBD><D5B3><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>
transform.LookAt(targetPos);
}
else
{
transform.position = targetPos + rotatedOffset;
// <20><><EFBFBD><EFBFBD>ʼ<EFBFBD>ճ<EFBFBD><D5B3><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>
transform.LookAt(targetPos);
}
2025-02-08 16:22:00 +08:00
}
}