1
1
using System ;
2
2
using System . Linq ;
3
+ using System . Reflection ;
3
4
using UnityEditor . Experimental . SceneManagement ;
4
5
using UnityEngine ;
5
6
using UnityEngine . ProBuilder ;
@@ -18,6 +19,11 @@ namespace UnityEditor.ProBuilder
18
19
/// </summary>
19
20
sealed class ShapeEditor : ConfigurableWindow
20
21
{
22
+ static class Styles
23
+ {
24
+ public static readonly GUIStyle options = "PaneOptions" ;
25
+ }
26
+
21
27
abstract class ShapeBuilder
22
28
{
23
29
public virtual string name
@@ -28,6 +34,22 @@ public virtual string name
28
34
public abstract void OnGUI ( ) ;
29
35
30
36
public abstract ProBuilderMesh Build ( bool isPreview = false ) ;
37
+
38
+ public void ResetParameters ( )
39
+ {
40
+ var members = GetType ( ) . GetFields ( BindingFlags . Static | BindingFlags . Public | BindingFlags . NonPublic ) ;
41
+
42
+ foreach ( var fi in members )
43
+ {
44
+ if ( fi . GetValue ( this ) is IUserSetting setting )
45
+ setting . Reset ( ) ;
46
+ // if(fi.FieldType.BaseType?.GetGenericTypeDefinition() == typeof(UserSetting<>))
47
+ // {
48
+ // var setting = fi.GetValue(this) as IUserSetting;
49
+ // Debug.Log($"Name: {fi.Name}\nType: {fi.FieldType}\nValue {fi.GetValue(this)}");
50
+ // }
51
+ }
52
+ }
31
53
}
32
54
33
55
public static void MenuOpenShapeCreator ( )
@@ -71,7 +93,7 @@ void OnEnable()
71
93
m_ShapeTypes = s_ShapeBuilders . Select ( x => x . name ) . ToArray ( ) ;
72
94
// Delaying the call til end of frame fixes an issue where entering play mode would cause the preview object
73
95
// to not appear in the Hierarchy until the Shape Editor is interacted with.
74
- EditorApplication . delayCall += ( ) => SetPreviewMesh ( s_ShapeBuilders [ s_CurrentIndex ] . Build ( ) ) ;
96
+ EditorApplication . delayCall += ( ) => SetPreviewMesh ( GetActiveShapeBuilder ( ) . Build ( ) ) ;
75
97
EditorApplication . playModeStateChanged += PlayModeStateChanged ;
76
98
}
77
99
@@ -86,7 +108,7 @@ void OnDisable()
86
108
void PlayModeStateChanged ( PlayModeStateChange state )
87
109
{
88
110
if ( state == PlayModeStateChange . EnteredEditMode )
89
- SetPreviewMesh ( s_ShapeBuilders [ s_CurrentIndex ] . Build ( ) ) ;
111
+ SetPreviewMesh ( GetActiveShapeBuilder ( ) . Build ( ) ) ;
90
112
}
91
113
92
114
void PrefabStageOpened ( PrefabStage stage )
@@ -126,11 +148,16 @@ void OnGUI()
126
148
127
149
s_CurrentIndex . value = EditorGUILayout . Popup ( s_CurrentIndex , m_ShapeTypes ) ;
128
150
151
+ GUILayout . BeginHorizontal ( ) ;
129
152
GUILayout . Label ( "Shape Settings" , EditorStyles . boldLabel ) ;
153
+ GUILayout . FlexibleSpace ( ) ;
154
+ if ( GUILayout . Button ( GUIContent . none , Styles . options ) )
155
+ ShapeBuilderOptions ( GetActiveShapeBuilder ( ) ) ;
156
+ GUILayout . EndHorizontal ( ) ;
130
157
131
158
m_Scroll = EditorGUILayout . BeginScrollView ( m_Scroll ) ;
132
159
133
- var shape = s_ShapeBuilders [ s_CurrentIndex ] ;
160
+ var shape = GetActiveShapeBuilder ( ) ;
134
161
135
162
shape . OnGUI ( ) ;
136
163
@@ -154,8 +181,10 @@ void CreateSelectedShape(bool forceCloseWindow = false)
154
181
ApplyPreviewTransform ( res ) ;
155
182
DestroyPreviewObject ( true ) ;
156
183
157
- if ( forceCloseWindow || s_CloseWindowAfterCreateShape )
184
+ if ( forceCloseWindow || s_CloseWindowAfterCreateShape )
158
185
Close ( ) ;
186
+ else
187
+ ResetPreviewAfterShapeCreation ( res ) ;
159
188
}
160
189
161
190
/// <summary>
@@ -170,6 +199,21 @@ public static ProBuilderMesh CreateActiveShape()
170
199
return res ;
171
200
}
172
201
202
+ // Reinitialize the shape preview and move it to the right a bit so that it is visible
203
+ void ResetPreviewAfterShapeCreation ( ProBuilderMesh lastInstantiatedMesh )
204
+ {
205
+ RebuildPreview ( ) ;
206
+
207
+ if ( lastInstantiatedMesh != null )
208
+ {
209
+ var src = lastInstantiatedMesh . transform ;
210
+ var dst = m_PreviewObject . transform ;
211
+ dst . position = src . position + Vector3 . right ;
212
+ dst . localRotation = src . localRotation ;
213
+ dst . localScale = src . localScale ;
214
+ }
215
+ }
216
+
173
217
void DestroyPreviewObject ( bool immediate )
174
218
{
175
219
if ( immediate )
@@ -178,6 +222,27 @@ void DestroyPreviewObject(bool immediate)
178
222
EditorApplication . delayCall += DestroyPreviewObjectInternal ;
179
223
}
180
224
225
+ void ShapeBuilderOptions ( ShapeBuilder builder )
226
+ {
227
+ var menu = new GenericMenu ( ) ;
228
+ menu . AddItem ( new GUIContent ( "Reset" , "Reset the selected Shape parameters." ) , false , ( ) =>
229
+ {
230
+ builder . ResetParameters ( ) ;
231
+ RebuildPreview ( ) ;
232
+ } ) ;
233
+ menu . ShowAsContext ( ) ;
234
+ }
235
+
236
+ static ShapeBuilder GetActiveShapeBuilder ( )
237
+ {
238
+ return s_ShapeBuilders [ PMath . Clamp ( s_CurrentIndex , 0 , s_ShapeBuilders . Length - 1 ) ] ;
239
+ }
240
+
241
+ public void RebuildPreview ( )
242
+ {
243
+ SetPreviewMesh ( GetActiveShapeBuilder ( ) . Build ( ) ) ;
244
+ }
245
+
181
246
void DestroyPreviewObjectInternal ( )
182
247
{
183
248
if ( m_PreviewObject != null )
@@ -239,20 +304,14 @@ void SetPreviewMesh(ProBuilderMesh mesh)
239
304
240
305
void ApplyPreviewTransform ( ProBuilderMesh mesh )
241
306
{
242
- var position = Vector3 . zero ;
243
- var scale = Vector3 . one ;
244
- var rotation = Quaternion . identity ;
245
307
var previous = m_PreviewObject != null ;
246
308
247
309
if ( previous )
248
310
{
249
- position = m_PreviewObject . transform . position ;
250
- rotation = m_PreviewObject . transform . localRotation ;
251
- scale = m_PreviewObject . transform . localScale ;
252
-
253
- mesh . transform . position = position ;
254
- mesh . transform . localRotation = rotation ;
255
- mesh . transform . localScale = scale ;
311
+ var trs = mesh . transform ;
312
+ trs . position = m_PreviewObject . transform . position ;
313
+ trs . localRotation = m_PreviewObject . transform . localRotation ;
314
+ trs . localScale = m_PreviewObject . transform . localScale ;
256
315
}
257
316
else
258
317
{
0 commit comments