コード例 #1
0
        private static void UpdateAssets()
        {
            updateStarted?.Invoke();

            EditorUtility.DisplayProgressBar("Updating connectivity", "Getting ready", 0.0f);
            updating = true;

            var activeScene     = SceneManager.GetActiveScene();
            var activeScenePath = activeScene.path;

            CheckConnectivityFeatureLayer.CreateReceptorLayer();
            CheckConnectivityFeatureLayer.CreateConnectorLayer();

            // 1. Update connectivity prefabs.
            string[] guids = AssetDatabase.FindAssets("", new string[] { PartUtility.connectivityPath });

            for (int i = 0; i < guids.Length; i++)
            {
                EditorUtility.DisplayProgressBar("Updating connectivity", "Updating connectivity prefabs", 0.25f * i / guids.Length);

                string       assetPath    = AssetDatabase.GUIDToAssetPath(guids[i]);
                Connectivity connectivity = AssetDatabase.LoadAssetAtPath <Connectivity>(assetPath);
                if (connectivity)
                {
                    if (connectivity.version == 0 && currentVersion == 1)
                    {
                        ConvertVersion_0_To_1(connectivity);
                    }
                }
            }

            // 2. Run through all prefabs and determine dependency graph based on nesting. Also collect all scene paths for later processing.
            string[]      allAssetPaths = AssetDatabase.GetAllAssetPaths();
            List <string> scenes        = new List <string>();
            var           index         = 0;

            var dependencyGraph         = new DirectedGraph <string>();
            var existingDependencyNodes = new Dictionary <string, DirectedGraph <string> .Node>();

            foreach (var path in allAssetPaths)
            {
                EditorUtility.DisplayProgressBar("Updating connectivity", "Detecting prefab dependencies", 0.25f + 0.25f * index++ / allAssetPaths.Length);

                int pos = path.IndexOf("/", StringComparison.Ordinal);
                if (pos < 0 || path.Substring(0, pos) == "Packages")
                {
                    continue;   // Skip assets in packages.
                }
                if (path.StartsWith(PartUtility.connectivityPath))
                {
                    continue;   // Skip connectivity assets.
                }
                if (path.StartsWith(PartUtility.collidersPath))
                {
                    continue;   // Skip collider assets.
                }
                if (path.StartsWith(PartUtility.geometryPath))
                {
                    continue;   // Skip geometry assets.
                }
                pos = path.LastIndexOf(".", StringComparison.Ordinal) + 1;
                string type = path.Substring(pos, path.Length - pos);

                switch (type)
                {
                case "prefab":
                {
                    var contents = PrefabUtility.LoadPrefabContents(path);

                    var bricks = contents.GetComponentsInChildren <Brick>(true);

                    if (bricks.Length > 0)
                    {
                        FindDependencies(path, bricks, existingDependencyNodes, dependencyGraph);
                    }

                    PrefabUtility.UnloadPrefabContents(contents);
                }
                break;

                case "unity":
                {
                    scenes.Add(path);
                }
                break;
                }
            }

            // 3. Run through dependency sorted prefabs and update+connect connectivity on non-prefab instances.
            var sortedNodes = dependencyGraph.TopologicalSort();

            index = 0;
            foreach (var node in sortedNodes)
            {
                EditorUtility.DisplayProgressBar("Updating connectivity", "Updating prefabs", 0.5f + 0.25f * index++ / sortedNodes.Count);

                var contents = PrefabUtility.LoadPrefabContents(node.data);

                var bricks = contents.GetComponentsInChildren <Brick>(true);

                if (bricks.Length > 0)
                {
                    if (UpdateConnections(bricks))
                    {
                        Debug.Log(node.data + " Updated");
                    }
                    FixConnections(bricks);

                    PrefabUtility.SaveAsPrefabAsset(contents, node.data);
                }

                PrefabUtility.UnloadPrefabContents(contents);
            }

            // 4. Run through all scenes and update+connect connectivity on non-prefab instances.
            index = 0;
            foreach (var path in scenes)
            {
                EditorUtility.DisplayProgressBar("Updating connectivity", "Updating scenes", 0.75f + 0.25f * index++ / scenes.Count);

                Scene scene = EditorSceneManager.OpenScene(path);

                var gameObjectsInScene = scene.GetRootGameObjects();

                foreach (var gameObject in gameObjectsInScene)
                {
                    if (PrefabUtility.IsPartOfAnyPrefab(gameObject))
                    {
                        continue;
                    }

                    var bricks = gameObject.GetComponentsInChildren <Brick>(true);

                    if (bricks.Length > 0)
                    {
                        if (UpdateConnections(bricks))
                        {
                            Debug.Log($" -------- {gameObject.name} Updated");
                        }
                        FixConnections(bricks);
                    }
                }
                EditorSceneManager.SaveScene(scene);
            }

            if (activeScenePath.Length != 0)
            {
                EditorSceneManager.OpenScene(activeScenePath);
            }

            updating = false;
            EditorUtility.ClearProgressBar();

            updateFinished?.Invoke();
        }
コード例 #2
0
        private static void FindDependencies(string assetPath, Brick[] bricks, Dictionary <string, DirectedGraph <string> .Node> existingNodes, DirectedGraph <string> dependencyGraph)
        {
            DirectedGraph <string> .Node node;
            if (!existingNodes.ContainsKey(assetPath))
            {
                node = new DirectedGraph <string> .Node()
                {
                    data = assetPath
                };
                existingNodes.Add(assetPath, node);
                dependencyGraph.AddNode(node);
            }
            else
            {
                node = existingNodes[assetPath];
            }

            foreach (var brick in bricks)
            {
                if (PrefabUtility.IsPartOfPrefabInstance(brick))
                {
                    var dependencyAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(brick);

                    DirectedGraph <string> .Node dependencyNode;
                    if (!existingNodes.ContainsKey(dependencyAssetPath))
                    {
                        dependencyNode = new DirectedGraph <string> .Node()
                        {
                            data = dependencyAssetPath
                        };
                        existingNodes.Add(dependencyAssetPath, dependencyNode);
                        dependencyGraph.AddNode(dependencyNode);
                    }
                    else
                    {
                        dependencyNode = existingNodes[dependencyAssetPath];
                    }

                    dependencyGraph.AddEdge(dependencyNode, node);
                }
            }
        }