public static void UpdateLinkedPrefab(GameObject prefabOrInstance) { // Find the prefab, bail if this is neither a prefab nor an instance. GameObject prefab; switch (PrefabUtility.GetPrefabType(prefabOrInstance)) { case PrefabType.Prefab: prefab = prefabOrInstance; break; case PrefabType.PrefabInstance: prefab = PrefabUtility.GetCorrespondingObjectFromSource(prefabOrInstance) as GameObject; break; default: return; } foreach (var fbxPrefabComponent in prefab.GetComponentsInChildren <FbxPrefab>()) { // Launch the manual update UI to allow the user to fix // renamed nodes (or auto-update if there's nothing to rename). var fbxPrefabUtility = new FbxPrefabUtility(fbxPrefabComponent); if (UnityEditor.Formats.Fbx.Exporter.ExportSettings.instance.AutoUpdaterEnabled || runningUnitTest) { fbxPrefabUtility.SyncPrefab(); } else { ManualUpdateEditorWindow window = (ManualUpdateEditorWindow)EditorWindow.GetWindow(typeof(ManualUpdateEditorWindow)); window.Init(fbxPrefabUtility, fbxPrefabComponent); window.Show(); } } }
static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[] moved, string[] movedFrom) { // Do not start if Auto Updater is disabled in FBX Exporter Settings if (!UnityEditor.Formats.Fbx.Exporter.ExportSettings.instance.AutoUpdaterEnabled) { return; } if (Verbose) { Debug.Log("Postprocessing..."); } // Did we import an fbx file at all? // Optimize to not allocate in the common case of 'no' HashSet <string> fbxImported = null; foreach (var fbxModel in imported) { if (IsFbxAsset(fbxModel)) { if (fbxImported == null) { fbxImported = new HashSet <string>(); } fbxImported.Add(fbxModel); if (Verbose) { Debug.Log("Tracking fbx asset " + fbxModel); } } else { if (Verbose) { Debug.Log("Not an fbx asset " + fbxModel); } } } if (fbxImported == null) { if (Verbose) { Debug.Log("No fbx imported"); } return; } // // Iterate over all the prefabs that have an FbxPrefab component that // points to an FBX file that got (re)-imported. // // There's no one-line query to get those, so we search for a much // larger set and whittle it down, hopefully without needing to // load the asset into memory if it's not necessary. // var fbxPrefabScriptPath = FindFbxPrefabAssetPath(); var allObjectGuids = AssetDatabase.FindAssets("t:GameObject"); foreach (var guid in allObjectGuids) { var prefabPath = AssetDatabase.GUIDToAssetPath(guid); if (!IsPrefabAsset(prefabPath)) { if (Verbose) { Debug.Log("Not a prefab: " + prefabPath); } continue; } if (!MayHaveFbxPrefabToFbxAsset(prefabPath, fbxPrefabScriptPath, fbxImported)) { if (Verbose) { Debug.Log("No dependence: " + prefabPath); } continue; } if (Verbose) { Debug.Log("Considering updating prefab " + prefabPath); } // We're now guaranteed that this is a prefab, and it depends // on the FbxPrefab script, and it depends on an Fbx file that // was imported. // // To be sure it has an FbxPrefab component that points to an // Fbx file, we need to load the asset (which we need to do to // update the prefab anyway). var prefab = AssetDatabase.LoadMainAssetAtPath(prefabPath) as GameObject; if (!prefab) { if (Verbose) { Debug.LogWarning("FbxPrefab reimport: failed to update prefab " + prefabPath); } continue; } foreach (var fbxPrefabComponent in prefab.GetComponentsInChildren <FbxPrefab>()) { var fbxPrefabUtility = new FbxPrefabUtility(fbxPrefabComponent); if (!fbxPrefabUtility.WantsAutoUpdate()) { if (Verbose) { Debug.Log("Not auto-updating " + prefabPath); } continue; } var fbxAssetPath = fbxPrefabUtility.FbxAssetPath; if (!fbxImported.Contains(fbxAssetPath)) { if (Verbose) { Debug.Log("False-positive dependence: " + prefabPath + " via " + fbxAssetPath); } continue; } if (Verbose) { Debug.Log("Updating " + prefabPath + "..."); } fbxPrefabUtility.SyncPrefab(); } } }
void OnGUI() { // If there is nothing to map, sync prefab automatically and close the window if (m_nodesToDestroy.Count == 0 && m_nodesToRename.Count == 0) { m_fbxPrefabUtility.SyncPrefab(); Close(); } //Titles of the columns GUILayout.BeginHorizontal(); GUILayout.Label("Unity Names", EditorStyles.boldLabel); GUILayout.Label("FBX Names", EditorStyles.boldLabel); GUILayout.EndHorizontal(); // List of nodes that will be destroyed on the Unity object, unless the user wants to map them for (int i = 0; i < m_nodesToDestroy.Count; i++) { GUILayout.BeginHorizontal(); EditorGUILayout.LabelField(m_nodesToDestroy[i]); List <GUIContent> listFbxNames = new List <GUIContent>(); listFbxNames.Add(new GUIContent("[Delete]")); for (int j = 0; j < m_nodeNameToSuggest.Count; j++) { listFbxNames.Add(new GUIContent(m_fbxPrefabUtility.GetFBXObjectName(m_nodeNameToSuggest[j]))); } options = listFbxNames.ToArray(); selectedNodesToDestroy[i] = EditorGUILayout.Popup(selectedNodesToDestroy[i], options); GUILayout.EndHorizontal(); } // List of nodes that will be renamed on the Unity object, unless the user wants to map them or delete them for (int i = 0; i < m_nodesToRename.Count; i++) { GUILayout.BeginHorizontal(); EditorGUILayout.LabelField(m_fbxPrefabUtility.GetUnityObjectName(m_nodesToRename[i])); List <GUIContent> listFbxNames = new List <GUIContent>(); listFbxNames.Add(new GUIContent("[Delete]")); for (int j = 0; j < m_nodeNameToSuggest.Count; j++) { listFbxNames.Add(new GUIContent(m_fbxPrefabUtility.GetFBXObjectName(m_nodeNameToSuggest[j]))); } options = listFbxNames.ToArray(); selectedNodesToRename[i] = EditorGUILayout.Popup(selectedNodesToRename[i], options); GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); if (GUILayout.Button("Apply Changes")) { ApplyChanges(); //Close editor window Close(); } if (GUILayout.Button("Cancel")) { //Close editor window Close(); } GUILayout.EndHorizontal(); }