Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
kerven_hankangwen
UnityPreviewEditor
提交
a378e532
U
UnityPreviewEditor
项目概览
kerven_hankangwen
/
UnityPreviewEditor
通知
58
Star
3
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
UnityPreviewEditor
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
a378e532
编写于
1月 13, 2022
作者:
Kerven_HKW
⛹🏿
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
内容完善
上级
43b32a19
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
774 addition
and
12 deletion
+774
-12
README.md
README.md
+323
-0
UnityPreviewEditor/.idea/.idea.UnityPreviewEditor/.idea/contentModel.xml
...tor/.idea/.idea.UnityPreviewEditor/.idea/contentModel.xml
+8
-0
UnityPreviewEditor/Assembly-CSharp.csproj.meta
UnityPreviewEditor/Assembly-CSharp.csproj.meta
+3
-0
UnityPreviewEditor/Assets.meta
UnityPreviewEditor/Assets.meta
+3
-0
UnityPreviewEditor/Assets/Editor/Example.meta
UnityPreviewEditor/Assets/Editor/Example.meta
+8
-0
UnityPreviewEditor/Assets/Editor/Example/PreviewExample.cs
UnityPreviewEditor/Assets/Editor/Example/PreviewExample.cs
+18
-0
UnityPreviewEditor/Assets/Editor/Example/PreviewExample.cs.meta
...reviewEditor/Assets/Editor/Example/PreviewExample.cs.meta
+11
-0
UnityPreviewEditor/Assets/Editor/Example/PreviewExampleInspector.cs
...ewEditor/Assets/Editor/Example/PreviewExampleInspector.cs
+18
-0
UnityPreviewEditor/Assets/Editor/Example/PreviewExampleInspector.cs.meta
...tor/Assets/Editor/Example/PreviewExampleInspector.cs.meta
+11
-0
UnityPreviewEditor/Assets/Editor/PreviewRenderEditor.cs
UnityPreviewEditor/Assets/Editor/PreviewRenderEditor.cs
+2
-2
UnityPreviewEditor/Assets/PreviewExample.meta
UnityPreviewEditor/Assets/PreviewExample.meta
+8
-0
UnityPreviewEditor/Assets/PreviewExample/Editor.meta
UnityPreviewEditor/Assets/PreviewExample/Editor.meta
+8
-0
UnityPreviewEditor/Assets/PreviewExample/Editor/PreviewExampleInspector.cs
...r/Assets/PreviewExample/Editor/PreviewExampleInspector.cs
+191
-0
UnityPreviewEditor/Assets/PreviewExample/Editor/PreviewExampleInspector.cs.meta
...ets/PreviewExample/Editor/PreviewExampleInspector.cs.meta
+11
-0
UnityPreviewEditor/Assets/PreviewExample/Editor/PreviewExampleWindow.cs
...itor/Assets/PreviewExample/Editor/PreviewExampleWindow.cs
+34
-0
UnityPreviewEditor/Assets/PreviewExample/Editor/PreviewExampleWindow.cs.meta
...Assets/PreviewExample/Editor/PreviewExampleWindow.cs.meta
+11
-0
UnityPreviewEditor/Assets/PreviewExample/PreviewExample.cs
UnityPreviewEditor/Assets/PreviewExample/PreviewExample.cs
+6
-0
UnityPreviewEditor/Assets/PreviewExample/PreviewExample.cs.meta
...reviewEditor/Assets/PreviewExample/PreviewExample.cs.meta
+11
-0
UnityPreviewEditor/Assets/Scenes/SampleScene.unity
UnityPreviewEditor/Assets/Scenes/SampleScene.unity
+89
-10
未找到文件。
README.md
浏览文件 @
a378e532
...
@@ -4,6 +4,7 @@ UnityPreviewEditor:使用PreviewRenderUtility创建预览窗口。
...
@@ -4,6 +4,7 @@ UnityPreviewEditor:使用PreviewRenderUtility创建预览窗口。
Unity 版本: Unity 2020.3.18f1c1
Unity 版本: Unity 2020.3.18f1c1
[toc]
### 简介
### 简介
1.
Example -> PreviewRenderWindow 打开
1.
Example -> PreviewRenderWindow 打开
2.
效果图:
2.
效果图:
...
@@ -11,6 +12,9 @@ Unity 版本: Unity 2020.3.18f1c1
...
@@ -11,6 +12,9 @@ Unity 版本: Unity 2020.3.18f1c1
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/11_21_27_21_20220111212720.png
)
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/11_21_27_21_20220111212720.png
)
### 代码
### 代码
<details>
<summary><font
color=
darkred
>
查看代码
</font></summary>
```
c++
```
c++
// PreviewRenderWindow.cs 负责自定义管理界面
// PreviewRenderWindow.cs 负责自定义管理界面
using
System
.
Collections
;
using
System
.
Collections
;
...
@@ -230,3 +234,322 @@ public class PreviewRenderEditor : Editor
...
@@ -230,3 +234,322 @@ public class PreviewRenderEditor : Editor
}
}
}
}
```
```
</details>
### Unity 预览界面
#### 预览界面
在Unity编辑器界面上可以看到除了Game视图、Scene视图,其他的视图也会出现绘制三维物体的地方,比如检视器的预览窗口,当选中网格时,会对网格进行预览,如下所示:
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/12_20_46_52_20220112204650.png
)
绘制的方法都是使用 UnityEditor 未公开文档的PreviewRenderUtility类进行的。
#### 检视器预览界面
资产或脚本实现预览窗口可参考Editor类的文档说明,重载带有Preview关键字的接口。
#### 开启预览功能
默认脚本对象的检视器窗口是没有预览窗口的,如下所示:
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/12_20_51_42_20220112205141.png
)
想要开启预览窗口,那么得创建自己的检视器窗口类,然后重载HasPreviewGUI接口,完整代码如下:
```
c++
using
UnityEngine
;
public
class
PreviewExample
:
MonoBehaviour
{
}
using
UnityEditor
;
using
UnityEngine
;
[
CustomEditor
(
typeof
(
PreviewExample
))]
public
class
PreviewExampleInspector
:
Editor
{
public
override
bool
HasPreviewGUI
()
{
return
true
;
}
}
```
可以看到有黑色的预览窗口了,如下所示:
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/12_21_4_19_20220112210419.png
)
#### 标题栏绘制
默认显示的是物体的名称,重载 GetPreviewTitle 接口可以更改标题名称:
```
c++
public
override
GUIContent
GetPreviewTitle
()
{
return
new
GUIContent
(
"预览"
);
}
```
标题栏右边可以绘制其他的信息或者按钮等,重载 OnPreviewSettings 接口方便对预览窗口进行控制:
```
c++
public
override
void
OnPreviewSettings
()
{
GUILayout
.
Label
(
"文本"
,
"preLabel"
);
GUILayout
.
Button
(
"按钮"
,
"preButton"
);
}
```
#### 预览内容的绘制
最后预览内容的绘制,只需要重载 OnPreviewGUI 接口即可:
```
c++
public
override
void
OnPreviewGUI
(
Rect
r
,
GUIStyle
background
)
{
GUI
.
Box
(
r
,
"Preview"
);
}
```
最后显示如下所示:
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/12_21_15_5_20220112211505.png
)
#### 摄像机渲染
不仅仅在预览窗口进行绘制控件,还可以绘制三维物体,实质是绘制独立的摄像机所照射的信息,例如动画片段预览窗口:
鼠标可以拖动旋转等,还可以看其他方向,就像操作摄像机一样。
这都是通过 PreviewRenderUtility 来实现的,对于这个类没有官方文档,可以通过网上其他人的分享,还有 UnityEditor 内部的使用来学习。
#### 基础绘制
PreviewRenderUtility 的构造和销毁,还有要预览物体的构造和销毁,以及调用绘制,以 BeginPreview 和 EndAndDrawPreview 包围,在其中进行摄像机的渲染 Camera.Render 调用,代码如下:
<details>
<summary><font
color=
darkred
>
查看代码
</font></summary>
```
c++
using
UnityEditor
;
using
UnityEngine
;
[
CustomEditor
(
typeof
(
PreviewExample
))]
public
class
PreviewExampleInspector
:
Editor
{
private
GameObject
_lastGameObj
;
private
bool
_canRefreshPreviewGo
=
false
;
public
override
void
OnInspectorGUI
()
{
// target 当前操作的对象
PreviewExample
pe
=
(
PreviewExample
)
target
;
pe
.
previewGo
=
EditorGUILayout
.
ObjectField
(
"预览目标"
,
pe
.
previewGo
,
typeof
(
GameObject
))
as
GameObject
;
if
(
pe
.
previewGo
!=
_lastGameObj
)
{
_lastGameObj
=
pe
.
previewGo
;
_canRefreshPreviewGo
=
true
;
}
serializedObject
.
ApplyModifiedProperties
();
}
public
override
bool
HasPreviewGUI
()
{
return
true
;
}
public
override
GUIContent
GetPreviewTitle
()
{
return
new
GUIContent
(
"预览"
);
}
public
override
void
OnPreviewSettings
()
{
GUILayout
.
Label
(
"文本"
,
"preLabel"
);
GUILayout
.
Button
(
"按钮"
,
"preButton"
);
}
public
override
void
OnPreviewGUI
(
Rect
r
,
GUIStyle
background
)
{
InitPreview
();
if
(
Event
.
current
.
type
!=
EventType
.
Repaint
)
{
return
;
}
_previewRenderUtility
.
BeginPreview
(
r
,
background
);
Camera
camera
=
_previewRenderUtility
.
camera
;
if
(
_previewInstance
)
{
camera
.
transform
.
position
=
_previewInstance
.
transform
.
position
+
new
Vector3
(
0
,
5
f
,
3
f
);
camera
.
transform
.
LookAt
(
_previewInstance
.
transform
);
}
camera
.
Render
();
_previewRenderUtility
.
EndAndDrawPreview
(
r
);
}
private
PreviewRenderUtility
_previewRenderUtility
;
private
GameObject
_previewInstance
;
private
void
InitPreview
()
{
if
(
_previewRenderUtility
==
null
)
{
// 参数true代表绘制场景内的游戏对象
_previewRenderUtility
=
new
PreviewRenderUtility
(
true
);
// 设置摄像机的一些参数
_previewRenderUtility
.
cameraFieldOfView
=
30
f
;
}
if
(
_canRefreshPreviewGo
)
{
_canRefreshPreviewGo
=
false
;
// 创建预览的游戏对象
CreatePreviewInstances
();
}
}
private
void
DestroyPreview
()
{
if
(
_previewRenderUtility
!=
null
)
{
// 务必要进行清理,才不会残留生成的摄像机对象等
_previewRenderUtility
.
Cleanup
();
_previewRenderUtility
=
null
;
}
}
private
void
CreatePreviewInstances
()
{
DestroyPreviewInstances
();
// 绘制预览的游戏对象
if
(
_lastGameObj
)
{
_previewInstance
=
Instantiate
(
_lastGameObj
);
_previewRenderUtility
.
AddSingleGO
(
_previewInstance
);
}
}
private
void
DestroyPreviewInstances
()
{
if
(
_previewInstance
)
{
DestroyImmediate
(
_previewInstance
);
}
_previewInstance
=
null
;
}
void
OnDestroy
()
{
DestroyPreviewInstances
();
DestroyPreview
();
}
}
```
</details>
最后效果如下所示:
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/13_10_13_40_20220113101338.png
)
#### 拖动旋转
在预览窗口鼠标拖动可以旋转进行预览,就像Cube物体预览一样。要想让摄像机旋转,得知道游戏对象的中心,才能绕着它进行旋转。
<details>
<summary><font
color=
darkred
>
查看代码
</font></summary>
```
c++
private
static
int
sliderHash
=
"Slider"
.
GetHashCode
();
private
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
>
50
f
;
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
)
*
140
f
;
// 以下两条缺少任意一个,会导致延迟更新,拖动过程中无法实时更新
// 直到 repaint事件触发才重新绘制
current
.
Use
();
GUI
.
changed
=
true
;
}
break
;
}
}
return
scrollPosition
;
}
```
</details>
最后效果,如下图所示:
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/13_10_48_42_20220113104841.png
)
#### 自定义视图的预览
在自定义视图上的预览,可以采用类似以上的方式进行绘制,也可以创建相应的检视器类,直接调用绘制预览接口。代码如下:
<details>
<summary><font
color=
darkred
>
查看代码
</font></summary>
```
c++
using
UnityEngine
;
using
UnityEditor
;
public
class
PreviewExampleWindow
:
EditorWindow
{
private
Editor
m_Editor
;
[
MenuItem
(
"Example/PreviewExample"
)]
static
void
ShowWindow
()
{
GetWindow
<
PreviewExampleWindow
>
(
"PreviewExample"
);
}
private
void
OnDestroy
()
{
if
(
m_Editor
!=
null
)
{
DestroyImmediate
(
m_Editor
);
}
m_Editor
=
null
;
}
void
OnGUI
()
{
if
(
m_Editor
==
null
)
{
// 第一个参数这里暂时没关系,因为编辑器没有取目标对象
m_Editor
=
Editor
.
CreateEditor
(
this
,
typeof
(
PreviewExampleInspector
));
}
m_Editor
.
DrawPreview
(
GUILayoutUtility
.
GetRect
(
300
,
200
));
}
}
```
</details>
打开测试窗口,如下图所示:
![](
https://gitcode.net/hankangwen/blog-image/-/raw/master/pictures/2022/01/13_11_3_33_20220113110332.png
)
### 开源代码
[
https://gitcode.net/hankangwen/unityprevieweditor
](
https://gitcode.net/hankangwen/unityprevieweditor
)
UnityPreviewEditor/.idea/.idea.UnityPreviewEditor/.idea/contentModel.xml
浏览文件 @
a378e532
...
@@ -6,11 +6,19 @@
...
@@ -6,11 +6,19 @@
<e
p=
"C:\Users\king\.Rider2019.3\system\resharper-host\local\Transient\ReSharperHost\v193\SolutionCaches\_UnityPreviewEditor.802915575.00"
t=
"ExcludeRecursive"
/>
<e
p=
"C:\Users\king\.Rider2019.3\system\resharper-host\local\Transient\ReSharperHost\v193\SolutionCaches\_UnityPreviewEditor.802915575.00"
t=
"ExcludeRecursive"
/>
<e
p=
"D:\GitCode\UnityPreviewEditor\UnityPreviewEditor"
t=
"IncludeRecursive"
>
<e
p=
"D:\GitCode\UnityPreviewEditor\UnityPreviewEditor"
t=
"IncludeRecursive"
>
<e
p=
"Assembly-CSharp-Editor.csproj"
t=
"IncludeRecursive"
/>
<e
p=
"Assembly-CSharp-Editor.csproj"
t=
"IncludeRecursive"
/>
<e
p=
"Assembly-CSharp.csproj"
t=
"IncludeRecursive"
/>
<e
p=
"Assets"
t=
"Include"
>
<e
p=
"Assets"
t=
"Include"
>
<e
p=
"Editor"
t=
"Include"
>
<e
p=
"Editor"
t=
"Include"
>
<e
p=
"PreviewRenderEditor.cs"
t=
"Include"
/>
<e
p=
"PreviewRenderEditor.cs"
t=
"Include"
/>
<e
p=
"PreviewRenderWindow.cs"
t=
"Include"
/>
<e
p=
"PreviewRenderWindow.cs"
t=
"Include"
/>
</e>
</e>
<e
p=
"PreviewExample"
t=
"Include"
>
<e
p=
"Editor"
t=
"Include"
>
<e
p=
"PreviewExampleInspector.cs"
t=
"Include"
/>
<e
p=
"PreviewExampleWindow.cs"
t=
"Include"
/>
</e>
<e
p=
"PreviewExample.cs"
t=
"Include"
/>
</e>
</e>
</e>
<e
p=
"obj"
t=
"ExcludeRecursive"
/>
<e
p=
"obj"
t=
"ExcludeRecursive"
/>
<e
p=
"Packages"
t=
"ExcludeRecursive"
/>
<e
p=
"Packages"
t=
"ExcludeRecursive"
/>
...
...
UnityPreviewEditor/Assembly-CSharp.csproj.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 7e2b1b35abda435a9fd3f74c027625e8
timeCreated: 1641992479
\ No newline at end of file
UnityPreviewEditor/Assets.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 5198225033f14f39bead8eb262a2f737
timeCreated: 1641992479
\ No newline at end of file
UnityPreviewEditor/Assets/Editor/Example.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 5dd31354876b45e48aa1b5f429f363fb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
UnityPreviewEditor/Assets/Editor/Example/PreviewExample.cs
0 → 100644
浏览文件 @
a378e532
using
System.Collections
;
using
System.Collections.Generic
;
using
UnityEngine
;
public
class
PreviewExample
:
MonoBehaviour
{
// Start is called before the first frame update
void
Start
()
{
}
// Update is called once per frame
void
Update
()
{
}
}
UnityPreviewEditor/Assets/Editor/Example/PreviewExample.cs.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 52e1416b880a27047b16f6098d52bde3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
UnityPreviewEditor/Assets/Editor/Example/PreviewExampleInspector.cs
0 → 100644
浏览文件 @
a378e532
using
System.Collections
;
using
System.Collections.Generic
;
using
UnityEngine
;
public
class
PreviewExampleInspector
:
MonoBehaviour
{
// Start is called before the first frame update
void
Start
()
{
}
// Update is called once per frame
void
Update
()
{
}
}
UnityPreviewEditor/Assets/Editor/Example/PreviewExampleInspector.cs.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 2f9601ed07e8b98409ad843aa4c10e2d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
UnityPreviewEditor/Assets/Editor/PreviewRenderEditor.cs
浏览文件 @
a378e532
...
@@ -83,7 +83,7 @@ public class PreviewRenderEditor : Editor
...
@@ -83,7 +83,7 @@ public class PreviewRenderEditor : Editor
camera
.
nearClipPlane
=
2.0f
;
camera
.
nearClipPlane
=
2.0f
;
camera
.
backgroundColor
=
new
Color
(
49.0f
/
255.0f
,
77.0f
/
255.0f
,
121.0f
/
255.0f
,
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
].
intensity
=
0.7f
;
_previewRenderUtility
.
lights
[
0
].
transform
.
rotation
=
Quaternion
.
Euler
(
_lightRot
.
x
,
_lightRot
.
y
,
0f
);
_previewRenderUtility
.
lights
[
0
].
transform
.
rotation
=
Quaternion
.
Euler
(
_lightRot
.
x
,
_lightRot
.
y
,
0f
);
_previewRenderUtility
.
lights
[
1
].
intensity
=
0.7f
;
_previewRenderUtility
.
lights
[
1
].
intensity
=
0.7f
;
...
@@ -101,7 +101,7 @@ public class PreviewRenderEditor : Editor
...
@@ -101,7 +101,7 @@ public class PreviewRenderEditor : Editor
// Drag2D 来自源码
// Drag2D 来自源码
private
static
int
sliderHash
=
"Slider"
.
GetHashCode
();
private
static
int
sliderHash
=
"Slider"
.
GetHashCode
();
p
ublic
static
Vector2
Drag2D
(
Vector2
scrollPosition
,
Rect
position
)
p
rivate
static
Vector2
Drag2D
(
Vector2
scrollPosition
,
Rect
position
)
{
{
// 每次获得独一无二的 controlID
// 每次获得独一无二的 controlID
int
controlID
=
GUIUtility
.
GetControlID
(
sliderHash
,
FocusType
.
Passive
);
int
controlID
=
GUIUtility
.
GetControlID
(
sliderHash
,
FocusType
.
Passive
);
...
...
UnityPreviewEditor/Assets/PreviewExample.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: d3282b6a4d7bc764093a9ebdd6da1892
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
UnityPreviewEditor/Assets/PreviewExample/Editor.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 15a92cf5efdc18143b700a35cef9c204
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
UnityPreviewEditor/Assets/PreviewExample/Editor/PreviewExampleInspector.cs
0 → 100644
浏览文件 @
a378e532
using
UnityEditor
;
using
UnityEngine
;
[
CustomEditor
(
typeof
(
PreviewExample
))]
public
class
PreviewExampleInspector
:
Editor
{
private
GameObject
_lastGameObj
;
private
bool
_canRefreshPreviewGo
=
false
;
private
Vector2
_drag
=
new
Vector2
(
250f
,
-
30f
);
private
Vector2
_lightRot
=
new
Vector2
(
180f
,
0
);
public
override
void
OnInspectorGUI
()
{
// target 当前操作的对象
PreviewExample
pe
=
(
PreviewExample
)
target
;
pe
.
previewGo
=
EditorGUILayout
.
ObjectField
(
"预览目标"
,
pe
.
previewGo
,
typeof
(
GameObject
))
as
GameObject
;
if
(
pe
.
previewGo
!=
_lastGameObj
)
{
_lastGameObj
=
pe
.
previewGo
;
_canRefreshPreviewGo
=
true
;
}
pe
.
lightRot
=
EditorGUILayout
.
Vector2Field
(
"光源角度"
,
pe
.
lightRot
);
_lightRot
=
pe
.
lightRot
;
serializedObject
.
ApplyModifiedProperties
();
}
public
override
bool
HasPreviewGUI
()
{
return
true
;
}
public
override
GUIContent
GetPreviewTitle
()
{
return
new
GUIContent
(
"预览"
);
}
public
override
void
OnPreviewSettings
()
{
GUILayout
.
Label
(
"文本"
,
"preLabel"
);
GUILayout
.
Button
(
"按钮"
,
"preButton"
);
}
public
override
void
OnPreviewGUI
(
Rect
r
,
GUIStyle
background
)
{
InitPreview
();
// 获取拖拽向量
_drag
=
Drag2D
(
_drag
,
r
);
if
(
Event
.
current
.
type
!=
EventType
.
Repaint
)
{
return
;
}
_previewRenderUtility
.
BeginPreview
(
r
,
background
);
//调整相机位置与角度
Camera
camera
=
_previewRenderUtility
.
camera
;
camera
.
clearFlags
=
CameraClearFlags
.
Skybox
;
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
);
// 设置光源数据
_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
.
Render
();
_previewRenderUtility
.
EndAndDrawPreview
(
r
);
}
private
PreviewRenderUtility
_previewRenderUtility
;
private
GameObject
_previewInstance
;
private
void
InitPreview
()
{
if
(
_previewRenderUtility
==
null
)
{
// 参数true代表绘制场景内的游戏对象
_previewRenderUtility
=
new
PreviewRenderUtility
(
true
);
// 设置摄像机的一些参数
_previewRenderUtility
.
cameraFieldOfView
=
30f
;
}
if
(
_canRefreshPreviewGo
)
{
_canRefreshPreviewGo
=
false
;
// 创建预览的游戏对象
CreatePreviewInstances
();
}
}
private
void
DestroyPreview
()
{
if
(
_previewRenderUtility
!=
null
)
{
// 务必要进行清理,才不会残留生成的摄像机对象等
_previewRenderUtility
.
Cleanup
();
_previewRenderUtility
=
null
;
}
}
private
void
CreatePreviewInstances
()
{
DestroyPreviewInstances
();
// 绘制预览的游戏对象
if
(
_lastGameObj
)
{
_previewInstance
=
Instantiate
(
_lastGameObj
);
_previewRenderUtility
.
AddSingleGO
(
_previewInstance
);
}
}
private
void
DestroyPreviewInstances
()
{
if
(
_previewInstance
)
{
DestroyImmediate
(
_previewInstance
);
}
_previewInstance
=
null
;
}
void
OnDestroy
()
{
DestroyPreviewInstances
();
DestroyPreview
();
}
// Drag2D 来自源码
private
static
int
sliderHash
=
"Slider"
.
GetHashCode
();
private
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
;
}
}
UnityPreviewEditor/Assets/PreviewExample/Editor/PreviewExampleInspector.cs.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 2f9601ed07e8b98409ad843aa4c10e2d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
UnityPreviewEditor/Assets/PreviewExample/Editor/PreviewExampleWindow.cs
0 → 100644
浏览文件 @
a378e532
using
UnityEngine
;
using
UnityEditor
;
public
class
PreviewExampleWindow
:
EditorWindow
{
private
Editor
m_Editor
;
[
MenuItem
(
"Example/PreviewExample"
)]
static
void
ShowWindow
()
{
GetWindow
<
PreviewExampleWindow
>(
"PreviewExample"
);
}
private
void
OnDestroy
()
{
if
(
m_Editor
!=
null
)
{
DestroyImmediate
(
m_Editor
);
}
m_Editor
=
null
;
}
void
OnGUI
()
{
if
(
m_Editor
==
null
)
{
// 第一个参数这里暂时没关系,因为编辑器没有取目标对象
m_Editor
=
Editor
.
CreateEditor
(
this
,
typeof
(
PreviewExampleInspector
));
}
m_Editor
.
DrawPreview
(
GUILayoutUtility
.
GetRect
(
300
,
200
));
}
}
\ No newline at end of file
UnityPreviewEditor/Assets/PreviewExample/Editor/PreviewExampleWindow.cs.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 30447c5b23aa946449627f4c1c58573a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
UnityPreviewEditor/Assets/PreviewExample/PreviewExample.cs
0 → 100644
浏览文件 @
a378e532
using
UnityEngine
;
public
class
PreviewExample
:
MonoBehaviour
{
public
GameObject
previewGo
;
public
Vector2
lightRot
;
}
\ No newline at end of file
UnityPreviewEditor/Assets/PreviewExample/PreviewExample.cs.meta
0 → 100644
浏览文件 @
a378e532
fileFormatVersion: 2
guid: 52e1416b880a27047b16f6098d52bde3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
UnityPreviewEditor/Assets/Scenes/SampleScene.unity
浏览文件 @
a378e532
...
@@ -38,7 +38,7 @@ RenderSettings:
...
@@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity
:
1
m_ReflectionIntensity
:
1
m_CustomReflection
:
{
fileID
:
0
}
m_CustomReflection
:
{
fileID
:
0
}
m_Sun
:
{
fileID
:
705507994
}
m_Sun
:
{
fileID
:
705507994
}
m_IndirectSpecularColor
:
{
r
:
0
,
g
:
0
,
b
:
0
,
a
:
1
}
m_IndirectSpecularColor
:
{
r
:
0
.44657898
,
g
:
0.4964133
,
b
:
0.5748178
,
a
:
1
}
m_UseRadianceAmbientProbe
:
0
m_UseRadianceAmbientProbe
:
0
---
!u!157
&3
---
!u!157
&3
LightmapSettings
:
LightmapSettings
:
...
@@ -118,6 +118,8 @@ NavMeshSettings:
...
@@ -118,6 +118,8 @@ NavMeshSettings:
manualTileSize
:
0
manualTileSize
:
0
tileSize
:
256
tileSize
:
256
accuratePlacement
:
0
accuratePlacement
:
0
maxJobWorkers
:
0
preserveTilesOutsideBounds
:
0
debug
:
debug
:
m_Flags
:
0
m_Flags
:
0
m_NavMeshData
:
{
fileID
:
0
}
m_NavMeshData
:
{
fileID
:
0
}
...
@@ -125,7 +127,8 @@ NavMeshSettings:
...
@@ -125,7 +127,8 @@ NavMeshSettings:
GameObject
:
GameObject
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInternal
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
serializedVersion
:
6
serializedVersion
:
6
m_Component
:
m_Component
:
-
component
:
{
fileID
:
705507995
}
-
component
:
{
fileID
:
705507995
}
...
@@ -141,15 +144,18 @@ GameObject:
...
@@ -141,15 +144,18 @@ GameObject:
Light
:
Light
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInternal
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
705507993
}
m_GameObject
:
{
fileID
:
705507993
}
m_Enabled
:
1
m_Enabled
:
1
serializedVersion
:
8
serializedVersion
:
10
m_Type
:
1
m_Type
:
1
m_Shape
:
0
m_Color
:
{
r
:
1
,
g
:
0.95686275
,
b
:
0.8392157
,
a
:
1
}
m_Color
:
{
r
:
1
,
g
:
0.95686275
,
b
:
0.8392157
,
a
:
1
}
m_Intensity
:
1
m_Intensity
:
1
m_Range
:
10
m_Range
:
10
m_SpotAngle
:
30
m_SpotAngle
:
30
m_InnerSpotAngle
:
21.80208
m_CookieSize
:
10
m_CookieSize
:
10
m_Shadows
:
m_Shadows
:
m_Type
:
2
m_Type
:
2
...
@@ -159,6 +165,24 @@ Light:
...
@@ -159,6 +165,24 @@ Light:
m_Bias
:
0.05
m_Bias
:
0.05
m_NormalBias
:
0.4
m_NormalBias
:
0.4
m_NearPlane
:
0.2
m_NearPlane
:
0.2
m_CullingMatrixOverride
:
e00
:
1
e01
:
0
e02
:
0
e03
:
0
e10
:
0
e11
:
1
e12
:
0
e13
:
0
e20
:
0
e21
:
0
e22
:
1
e23
:
0
e30
:
0
e31
:
0
e32
:
0
e33
:
1
m_UseCullingMatrixOverride
:
0
m_Cookie
:
{
fileID
:
0
}
m_Cookie
:
{
fileID
:
0
}
m_DrawHalo
:
0
m_DrawHalo
:
0
m_Flare
:
{
fileID
:
0
}
m_Flare
:
{
fileID
:
0
}
...
@@ -166,19 +190,24 @@ Light:
...
@@ -166,19 +190,24 @@ Light:
m_CullingMask
:
m_CullingMask
:
serializedVersion
:
2
serializedVersion
:
2
m_Bits
:
4294967295
m_Bits
:
4294967295
m_RenderingLayerMask
:
1
m_Lightmapping
:
1
m_Lightmapping
:
1
m_LightShadowCasterMode
:
0
m_LightShadowCasterMode
:
0
m_AreaSize
:
{
x
:
1
,
y
:
1
}
m_AreaSize
:
{
x
:
1
,
y
:
1
}
m_BounceIntensity
:
1
m_BounceIntensity
:
1
m_ColorTemperature
:
6570
m_ColorTemperature
:
6570
m_UseColorTemperature
:
0
m_UseColorTemperature
:
0
m_BoundingSphereOverride
:
{
x
:
0
,
y
:
0
,
z
:
0
,
w
:
0
}
m_UseBoundingSphereOverride
:
0
m_UseViewFrustumForShadowCasterCull
:
1
m_ShadowRadius
:
0
m_ShadowRadius
:
0
m_ShadowAngle
:
0
m_ShadowAngle
:
0
---
!u!4
&705507995
---
!u!4
&705507995
Transform
:
Transform
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInternal
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
705507993
}
m_GameObject
:
{
fileID
:
705507993
}
m_LocalRotation
:
{
x
:
0.40821788
,
y
:
-0.23456968
,
z
:
0.10938163
,
w
:
0.8754261
}
m_LocalRotation
:
{
x
:
0.40821788
,
y
:
-0.23456968
,
z
:
0.10938163
,
w
:
0.8754261
}
m_LocalPosition
:
{
x
:
0
,
y
:
3
,
z
:
0
}
m_LocalPosition
:
{
x
:
0
,
y
:
3
,
z
:
0
}
...
@@ -191,7 +220,8 @@ Transform:
...
@@ -191,7 +220,8 @@ Transform:
GameObject
:
GameObject
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInternal
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
serializedVersion
:
6
serializedVersion
:
6
m_Component
:
m_Component
:
-
component
:
{
fileID
:
963194228
}
-
component
:
{
fileID
:
963194228
}
...
@@ -208,23 +238,26 @@ GameObject:
...
@@ -208,23 +238,26 @@ GameObject:
AudioListener
:
AudioListener
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInternal
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
963194225
}
m_GameObject
:
{
fileID
:
963194225
}
m_Enabled
:
1
m_Enabled
:
1
---
!u!20
&963194227
---
!u!20
&963194227
Camera
:
Camera
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInternal
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
963194225
}
m_GameObject
:
{
fileID
:
963194225
}
m_Enabled
:
1
m_Enabled
:
1
serializedVersion
:
2
serializedVersion
:
2
m_ClearFlags
:
1
m_ClearFlags
:
1
m_BackGroundColor
:
{
r
:
0.19215687
,
g
:
0.3019608
,
b
:
0.4745098
,
a
:
0
}
m_BackGroundColor
:
{
r
:
0.19215687
,
g
:
0.3019608
,
b
:
0.4745098
,
a
:
0
}
m_projectionMatrixMode
:
1
m_projectionMatrixMode
:
1
m_GateFitMode
:
2
m_FOVAxisMode
:
0
m_SensorSize
:
{
x
:
36
,
y
:
24
}
m_SensorSize
:
{
x
:
36
,
y
:
24
}
m_LensShift
:
{
x
:
0
,
y
:
0
}
m_LensShift
:
{
x
:
0
,
y
:
0
}
m_GateFitMode
:
2
m_FocalLength
:
50
m_FocalLength
:
50
m_NormalizedViewPortRect
:
m_NormalizedViewPortRect
:
serializedVersion
:
2
serializedVersion
:
2
...
@@ -256,7 +289,8 @@ Camera:
...
@@ -256,7 +289,8 @@ Camera:
Transform
:
Transform
:
m_ObjectHideFlags
:
0
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInternal
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
963194225
}
m_GameObject
:
{
fileID
:
963194225
}
m_LocalRotation
:
{
x
:
0
,
y
:
0
,
z
:
0
,
w
:
1
}
m_LocalRotation
:
{
x
:
0
,
y
:
0
,
z
:
0
,
w
:
1
}
m_LocalPosition
:
{
x
:
0
,
y
:
1
,
z
:
-10
}
m_LocalPosition
:
{
x
:
0
,
y
:
1
,
z
:
-10
}
...
@@ -265,3 +299,48 @@ Transform:
...
@@ -265,3 +299,48 @@ Transform:
m_Father
:
{
fileID
:
0
}
m_Father
:
{
fileID
:
0
}
m_RootOrder
:
0
m_RootOrder
:
0
m_LocalEulerAnglesHint
:
{
x
:
0
,
y
:
0
,
z
:
0
}
m_LocalEulerAnglesHint
:
{
x
:
0
,
y
:
0
,
z
:
0
}
---
!u!1
&2025848853
GameObject
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
serializedVersion
:
6
m_Component
:
-
component
:
{
fileID
:
2025848854
}
-
component
:
{
fileID
:
2025848855
}
m_Layer
:
0
m_Name
:
PreviewExample
m_TagString
:
Untagged
m_Icon
:
{
fileID
:
0
}
m_NavMeshLayer
:
0
m_StaticEditorFlags
:
0
m_IsActive
:
1
---
!u!4
&2025848854
Transform
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
2025848853
}
m_LocalRotation
:
{
x
:
0
,
y
:
0
,
z
:
0
,
w
:
1
}
m_LocalPosition
:
{
x
:
0
,
y
:
0
,
z
:
0
}
m_LocalScale
:
{
x
:
1
,
y
:
1
,
z
:
1
}
m_Children
:
[]
m_Father
:
{
fileID
:
0
}
m_RootOrder
:
2
m_LocalEulerAnglesHint
:
{
x
:
0
,
y
:
0
,
z
:
0
}
---
!u!114
&2025848855
MonoBehaviour
:
m_ObjectHideFlags
:
0
m_CorrespondingSourceObject
:
{
fileID
:
0
}
m_PrefabInstance
:
{
fileID
:
0
}
m_PrefabAsset
:
{
fileID
:
0
}
m_GameObject
:
{
fileID
:
2025848853
}
m_Enabled
:
1
m_EditorHideFlags
:
0
m_Script
:
{
fileID
:
11500000
,
guid
:
52e1416b880a27047b16f6098d52bde3
,
type
:
3
}
m_Name
:
m_EditorClassIdentifier
:
previewGo
:
{
fileID
:
6569321644736967870
,
guid
:
9982c14b1dcece344b5aa928834f2f3a
,
type
:
3
}
lightRot
:
{
x
:
3.08
,
y
:
130.93
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录