167 lines
4.4 KiB
C#
167 lines
4.4 KiB
C#
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
public class Show3DCamera : MonoBehaviour
|
|
{
|
|
public Transform target; // 围绕旋转的目标点
|
|
public float rotateSpeed = 10f; // 旋转速度
|
|
public float moveSpeed = 10f; // 移动速度
|
|
public float distance = 10f; // 相机与目标的距离
|
|
public Vector2 pitchMinMax = new Vector2(-20, 80); // 相机俯仰角范围
|
|
|
|
private Vector3 offset; // 相机与目标的偏移量
|
|
private float yaw = 0f; // 偏航角(左右旋转)
|
|
private float pitch = 0f; // 俯仰角(上下旋转)
|
|
|
|
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);
|
|
// 初始化相机位置
|
|
offset = new Vector3(0, 0, -distance);
|
|
UpdateCameraPosition();
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
target = null;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (target != null)
|
|
{
|
|
// 按住鼠标左键时旋转相机
|
|
if (Input.GetMouseButton(0))
|
|
{
|
|
RotateCamera();
|
|
}
|
|
|
|
// 鼠标滚轮缩放
|
|
float scroll = Input.GetAxis("Mouse ScrollWheel");
|
|
if (scroll != 0)
|
|
{
|
|
ZoomCamera(scroll);
|
|
}
|
|
|
|
|
|
// 按住鼠标右键时移动目标点
|
|
if (Input.GetMouseButton(1))
|
|
{
|
|
MoveTarget();
|
|
}
|
|
|
|
DetectHoveredObject();
|
|
}
|
|
}
|
|
|
|
// 检测鼠标悬停的物体
|
|
private void DetectHoveredObject()
|
|
{
|
|
// 从相机发射射线
|
|
Ray ray = self.ScreenPointToRay(ConvertScreenToRenderTextureCoordinates(Input.mousePosition));
|
|
if (Physics.Raycast(ray, out RaycastHit hit))
|
|
{
|
|
// 打印物体名称
|
|
Debug.LogError("Hovered Object: " + hit.collider.gameObject.name);
|
|
}
|
|
Debug.DrawLine(ray.origin, hit.point, Color.red);
|
|
}
|
|
|
|
private Vector3 ConvertScreenToRenderTextureCoordinates(Vector3 screenPosition)
|
|
{
|
|
// 获取屏幕分辨率
|
|
int screenWidth = Screen.width;
|
|
int screenHeight = Screen.height;
|
|
|
|
|
|
// 计算比例
|
|
float scaleX = (float)rawWidth / screenWidth;
|
|
float scaleY = (float)rawHeight / screenHeight;
|
|
|
|
// 转换鼠标位置
|
|
Vector3 renderTexturePosition = new Vector3(
|
|
screenPosition.x * scaleX,
|
|
screenPosition.y * scaleY,
|
|
screenPosition.z
|
|
);
|
|
|
|
return renderTexturePosition;
|
|
}
|
|
|
|
|
|
// 移动目标点
|
|
private void MoveTarget()
|
|
{
|
|
float mouseX = Input.GetAxis("Mouse X") * moveSpeed;
|
|
float mouseY = Input.GetAxis("Mouse Y") * moveSpeed;
|
|
|
|
transform.Translate(new Vector3(-mouseX, -mouseY, 0));
|
|
}
|
|
// 缩放相机
|
|
private void ZoomCamera(float scroll)
|
|
{
|
|
distance -= scroll * 5f; // 调整缩放速度
|
|
distance = Mathf.Clamp(distance, 0.2f, 20f); // 限制距离范围
|
|
offset = new Vector3(0, 0, -distance);
|
|
UpdateCameraPosition();
|
|
}
|
|
|
|
// 旋转相机
|
|
private void RotateCamera()
|
|
{
|
|
// 获取鼠标移动量
|
|
float mouseX = Input.GetAxis("Mouse X") * rotateSpeed;
|
|
float mouseY = Input.GetAxis("Mouse Y") * rotateSpeed;
|
|
|
|
// 更新偏航角和俯仰角
|
|
yaw += mouseX;
|
|
pitch -= mouseY; // 注意:鼠标 Y 轴移动方向与俯仰角相反
|
|
pitch = Mathf.Clamp(pitch, pitchMinMax.x, pitchMinMax.y); // 限制俯仰角范围
|
|
|
|
// 更新相机位置
|
|
UpdateCameraPosition();
|
|
}
|
|
|
|
// 更新相机位置和朝向
|
|
private void UpdateCameraPosition()
|
|
{
|
|
// 计算旋转后的偏移量
|
|
Quaternion rotation = Quaternion.Euler(pitch, yaw, 0);
|
|
Vector3 rotatedOffset = rotation * offset;
|
|
|
|
// 更新相机位置
|
|
transform.position = target.position + rotatedOffset;
|
|
|
|
// 相机始终朝向目标点
|
|
transform.LookAt(target);
|
|
}
|
|
}
|
|
|
|
|