using UnityEngine; using UnityEngine.UI; using System.Collections; /// /// RawImage模型控制器 /// 功能:在RawImage上显示3D模型,并支持旋转和缩放操作 /// public class RawImageModelController : MonoBehaviour { [Header("【模型设置】")] [Tooltip("要显示的3D模型")] [SerializeField] private GameObject model; [Header("【UI组件】")] [Tooltip("显示模型的RawImage组件")] [SerializeField] private RawImage displayImage; [Tooltip("渲染模型的相机")] [SerializeField] private Camera renderCamera; [Tooltip("渲染纹理,相机将画面渲染到此,再由RawImage显示")] [SerializeField] private RenderTexture renderTexture; [Header("【控制设置】")] [Tooltip("旋转速度")] [SerializeField] private float rotationSpeed = 2.0f; [Tooltip("缩放速度")] [SerializeField] private float zoomSpeed = 0.5f; [Tooltip("最小缩放值")] [SerializeField] private float minZoom = 0.5f; [Tooltip("最大缩放值")] [SerializeField] private float maxZoom = 3.0f; [Tooltip("默认缩放值")] [SerializeField] private float defaultZoom = 1.0f; [Header("【相机设置】")] [Tooltip("相机相对于模型的初始偏移")] [SerializeField] private Vector3 cameraOffset = new Vector3(0, 0, 5); [Tooltip("相机视野")] [SerializeField] private float fieldOfView = 60f; [Header("【初始变换】")] [Tooltip("模型的初始旋转")] [SerializeField] private Vector3 initialRotation = Vector3.zero; [Tooltip("模型的初始缩放")] [SerializeField] private Vector3 initialScale = Vector3.one; // 内部状态变量 private Vector2 currentRotation = Vector2.zero; private float currentZoom = 1.0f; private float targetZoom = 1.0f; private Vector2 lastMousePosition; private bool isDragging = false; private bool isInitialized = false; /// /// 设置要显示的模型 /// /// 要显示的模型对象 public void SetModel(GameObject modelObj) { model = modelObj; if (model != null) { InitializeModel(); } } /// /// 获取当前显示的模型 /// /// 当前模型对象 public GameObject GetModel() { return model; } /// /// 初始化组件 /// void Start() { Initialize(); } /// /// 初始化所有组件 /// private void Initialize() { if (isInitialized) return; // 验证必要组件 if (displayImage == null) { Debug.LogError("RawImageModelController: 未设置Display Image组件!", this); return; } if (renderCamera == null) { Debug.LogError("RawImageModelController: 未设置Render Camera!", this); return; } if (renderTexture == null) { Debug.LogError("RawImageModelController: 未设置Render Texture!", this); return; } // 配置渲染相机 ConfigureRenderCamera(); // 设置RawImage的纹理 displayImage.texture = renderTexture; // 如果已有模型,则初始化 if (model != null) { InitializeModel(); } // 设置初始状态 currentZoom = defaultZoom; targetZoom = defaultZoom; currentRotation = new Vector2(initialRotation.y, -initialRotation.x); isInitialized = true; } /// /// 配置渲染相机 /// private void ConfigureRenderCamera() { renderCamera.targetTexture = renderTexture; renderCamera.fieldOfView = fieldOfView; renderCamera.enabled = true; // 默认启用相机 // 设置相机的初始位置 if (model != null) { renderCamera.transform.position = model.transform.position + cameraOffset; renderCamera.transform.LookAt(model.transform); } else { renderCamera.transform.position = cameraOffset; renderCamera.transform.LookAt(Vector3.zero); } } /// /// 初始化模型 /// private void InitializeModel() { if (model == null) return; // 设置模型的初始状态 model.transform.localRotation = Quaternion.Euler(initialRotation); model.transform.localScale = initialScale; // 将相机定位到模型前方 renderCamera.transform.position = model.transform.position + cameraOffset; renderCamera.transform.LookAt(model.transform); } /// /// 每帧更新 /// void Update() { if (!isInitialized || model == null) return; HandleInput(); UpdateModelTransform(); } /// /// 处理用户输入 /// private void HandleInput() { // 检查鼠标是否在RawImage区域内 if (IsMouseOverDisplayImage()) { // 旋转控制(鼠标左键拖拽) if (Input.GetMouseButtonDown(0)) { isDragging = true; lastMousePosition = Input.mousePosition; } if (Input.GetMouseButton(0) && isDragging) { Vector2 currentMousePos = Input.mousePosition; Vector2 delta = currentMousePos - lastMousePosition; // 根据鼠标移动增量更新旋转角度 currentRotation.x += delta.y * rotationSpeed * 0.1f; // 绕X轴旋转 currentRotation.y -= delta.x * rotationSpeed * 0.1f; // 绕Y轴旋转 // 限制垂直旋转角度,避免过度翻转 currentRotation.x = Mathf.Clamp(currentRotation.x, -85f, 85f); lastMousePosition = currentMousePos; } if (Input.GetMouseButtonUp(0)) { isDragging = false; } // 缩放控制(鼠标滚轮) float scroll = Input.GetAxis("Mouse ScrollWheel"); if (Mathf.Abs(scroll) > 0.01f) { // 根据滚轮方向调整目标缩放值 targetZoom -= scroll * zoomSpeed; targetZoom = Mathf.Clamp(targetZoom, minZoom, maxZoom); } } // 重置视图(R键) if (Input.GetKeyDown(KeyCode.R)) { ResetView(); } } /// /// 检测鼠标是否在显示图像的区域内 /// /// 如果鼠标在区域内返回true,否则返回false private bool IsMouseOverDisplayImage() { if (displayImage == null) return false; RectTransform rect = displayImage.rectTransform; Vector2 localPoint; // 将屏幕鼠标坐标转换为UI矩形内的本地坐标 return RectTransformUtility.ScreenPointToLocalPointInRectangle( rect, Input.mousePosition, null, out localPoint) && rect.rect.Contains(localPoint); } /// /// 更新模型的变换 /// private void UpdateModelTransform() { if (model == null) return; // 平滑插值缩放 currentZoom = Mathf.Lerp(currentZoom, targetZoom, 5f * Time.deltaTime); // 应用旋转 Quaternion targetRotation = Quaternion.Euler(currentRotation.x, currentRotation.y, 0); model.transform.rotation = targetRotation; // 应用缩放 model.transform.localScale = initialScale * currentZoom; // 更新相机位置以保持相对距离 Vector3 cameraDirection = (renderCamera.transform.position - model.transform.position).normalized; Vector3 targetCameraPosition = model.transform.position + cameraDirection * (cameraOffset.magnitude * currentZoom); renderCamera.transform.position = targetCameraPosition; renderCamera.transform.LookAt(model.transform); } /// /// 重置视图到初始状态 /// public void ResetView() { currentRotation = new Vector2(initialRotation.y, -initialRotation.x); currentZoom = defaultZoom; targetZoom = defaultZoom; if (model != null) { model.transform.localRotation = Quaternion.Euler(initialRotation); model.transform.localScale = initialScale; } // 重置相机位置 if (model != null) { renderCamera.transform.position = model.transform.position + cameraOffset; renderCamera.transform.LookAt(model.transform); } else { renderCamera.transform.position = cameraOffset; renderCamera.transform.LookAt(Vector3.zero); } } /// /// 设置旋转速度 /// /// 新的旋转速度 public void SetRotationSpeed(float speed) { rotationSpeed = speed; } /// /// 设置缩放速度 /// /// 新的缩放速度 public void SetZoomSpeed(float speed) { zoomSpeed = speed; } /// /// 设置缩放限制 /// /// 最小缩放值 /// 最大缩放值 public void SetZoomLimits(float min, float max) { minZoom = min; maxZoom = max; targetZoom = Mathf.Clamp(targetZoom, minZoom, maxZoom); } /// /// 获取当前缩放值 /// /// 当前缩放值 public float GetCurrentZoom() { return currentZoom; } /// /// 设置当前缩放值 /// /// 目标缩放值 public void SetZoom(float zoom) { targetZoom = Mathf.Clamp(zoom, minZoom, maxZoom); } /// /// 启用/禁用控制器 /// /// 是否启用 public void SetEnabled(bool enabled) { gameObject.SetActive(enabled); } /// /// 在编辑器中绘制调试信息 /// void OnValidate() { if (renderCamera != null) { // 确保相机设置正确 if (fieldOfView > 0) { renderCamera.fieldOfView = fieldOfView; } } } }