using System.Collections.Generic; using UnityEngine; namespace FIMSpace.FEditor { public static class FGUI_Finders { public static Component FoundAnimator; private static bool checkForAnim = true; private static int clicks = 0; /// /// Resetting static finders for new searching /// public static void ResetFinders(bool resetClicks = true) { checkForAnim = true; FoundAnimator = null; if ( resetClicks ) clicks = 0; } /// /// Searching for animator in given root object and it's parents /// If you want to search new aniamtor you have to call ResetFinders() /// /// Returns true if animator is found, enabled and have controller public static bool CheckForAnimator(GameObject root, bool needAnimatorBox = true, bool drawInactiveWarning = true, int clicksTohide = 1) { bool working = false; if (checkForAnim) { FoundAnimator = SearchForParentWithAnimator(root); } // Drawing animator specific dialogs if (FoundAnimator) { Animation legacy = FoundAnimator as Animation; Animator mec = FoundAnimator as Animator; if (legacy) if (legacy.enabled) working = true; if (mec) // Mecanim found but no controller assigned { if (mec.enabled) working = true; if (mec.runtimeAnimatorController == null) { #if UNITY_EDITOR UnityEditor.EditorGUILayout.HelpBox(" No 'Animator Controller' inside Animator ("+FoundAnimator.transform.name+")", UnityEditor.MessageType.Warning); #endif drawInactiveWarning = false; working = false; } } // Drawing dialogs for warnings if (needAnimatorBox) { if (drawInactiveWarning) { if (!working) { #if UNITY_EDITOR GUILayout.Space(-4); FGUI_Inspector.DrawWarning(" ANIMATOR IS DISABLED! "); GUILayout.Space(2); #endif } } } } else { if (needAnimatorBox) { if (clicks < clicksTohide) { #if UNITY_EDITOR GUILayout.Space(-4); if (FGUI_Inspector.DrawWarning(" ANIMATOR NOT FOUND! ")) clicks++; GUILayout.Space(2); #endif } } } checkForAnim = false; return working; } /// /// Searching in first children for animation/animator components /// If not found then searching in parents /// /// Returns transform with component or null if not found public static Component SearchForParentWithAnimator(GameObject root) { Animation animation = root.GetComponentInChildren(); if (animation) return animation; Animator animator = root.GetComponentInChildren(); if (animator) return animator; if (root.transform.parent != null) { Transform pr = root.transform.parent; while (pr != null) { animation = pr.GetComponent(); if (animation) return animation; animator = pr.GetComponent(); if (animator) return animator; pr = pr.parent; } } return null; } /// /// Finding skinned mesh renderer with largest count of bones /// public static SkinnedMeshRenderer GetBoneSearchArray(Transform root) { List skins = new List(); SkinnedMeshRenderer largestSkin = null; foreach (var t in root.GetComponentsInChildren()) { SkinnedMeshRenderer s = t.GetComponent(); if (s) skins.Add(s); } // Searching in parent if (skins.Count == 0) { Transform lastParent = root; while (lastParent != null) { if (lastParent.parent == null) break; lastParent = lastParent.parent; } foreach (var t in lastParent.GetComponentsInChildren()) { SkinnedMeshRenderer s = t.GetComponent(); if (!skins.Contains(s)) if (s) skins.Add(s); } } if (skins.Count > 1) { largestSkin = skins[0]; for (int i = 1; i < skins.Count; i++) if (skins[i].bones.Length > largestSkin.bones.Length) largestSkin = skins[i]; } else if (skins.Count > 0) largestSkin = skins[0]; if (largestSkin == null) return null; return largestSkin; } /// /// Checking if transform is child of choosed root bone parent transform /// public static bool IsChildOf(Transform child, Transform rootParent) { Transform tParent = child; while (tParent != null && tParent != rootParent) { tParent = tParent.parent; } if (tParent == null) return false; else return true; } /// /// Checking if transform is child of choosed root bone parent transform /// public static Transform GetLastChild(Transform rootParent) { Transform tChild = rootParent; while (tChild.childCount > 0) tChild = tChild.GetChild(0); return tChild; } /// /// Returns true if right keyword exists, false if left, null if unknown /// public static bool? IsRightOrLeft(string name, bool includeNotSure = false) { string nameLower = name.ToLower(); if (nameLower.Contains("right")) return true; if (nameLower.Contains("left")) return false; if (nameLower.StartsWith("r_")) return true; if (nameLower.StartsWith("l_")) return false; if (nameLower.EndsWith("_r")) return true; if (nameLower.EndsWith("_l")) return false; if (nameLower.StartsWith("r.")) return true; if (nameLower.StartsWith("l.")) return false; if (nameLower.EndsWith(".r")) return true; if (nameLower.EndsWith(".l")) return false; if ( includeNotSure) { if (nameLower.Contains("r_")) return true; if (nameLower.Contains("l_")) return false; if (nameLower.Contains("_r")) return true; if (nameLower.Contains("_l")) return false; if (nameLower.Contains("r.")) return true; if (nameLower.Contains("l.")) return false; if (nameLower.Contains(".r")) return true; if (nameLower.Contains(".l")) return false; } return null; } /// /// Returns true if child is on the right of root's relation, false if on the left, null if on the middle /// public static bool? IsRightOrLeft(Transform child, Transform itsRoot) { Vector3 transformed = itsRoot.InverseTransformPoint(child.position); if (transformed.x < 0f) return false; else if (transformed.x > 0f) return true; return null; } public static bool HaveKey(string text, string[] keys) { for (int i = 0; i < keys.Length; i++) if (text.Contains(keys[i])) return true; return false; } } }