5
5
using UnityEditor ;
6
6
using System . Linq ;
7
7
using System ;
8
+ using FbxExporters . Editor ;
9
+ using UnityEngine . TestTools ;
8
10
9
11
namespace FbxExporters
10
12
{
@@ -30,14 +32,18 @@ namespace FbxExporters
30
32
#else
31
33
public const string FBX_PREFAB_FILE = "/UnityFbxPrefab.dll" ;
32
34
#endif
35
+
36
+ const string MenuItemName = "GameObject/Update from FBX" ;
37
+ public static bool runningUnitTest = false ;
38
+
33
39
public static string FindFbxPrefabAssetPath ( )
34
40
{
35
41
// Find guids that are scripts that look like FbxPrefab.
36
42
// That catches FbxPrefabTest too, so we have to make sure.
37
43
var allGuids = AssetDatabase . FindAssets ( "FbxPrefab t:MonoScript" ) ;
38
- foreach ( var guid in allGuids ) {
44
+ foreach ( var guid in allGuids ) {
39
45
var path = AssetDatabase . GUIDToAssetPath ( guid ) ;
40
- if ( path . EndsWith ( FBX_PREFAB_FILE ) ) {
46
+ if ( path . EndsWith ( FBX_PREFAB_FILE ) ) {
41
47
return path ;
42
48
}
43
49
}
@@ -65,7 +71,7 @@ public static bool MayHaveFbxPrefabToFbxAsset(string prefabPath,
65
71
var depPaths = AssetDatabase . GetDependencies ( prefabPath , recursive : false ) ;
66
72
bool dependsOnFbxPrefab = false ;
67
73
bool dependsOnImportedFbx = false ;
68
- foreach ( var dep in depPaths ) {
74
+ foreach ( var dep in depPaths ) {
69
75
if ( dep == fbxPrefabScriptPath ) {
70
76
if ( dependsOnImportedFbx ) { return true ; }
71
77
dependsOnFbxPrefab = true ;
@@ -79,7 +85,7 @@ public static bool MayHaveFbxPrefabToFbxAsset(string prefabPath,
79
85
return false ;
80
86
}
81
87
82
- static void OnPostprocessAllAssets ( string [ ] imported , string [ ] deleted , string [ ] moved , string [ ] movedFrom )
88
+ static void OnPostprocessAllAssets ( string [ ] imported , string [ ] deleted , string [ ] moved , string [ ] movedFrom )
83
89
{
84
90
// Do not start if Auto Updater is disabled in FBX Exporter Settings
85
91
if ( ! FbxExporters . EditorTools . ExportSettings . instance . autoUpdaterEnabled )
@@ -92,9 +98,12 @@ static void OnPostprocessAllAssets(string [] imported, string [] deleted, string
92
98
// Did we import an fbx file at all?
93
99
// Optimize to not allocate in the common case of 'no'
94
100
HashSet < string > fbxImported = null ;
95
- foreach ( var fbxModel in imported ) {
101
+ foreach ( var fbxModel in imported ) {
96
102
if ( IsFbxAsset ( fbxModel ) ) {
97
- if ( fbxImported == null ) { fbxImported = new HashSet < string > ( ) ; }
103
+ if ( fbxImported == null )
104
+ {
105
+ fbxImported = new HashSet < string > ( ) ;
106
+ }
98
107
fbxImported . Add ( fbxModel ) ;
99
108
//Debug.Log("Tracking fbx asset " + fbxModel);
100
109
} else {
@@ -116,7 +125,7 @@ static void OnPostprocessAllAssets(string [] imported, string [] deleted, string
116
125
//
117
126
var fbxPrefabScriptPath = FindFbxPrefabAssetPath ( ) ;
118
127
var allObjectGuids = AssetDatabase . FindAssets ( "t:GameObject" ) ;
119
- foreach ( var guid in allObjectGuids ) {
128
+ foreach ( var guid in allObjectGuids ) {
120
129
var prefabPath = AssetDatabase . GUIDToAssetPath ( guid ) ;
121
130
if ( ! IsPrefabAsset ( prefabPath ) ) {
122
131
//Debug.Log("Not a prefab: " + prefabPath);
@@ -140,8 +149,8 @@ static void OnPostprocessAllAssets(string [] imported, string [] deleted, string
140
149
//Debug.LogWarning("FbxPrefab reimport: failed to update prefab " + prefabPath);
141
150
continue ;
142
151
}
143
- foreach ( var fbxPrefabComponent in prefab . GetComponentsInChildren < FbxPrefab > ( ) ) {
144
- var fbxPrefabUtility = new FbxPrefabUtility ( fbxPrefabComponent ) ;
152
+ foreach ( var fbxPrefabComponent in prefab . GetComponentsInChildren < FbxPrefab > ( ) ) {
153
+ var fbxPrefabUtility = new FbxPrefabUtility ( fbxPrefabComponent ) ;
145
154
if ( ! fbxPrefabUtility . WantsAutoUpdate ( ) ) {
146
155
//Debug.Log("Not auto-updating " + prefabPath);
147
156
continue ;
@@ -156,8 +165,89 @@ static void OnPostprocessAllAssets(string [] imported, string [] deleted, string
156
165
}
157
166
}
158
167
}
168
+ /// <summary>
169
+ /// Add an option "Update from FBX" in the contextual GameObject menu.
170
+ /// </summary>
171
+ [ MenuItem ( MenuItemName , false , 31 ) ]
172
+ static void OnContextItem ( MenuCommand command )
173
+ {
174
+ GameObject [ ] selection = null ;
175
+
176
+ if ( command == null || command . context == null )
177
+ {
178
+ // We were actually invoked from the top GameObject menu, so use the selection.
179
+ selection = Selection . GetFiltered < GameObject > ( SelectionMode . Editable | SelectionMode . TopLevel ) ;
180
+ }
181
+ else
182
+ {
183
+ // We were invoked from the right-click menu, so use the context of the context menu.
184
+ var selected = command . context as GameObject ;
185
+ if ( selected )
186
+ {
187
+ selection = new GameObject [ ] { selected } ;
188
+ }
189
+ }
190
+
191
+ foreach ( GameObject selectedObject in selection )
192
+ {
193
+ UpdateLinkedPrefab ( selectedObject ) ;
194
+ }
195
+ }
196
+
197
+ /// <summary>
198
+ /// Validate the menu item defined by the function above.
199
+ /// </summary>
200
+ [ MenuItem ( MenuItemName , true , 31 ) ]
201
+ public static bool OnValidateMenuItem ( )
202
+ {
203
+ GameObject [ ] selection = Selection . gameObjects ;
204
+
205
+ if ( selection == null || selection . Length == 0 )
206
+ {
207
+ return false ;
208
+ }
209
+
210
+ bool containsLinkedPrefab = false ;
211
+ foreach ( GameObject selectedObject in selection )
212
+ {
213
+ GameObject prefab = UnityEditor . PrefabUtility . GetPrefabParent ( selectedObject ) as GameObject ;
214
+ if ( prefab && prefab . GetComponentInChildren < FbxPrefab > ( ) )
215
+ {
216
+ containsLinkedPrefab = true ;
217
+ break ;
218
+ }
219
+ }
220
+
221
+ return containsLinkedPrefab ;
222
+ }
159
223
160
224
225
+ static void DisplayNoSelectionDialog ( string message )
226
+ {
227
+ UnityEditor . EditorUtility . DisplayDialog (
228
+ string . Format ( "{0} Warning" , ModelExporter . PACKAGE_UI_NAME ) ,
229
+ message ,
230
+ "Ok" ) ;
231
+ }
232
+
233
+ /// <summary>
234
+ /// Launch the manual update of the linked prefab specified
235
+ /// </summary>
236
+ public static void UpdateLinkedPrefab ( GameObject prefabInstance )
237
+ {
238
+ GameObject prefab = UnityEditor . PrefabUtility . GetPrefabParent ( prefabInstance ) as GameObject ;
239
+ if ( ! prefab )
240
+ {
241
+ return ;
242
+ }
243
+
244
+ foreach ( var fbxPrefabComponent in prefab . GetComponentsInChildren < FbxPrefab > ( ) )
245
+ {
246
+ var fbxPrefabUtility = new FbxPrefabUtility ( fbxPrefabComponent ) ;
247
+ fbxPrefabUtility . SyncPrefab ( ) ;
248
+ }
249
+ }
250
+
161
251
public class FbxPrefabUtility {
162
252
163
253
private FbxPrefab m_fbxPrefab ;
0 commit comments