《Unity》编辑器预览窗口实现相机旋转平移

这篇博客介绍了如何在Unity编辑器中创建一个ScreenShotPreview窗口,用于实现Scene视图的截图预览,并且增加了鼠标在预览窗口内的平移、旋转和缩放操作。通过监听鼠标事件,结合Quaternion和Vector3进行视角变换,提供了类似 Orbit 和 Pan 的交互体验,同时支持滚轮缩放。此功能对于游戏开发中的场景预览和调试非常实用。
摘要由CSDN通过智能技术生成

在这里插入图片描述
利用SceneView

之前做过一个通过scene截图来实现预览的效果,这次加上窗口内的鼠标平移旋转缩放的常见效果。

using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;

public class ScreenShotPreview : EditorWindow
{
    private bool bIsStartPreviewMouseEvent = false;
    private MouseCursor previewMouseCursor = MouseCursor.Arrow; 
    [MenuItem("Tools/截图预览窗口")]
    static void Open()
    {
        CreateWindow<ScreenShotPreview>();
    }
    void OnGUI()
    {
        // 接收按键
        if (Event.current.type == EventType.Repaint)
            Repaint(); // 保证窗口实时刷新
        Camera cam = SceneView.GetAllSceneCameras()[0];
        int pixWidth = cam.pixelWidth;
        int pixHeight = cam.pixelHeight;
        RenderTexture tex = new RenderTexture(pixWidth, pixHeight, 1, RenderTextureFormat.DefaultHDR);
        RenderTexture lastTex = cam.targetTexture;
        cam.targetTexture = tex;
        cam.Render();
        cam.targetTexture = lastTex;
        float width = pixWidth;
        float height = pixHeight;
        Rect rect = new Rect(0, 0, width, height);
        GUI.DrawTexture(rect, tex);
        HandleKey(rect,SceneView.lastActiveSceneView);
    }

    private void HandleKey(Rect rect, SceneView view)
    {
        Event evt = Event.current;
        switch (evt.type)
        {
            case EventType.MouseDown:
                if (rect.Contains(evt.mousePosition))
                {
                    switch (evt.button)
                    {
                        case 1:
                        case 2:
                            bIsStartPreviewMouseEvent = true;
                            // 让鼠标可以拖动到屏幕外后,从另一边出来
                             EditorGUIUtility.SetWantsMouseJumping(1);
                            break;
                    }
                }
                break;

            case EventType.MouseUp:
                bIsStartPreviewMouseEvent = false;
                previewMouseCursor = MouseCursor.Arrow;
                  EditorGUIUtility.SetWantsMouseJumping(0);
                break;

            case EventType.MouseDrag:
                if (bIsStartPreviewMouseEvent)
                {
                    switch (evt.button)
                    {
                        case 1:
                            previewMouseCursor = MouseCursor.Orbit;
                            Quaternion rotation = view.rotation;
                            rotation = Quaternion.AngleAxis(evt.delta.y * .003f * Mathf.Rad2Deg, rotation * Vector3.right) * rotation;
                            rotation = Quaternion.AngleAxis(evt.delta.x * .003f * Mathf.Rad2Deg, Vector3.up) * rotation;
                            view.rotation = rotation;
                            break;

                        case 2:
                            previewMouseCursor = MouseCursor.Pan;
                            Vector2 screenDelta = evt.delta;
                            Vector3 worldDelta = ScreenToWorldDistance(view, new Vector2(-screenDelta.x, screenDelta.y));

                            if (!evt.shift)
                                worldDelta *= 4;

                            view.pivot += worldDelta;
                            break;
                    }
                }
                break;

            case EventType.ScrollWheel:
                if (rect.Contains(evt.mousePosition))
                {
                    float zoomDelta = -HandleUtility.niceMouseDeltaZoom * (evt.shift ? 3 : 9);
                    if (view.orthographic)
                    {
                        view.size = Mathf.Max(.0001f, view.size * (1 + zoomDelta * .001f));
                    }
                    else
                    {
                        var s_StartZoom = view.size;
                        var s_ZoomSpeed = Mathf.Max(Mathf.Abs(s_StartZoom), .3f);
                        view.size = view.size + zoomDelta * s_ZoomSpeed * .003f;
                    }
                }
                break;
        }
        EditorGUIUtility.AddCursorRect(rect, previewMouseCursor);
        evt.Use();
    }
    private Vector3 ScreenToWorldDistance(SceneView view,Vector2 sceneDelta)
    {
        var camera = view.camera;
        Vector3 screenPos = camera.WorldToScreenPoint(view.pivot);
        screenPos += new Vector3(sceneDelta.x, sceneDelta.y, 0);
        Vector3 worldDelta = camera.ScreenToWorldPoint(screenPos) - view.pivot;
        worldDelta *= EditorGUIUtility.pixelsPerPoint;
        return worldDelta;
    }
}

在这里插入图片描述
在这里插入图片描述
相关业务实际上也可以看这个面板相关的源码学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JustEasyCode

谢谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值