public static bool TraverseRootGameObjects(GameObject[] rootObjects, bool skipCleanPrefabInstances, bool forceAllPrefabsTraverse, GameObjectTraverseCallback callback, SceneRootTraverseCallback rootTraverseCallback = null) { var rootObjectsCount = rootObjects.Length; var objectTraverseInfo = new ObjectTraverseInfo(skipCleanPrefabInstances, forceAllPrefabsTraverse, rootObjectsCount); for (var i = 0; i < rootObjectsCount; i++) { var rootObject = rootObjects[i]; if (rootTraverseCallback != null) { bool canceled; rootTraverseCallback.Invoke(i, rootObjectsCount, out canceled); if (canceled) { return(false); } } objectTraverseInfo.current = rootObject; objectTraverseInfo.rootIndex = i; if (!TraverseGameObjectTree(objectTraverseInfo, callback)) { return(false); } } return(true); }
public static bool TraversePrefabGameObjects(GameObject prefabAsset, bool enablePrefabChecks, GameObjectTraverseCallback callback) { var objectTraverseInfo = new ObjectTraverseInfo(enablePrefabChecks, 1) { current = prefabAsset, inPrefabInstance = false, dirtyComponents = null, rootIndex = 0, }; return(TraverseGameObjectTree(objectTraverseInfo, callback)); }
public static bool TraverseSceneGameObjects(Scene scene, bool skipCleanPrefabInstances, GameObjectTraverseCallback callback) { var rootObjects = scene.GetRootGameObjects(); var rootObjectsCount = rootObjects.Length; var objectTraverseInfo = new ObjectTraverseInfo(skipCleanPrefabInstances, rootObjectsCount); for (var i = 0; i < rootObjectsCount; i++) { var rootObject = rootObjects[i]; objectTraverseInfo.current = rootObject; objectTraverseInfo.rootIndex = i; if (!TraverseGameObjectTree(objectTraverseInfo, callback)) { return(false); } } return(true); }
public static void TraverseGameObjectComponents(ObjectTraverseInfo traverseInfo, ComponentTraverseCallback callback) { var components = traverseInfo.current.GetComponents <Component>(); var checkingPrefabInstanceObject = false; var checkingAddedToInstanceObject = false; if (traverseInfo.SkipCleanPrefabInstances) { #if UNITY_2018_3_OR_NEWER checkingPrefabInstanceObject = traverseInfo.inPrefabInstance && !traverseInfo.inMissingPrefabInstance; if (checkingPrefabInstanceObject) { checkingAddedToInstanceObject = PrefabUtility.IsAddedGameObjectOverride(traverseInfo.current); } #else checkingPrefabInstanceObject = CSPrefabTools.IsInstance(traverseInfo.current); #endif } var hasDirtyComponents = traverseInfo.dirtyComponents != null; var visibleIndex = -1; for (var i = 0; i < components.Length; i++) { var component = components[i]; if (component == null || component.hideFlags == HideFlags.None || component.hideFlags == HideFlags.HideInHierarchy) { visibleIndex++; } if (component == null) { // to register missing script callback(traverseInfo, null, visibleIndex); continue; } // transforms are checked at the GameObject level if (component is Transform) { continue; } if (!checkingPrefabInstanceObject) { Stats.componentsTraversed++; callback(traverseInfo, component, visibleIndex); } else { var hasOverridenProperties = checkingAddedToInstanceObject; if (!hasOverridenProperties && hasDirtyComponents) { if (Array.IndexOf(traverseInfo.dirtyComponents, component.GetInstanceID()) != -1) { hasOverridenProperties = true; } } if (hasOverridenProperties) { Stats.componentsTraversed++; callback(traverseInfo, component, visibleIndex); } } } }
public static bool TraverseGameObjectTree(ObjectTraverseInfo traverseInfo, GameObjectTraverseCallback callback) { Stats.gameObjectsTraversed++; var prefabInstanceRoot = false; if (!traverseInfo.inPrefabInstance) { //Debug.Log("IsPartOfPrefabInstance " + PrefabUtility.IsPartOfPrefabInstance(componentOrGameObject)); //Debug.Log(traverseInfo.current.name); traverseInfo.inPrefabInstance = CSPrefabTools.IsInstance(traverseInfo.current); if (traverseInfo.inPrefabInstance) { if (!CSPrefabTools.IsMissingPrefabInstance(traverseInfo.current)) { if (traverseInfo.SkipCleanPrefabInstances) { if (CSPrefabTools.IsWholeInstanceHasAnyOverrides(traverseInfo.current)) { CSPrefabTools.GetOverridenObjectsFromWholePrefabInstance(traverseInfo.current, out traverseInfo.dirtyComponents); } } } else { traverseInfo.inMissingPrefabInstance = true; } prefabInstanceRoot = true; } } if (!callback.Invoke(traverseInfo)) { return(false); } if (traverseInfo.skipCurrentTree) { if (prefabInstanceRoot) { traverseInfo.dirtyComponents = null; traverseInfo.inPrefabInstance = false; traverseInfo.inMissingPrefabInstance = false; traverseInfo.skipCurrentTree = false; } return(true); } var transform = traverseInfo.current.transform; var childrenCount = transform.childCount; for (var i = 0; i < childrenCount; i++) { var child = transform.GetChild(i); traverseInfo.current = child.gameObject; if (!TraverseGameObjectTree(traverseInfo, callback)) { return(false); } } if (prefabInstanceRoot) { traverseInfo.dirtyComponents = null; traverseInfo.inPrefabInstance = false; traverseInfo.inMissingPrefabInstance = false; traverseInfo.skipCurrentTree = false; } return(true); }