private ReferenceNode SearchAnimationClip( Object unityObject ) { AnimationClip clip = (AnimationClip) unityObject; ReferenceNode referenceNode = PopReferenceNode( clip ); // Get all curves from animation clip EditorCurveBinding[] objectCurves = AnimationUtility.GetObjectReferenceCurveBindings( clip ); for( int i = 0; i < objectCurves.Length; i++ ) { // Search through all the keyframes in this curve ObjectReferenceKeyframe[] keyframes = AnimationUtility.GetObjectReferenceCurve( clip, objectCurves[i] ); for( int j = 0; j < keyframes.Length; j++ ) referenceNode.AddLinkTo( SearchObject( keyframes[j].value ), "Keyframe: " + keyframes[j].time ); } // Get all events from animation clip AnimationEvent[] events = AnimationUtility.GetAnimationEvents( clip ); for( int i = 0; i < events.Length; i++ ) referenceNode.AddLinkTo( SearchObject( events[i].objectReferenceParameter ), "AnimationEvent: " + events[i].time ); return referenceNode; }
// Initializes commonly used variables of the nodes public void InitializeNodes() { for (int i = references.Count - 1; i >= 0; i--) { ReferenceNode node = references[i]; if (node.NumberOfOutgoingLinks == 0) { references.RemoveAt(i); } else { // For simplicity's sake, get rid of root nodes that are // already part of another node's hierarchy bool isRootNodeChildOfOtherNode = false; for (int j = references.Count - 1; j >= 0; j--) { if (i == j) { continue; } if (references[j].NodeExistsInChildrenRecursive(node)) { isRootNodeChildOfOtherNode = true; break; } } if (isRootNodeChildOfOtherNode) { references.RemoveAt(i); } else { node.InitializeRecursively(); } } } }
private ReferenceNode SearchComponent( Object unityObject ) { Component component = (Component) unityObject; // Ignore Transform component (no object field to search for) if( component is Transform ) return null; ReferenceNode referenceNode = PopReferenceNode( component ); if( searchMonoBehavioursForScript && component is MonoBehaviour ) { // If a searched asset is script, check if this component is an instance of it MonoScript script = MonoScript.FromMonoBehaviour( (MonoBehaviour) component ); if( objectsToSearchSet.Contains( script ) ) referenceNode.AddLinkTo( GetReferenceNode( script ) ); } else if( searchRenderers && component is Renderer ) { // If an asset is a shader, texture or material, and this component is a Renderer, // search it for references Material[] materials = ( (Renderer) component ).sharedMaterials; for( int i = 0; i < materials.Length; i++ ) referenceNode.AddLinkTo( SearchObject( materials[i] ) ); } else if( component is Animation ) { // If this component is an Animation, search its animation clips for references foreach( AnimationState anim in (Animation) component ) referenceNode.AddLinkTo( SearchObject( anim.clip ) ); } else if( component is Animator ) { // If this component is an Animator, search its animation clips for references referenceNode.AddLinkTo( SearchObject( ( (Animator) component ).runtimeAnimatorController ) ); } #if UNITY_2017_2_OR_NEWER else if( component is Tilemap ) { // If this component is a Tilemap, search its tiles for references TileBase[] tiles = new TileBase[( (Tilemap) component ).GetUsedTilesCount()]; ( (Tilemap) component ).GetUsedTilesNonAlloc( tiles ); if( tiles != null ) { for( int i = 0; i < tiles.Length; i++ ) referenceNode.AddLinkTo( SearchObject( tiles[i] ), "Tile" ); } } #endif #if UNITY_2017_1_OR_NEWER else if( component is PlayableDirector ) { // If this component is a PlayableDirectory, search its PlayableAsset's scene bindings for references PlayableAsset playableAsset = ( (PlayableDirector) component ).playableAsset; if( playableAsset != null && !playableAsset.Equals( null ) ) { foreach( PlayableBinding binding in playableAsset.outputs ) referenceNode.AddLinkTo( SearchObject( ( (PlayableDirector) component ).GetGenericBinding( binding.sourceObject ) ), "Binding: " + binding.streamName ); } } #endif SearchFieldsAndPropertiesOf( referenceNode ); return referenceNode; }
// Pool a reference node private void PoolReferenceNode( ReferenceNode node ) { node.Clear(); nodesPool.Add( node ); }
public Link(ReferenceNode targetNode, string description) { this.targetNode = targetNode; this.description = description; }
// Draw the results found for this container public void DrawOnGUI(SearchResultDrawParameters parameters) { Color c = GUI.color; GUI.color = Color.cyan; if (GUILayout.Button(title, Utilities.BoxGUIStyle, Utilities.GL_EXPAND_WIDTH, Utilities.GL_HEIGHT_40) && clickable) { // If the container (scene, usually) is clicked, highlight it on Project view AssetDatabase.LoadAssetAtPath <SceneAsset>(title).SelectInEditor(); } GUI.color = Color.yellow; if (parameters.pathDrawingMode == PathDrawingMode.Full) { for (int i = 0; i < references.Count; i++) { GUILayout.Space(5); references[i].DrawOnGUIRecursively(parameters, null); } } else { if (referencePathsShortUnique == null) { CalculateShortestPathsToReferences(); } List <ReferencePath> pathsToDraw; if (parameters.pathDrawingMode == PathDrawingMode.ShortRelevantParts) { pathsToDraw = referencePathsShortUnique; } else { pathsToDraw = referencePathsShortest; } for (int i = 0; i < pathsToDraw.Count; i++) { GUILayout.Space(5); GUILayout.BeginHorizontal(); ReferencePath path = pathsToDraw[i]; path.startNode.DrawOnGUI(parameters, null); ReferenceNode currentNode = path.startNode; for (int j = 0; j < path.pathLinksToFollow.Length; j++) { ReferenceNode.Link link = currentNode[path.pathLinksToFollow[j]]; link.targetNode.DrawOnGUI(parameters, link.description); currentNode = link.targetNode; } GUILayout.EndHorizontal(); } } GUI.color = c; GUILayout.Space(10); }
// Initializes commonly used variables of the nodes public void InitializeNodes(Func <object, ReferenceNode> nodeGetter) { // Remove root nodes that don't have any outgoing links or have null node objects (somehow) for (int i = references.Count - 1; i >= 0; i--) { if (references[i].NumberOfOutgoingLinks == 0) { references.RemoveAtFast(i); } else { object nodeObject = references[i].nodeObject; if (nodeObject == null || nodeObject.Equals(null)) { references.RemoveAtFast(i); } } } // For simplicity's sake, get rid of root nodes that are already part of another node's hierarchy for (int i = references.Count - 1; i >= 0; i--) { if (IsRootNodePartOfAnotherRootNode(i)) { references.RemoveAtFast(i); } } // For clarity, a reference path shouldn't start with a sub-asset but instead with its corresponding main asset for (int i = references.Count - 1; i >= 0; i--) { object nodeObject = references[i].nodeObject; if (nodeObject.IsAsset() && !AssetDatabase.IsMainAsset((Object)nodeObject)) { string assetPath = AssetDatabase.GetAssetPath((Object)nodeObject); if (string.IsNullOrEmpty(assetPath)) { continue; } Object mainAsset = AssetDatabase.LoadMainAssetAtPath(assetPath); if (mainAsset == null || mainAsset.Equals(null)) { continue; } if (nodeObject is Component && ((Component)nodeObject).gameObject == mainAsset) { continue; } // Get a ReferenceNode for the main asset, add a link to the sub-asset's node and change the root node ReferenceNode newRootNode = nodeGetter(mainAsset); newRootNode.AddLinkTo(references[i], (nodeObject is Component || nodeObject is GameObject) ? "Child object" : "Sub-asset"); references[i] = newRootNode; // Make sure that the new root node isn't already a part of another node's hierarchy if (IsRootNodePartOfAnotherRootNode(i)) { references.RemoveAtFast(i); } } } for (int i = references.Count - 1; i >= 0; i--) { references[i].InitializeRecursively(); } }
// Add a reference to the list public void AddReference(ReferenceNode node) { references.Add(node); }
public ReferencePath(ReferenceNode startNode, int[] pathIndices) { this.startNode = startNode; pathLinksToFollow = pathIndices; }
// Draw the results found for this container public void DrawOnGUI(SearchResultDrawParameters parameters) { Color c = GUI.color; GUI.color = Color.cyan; Rect rect = EditorGUILayout.GetControlRect(Utilities.GL_EXPAND_WIDTH, Utilities.GL_HEIGHT_40); float width = rect.width; rect.width = 40f; if (GUI.Button(rect, IsExpanded ? "v" : ">")) { IsExpanded = !IsExpanded; GUIUtility.ExitGUI(); } rect.x += 40f; rect.width = width - (parameters.searchResult != null ? 140f : 40f); if (GUI.Button(rect, Title, Utilities.BoxGUIStyle) && Type == GroupType.Scene) { // If the container (scene, usually) is clicked, highlight it on Project view AssetDatabase.LoadAssetAtPath <SceneAsset>(Title).SelectInEditor(); } if (parameters.searchResult != null) { rect.x += width - 140f; rect.width = 100f; if (GUI.Button(rect, "Refresh")) { parameters.searchResult.RefreshSearchResultGroup(this, parameters.noAssetDatabaseChanges); GUIUtility.ExitGUI(); } } if (IsExpanded) { GUI.color = Color.yellow; if (PendingSearch) { GUILayout.Box("Lazy Search: this scene potentially has some references, hit Refresh to find them", Utilities.BoxGUIStyle); } else if (references.Count == 0) { GUILayout.Box("No references found...", Utilities.BoxGUIStyle); } else { if (parameters.pathDrawingMode == PathDrawingMode.Full) { for (int i = 0; i < references.Count; i++) { GUILayout.Space(5); references[i].DrawOnGUIRecursively(parameters, null); } } else { if (referencePathsShortUnique == null) { CalculateShortestPathsToReferences(); } List <ReferencePath> pathsToDraw; if (parameters.pathDrawingMode == PathDrawingMode.ShortRelevantParts) { pathsToDraw = referencePathsShortUnique; } else { pathsToDraw = referencePathsShortest; } for (int i = 0; i < pathsToDraw.Count; i++) { GUILayout.Space(5); GUILayout.BeginHorizontal(); ReferencePath path = pathsToDraw[i]; path.startNode.DrawOnGUI(parameters, null); ReferenceNode currentNode = path.startNode; for (int j = 0; j < path.pathLinksToFollow.Length; j++) { ReferenceNode.Link link = currentNode[path.pathLinksToFollow[j]]; link.targetNode.DrawOnGUI(parameters, link.description); currentNode = link.targetNode; } GUILayout.EndHorizontal(); } } } } GUI.color = c; GUILayout.Space(10); }