Exemple #1
0
        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();
                }
            }
        }
Exemple #2
0
        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();
        }