167 lines
4.4 KiB
C#
Raw Normal View History

2025-02-08 16:22:00 +08:00
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class Show3DCamera : MonoBehaviour
{
public Transform target; // Χ<><CEA7><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>
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>
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;
int rawWidth;
int rawHeight;
Camera self;
private void Awake()
{
instance = this;
self = transform.GetComponent<Camera>();
DontDestroyOnLoad(this);
}
public void Set(int width,int height, Transform target, float rotateSpeed = 10, float moveSpeed = 0.1f, float distance = 0.1f, float pitchMin = -20, float pitchMax = 80)
{
if (target == null)
{
Debug.LogError("Target is not assigned!");
return;
}
this.rawWidth = width;
this.rawHeight = height;
yaw = 0;
pitch = 0;
this.target = target.transform;
this.rotateSpeed = rotateSpeed;
this.moveSpeed = moveSpeed;
this.distance = distance;
this.pitchMinMax = new Vector2(pitchMin, pitchMax);
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
offset = new Vector3(0, 0, -distance);
UpdateCameraPosition();
}
public void Clear()
{
target = null;
}
void Update()
{
if (target != null)
{
// <20><>ס<EFBFBD><D7A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
if (Input.GetMouseButton(0))
{
RotateCamera();
}
// <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>
private void DetectHoveredObject()
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Ray ray = self.ScreenPointToRay(ConvertScreenToRenderTextureCoordinates(Input.mousePosition));
if (Physics.Raycast(ray, out RaycastHit hit))
{
// <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Debug.LogError("Hovered Object: " + hit.collider.gameObject.name);
}
Debug.DrawLine(ray.origin, hit.point, Color.red);
}
private Vector3 ConvertScreenToRenderTextureCoordinates(Vector3 screenPosition)
{
// <20><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>
int screenWidth = Screen.width;
int screenHeight = Screen.height;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float scaleX = (float)rawWidth / screenWidth;
float scaleY = (float)rawHeight / screenHeight;
// ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
Vector3 renderTexturePosition = new Vector3(
screenPosition.x * scaleX,
screenPosition.y * scaleY,
screenPosition.z
);
return renderTexturePosition;
}
// <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>
distance = Mathf.Clamp(distance, 0.2f, 20f); // <20><><EFBFBD>ƾ<EFBFBD><C6BE>Χ
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>
private void UpdateCameraPosition()
{
// <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>
transform.position = target.position + rotatedOffset;
// <20><><EFBFBD><EFBFBD>ʼ<EFBFBD>ճ<EFBFBD><D5B3><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>
transform.LookAt(target);
}
}