提交 921bcf4c 编写于 作者: Kerven_HKW's avatar Kerven_HKW ⛹🏿

Add README.md

上级 80d0f2a7
# UnityPreviewEditor
2222
UnityPreviewEditor:使用PreviewRenderUtility创建预览窗口。
Unity 版本: Unity 2020.3.18f1c1
### 简介
1. Example -> PreviewRenderWindow 打开
2. 效果图:
![](https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/11_21_27_21_20220111212720.png)
### 代码
```c++
// PreviewRenderWindow.cs 负责自定义管理界面
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class PreviewRenderWindow : EditorWindow
{
[MenuItem("Example/PreviewRenderWindow")]
static void ShowWindow()
{
GetWindow<PreviewRenderWindow>("PreviewRenderWindow").Show();
}
GameObject _gameObject;
GameObject _lastGameObject;
PreviewRenderEditor _editor;
bool _load = true;
Vector2 _lightRot;
Vector2 _lastLightRot;
void OnGUI()
{
_gameObject = (GameObject) EditorGUILayout.ObjectField("预览预制体", _gameObject, typeof(GameObject), true);
_lightRot = EditorGUILayout.Vector2Field("光源方向", _lightRot);
if (_editor == null)
{
_editor = Editor.CreateEditor(this, typeof(PreviewRenderEditor)) as PreviewRenderEditor;
}
if(_editor)
{
if (_lastLightRot != _lightRot)
{
_lastLightRot = _lightRot;
_editor.RefreshLightRot(_lightRot);
}
_editor.DrawPreview(GUILayoutUtility.GetRect(400, 400));
}
if (_gameObject && _load)
{
_editor.RefreshPreviewInstance(_gameObject);
_load = false;
_lastGameObject = _gameObject;
}
if (_lastGameObject != _gameObject)
{
_load = true;
}
}
}
```
```c++
// PreviewRenderEditor.cs 负责预览界面
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class PreviewRenderEditor : Editor
{
private PreviewRenderUtility _previewRenderUtility;
private GameObject _previewInstance;
private GameObject _targetObj;
private static bool _loaded = true;
private Vector2 _drag = new Vector2(250f, -30f);
private Vector2 _lightRot = new Vector2(180f, 0);
public void RefreshLightRot(Vector2 rot)
{
_lightRot = rot;
}
public void RefreshPreviewInstance(GameObject obj)
{
_targetObj = obj;
if (_previewInstance)
UnityEngine.Object.DestroyImmediate(_previewInstance);
_previewInstance = null;
_loaded = true;
}
private void OnEnable()
{
if (_previewRenderUtility == null)
{
_previewRenderUtility = new PreviewRenderUtility();
}
}
private void OnDisable()
{
if (_previewRenderUtility != null)
{
// 必须进行清理,否则会存在残留对象
_previewInstance = null;
_previewRenderUtility.Cleanup();
_previewRenderUtility = null;
}
}
public override void OnPreviewGUI(Rect r, GUIStyle background)
{
// _loaded 确保只加载一次物体
if (_loaded && _targetObj)
{
_previewInstance = Instantiate(_targetObj as GameObject, Vector3.zero, Quaternion.identity);
// AddSingleGO 添加物体
_previewRenderUtility.AddSingleGO(_previewInstance);
_loaded = false;
}
// 获取拖拽向量
_drag = Drag2D(_drag, r);
// 事件为绘制时,才进行绘制
if (Event.current.type == EventType.Repaint)
{
_previewRenderUtility.BeginPreview(r, background);
//调整相机位置与角度
Camera camera = _previewRenderUtility.camera;
var cameraTran = camera.transform;
cameraTran.position = Vector2.zero;
cameraTran.rotation = Quaternion.Euler(new Vector3(-_drag.y, -_drag.x, 0));
cameraTran.position = cameraTran.forward * -6f;
var pos = cameraTran.position;
cameraTran.position = new Vector3(pos.x, pos.y + 0.6f, pos.z);
EditorUtility.SetCameraAnimateMaterials(camera, true);
camera.cameraType = CameraType.Preview;
camera.enabled = false;
camera.clearFlags = CameraClearFlags.Skybox;
camera.fieldOfView = 30;
camera.farClipPlane = 10.0f;
camera.nearClipPlane = 2.0f;
camera.backgroundColor = new Color(49.0f / 255.0f, 77.0f / 255.0f, 121.0f / 255.0f, 0f);
// // 设置光源数据
_previewRenderUtility.lights[0].intensity = 0.7f;
_previewRenderUtility.lights[0].transform.rotation = Quaternion.Euler(_lightRot.x, _lightRot.y, 0f);
_previewRenderUtility.lights[1].intensity = 0.7f;
_previewRenderUtility.lights[1].transform.rotation = Quaternion.Euler(_lightRot.x, _lightRot.y, 0f);
_previewRenderUtility.ambientColor = new Color(0.3f, 0.3f, 0.3f, 0f);
// camera.transform.LookAt(_previewInstance.transform);
// 相机渲染
camera.Render();
// 结束并绘制
_previewRenderUtility.EndAndDrawPreview(r);
}
}
// Drag2D 来自源码
private static int sliderHash = "Slider".GetHashCode();
public static Vector2 Drag2D(Vector2 scrollPosition, Rect position)
{
// 每次获得独一无二的 controlID
int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive);
Event current = Event.current;
// 获取对应 controlID 的事件
switch (current.GetTypeForControl(controlID))
{
case EventType.MouseDown:
{
bool flag = position.Contains(current.mousePosition) && position.width > 50f;
if (flag)
{
// 鼠标摁住拖出预览窗口外,预览物体任然能够旋转
GUIUtility.hotControl = controlID;
// 采用事件
current.Use();
// 让鼠标可以拖动到屏幕外后,从另一边出来
EditorGUIUtility.SetWantsMouseJumping(1);
}
break;
}
case EventType.MouseUp:
{
bool flag2 = GUIUtility.hotControl == controlID;
if (flag2)
{
GUIUtility.hotControl = 0;
}
EditorGUIUtility.SetWantsMouseJumping(0);
break;
}
case EventType.MouseDrag:
{
bool flag3 = GUIUtility.hotControl == controlID;
if (flag3)
{
// shift 加速
scrollPosition -= current.delta * (float) (current.shift ? 3 : 1) /
Mathf.Min(position.width, position.height) * 140f;
// 以下两条缺少任意一个,会导致延迟更新,拖动过程中无法实时更新
// 直到 repaint事件触发才重新绘制
current.Use();
GUI.changed = true;
}
break;
}
}
return scrollPosition;
}
}
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册