using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; #pragma warning disable CS0162 namespace DA_Assets.Extensions { public static class MonoBehExtensions { public static void DestroyChilds(this GameObject parent) { if (parent == null) return; int childCount = parent.transform.childCount; for (int i = childCount - 1; i >= 0; i--) { GameObject go = parent.transform.GetChild(i).gameObject; go.Destroy(); } Debug.Log("log_current_canvas_childs_destroy " + childCount); } public static bool TryGetComponentSafe(this GameObject gameObject, out T component) { component = default; if (gameObject == null) return false; return gameObject.TryGetComponent(out component); } public static T[] GetChilds(this GameObject gameObject) { T[] childs = gameObject.GetComponentsInChildren(true).Skip(1).ToArray(); return childs; } /// /// Removes the RectTransform component from a GameObject by creating a new GameObject /// with the same components (excluding RectTransform), children, and parent. /// /// The GameObject from which to remove the RectTransform. public static GameObject RemoveRectTransform(this GameObject gameObject) { // Create a new GameObject GameObject newGameObject = CreateEmptyGameObject(); newGameObject.name = gameObject.name; // Save the siblingIndex of the old GameObject int siblingIndex = gameObject.transform.GetSiblingIndex(); // Assign the parent object newGameObject.transform.SetParent(gameObject.transform.parent); newGameObject.transform.localPosition = gameObject.transform.localPosition; newGameObject.transform.localRotation = gameObject.transform.localRotation; newGameObject.transform.localScale = gameObject.transform.localScale; // Set siblingIndex for the new GameObject newGameObject.transform.SetSiblingIndex(siblingIndex); // Transfer all child objects for (int i = gameObject.transform.childCount - 1; i >= 0; i--) { Transform child = gameObject.transform.GetChild(i); // Save the siblingIndex for child objects int childSiblingIndex = child.GetSiblingIndex(); child.SetParent(newGameObject.transform); child.SetSiblingIndex(childSiblingIndex); } // Copy all components Component[] components = gameObject.GetComponents(); foreach (Component component in components) { if (!(component is Transform)) { Component newComponent = newGameObject.AddComponent(component.GetType()); component.CopySerializedFields(newComponent); } } // Destroy the old GameObject gameObject.Destroy(); return newGameObject; } public static List GetComponentsInReverseOrder(this GameObject parent) where T : Component { List results = new List(); AddComponentsInReverseOrder(parent.transform); return results; void AddComponentsInReverseOrder(Transform current) { for (int i = current.childCount - 1; i >= 0; i--) { AddComponentsInReverseOrder(current.GetChild(i)); } T component = current.GetComponent(); if (component != null/* && !results.Contains(component)*/) { results.Add(component); } } } /// /// Saves the GameObject as a prefab asset at the specified local path and tries to get the component of type T from the prefab. /// /// The type of the MonoBehaviour to retrieve from the prefab. /// The GameObject to be saved as a prefab. /// The local path within the project where the prefab should be saved. /// The component of type T retrieved from the prefab, or null if the operation failed. /// Any exceptions that occurred during the process. /// True if the prefab was saved and the component of type T was successfully retrieved, otherwise false. public static bool SaveAsPrefabAsset(this GameObject gameObject, string localPath, out T savedPrefab, out Exception ex) where T : MonoBehaviour { // Check for null GameObject if (gameObject == null) { ex = new NullReferenceException("GameObject is null."); savedPrefab = null; return false; } #if UNITY_EDITOR // Save the GameObject as a prefab asset in Editor mode. GameObject prefabGo = null; try { prefabGo = UnityEditor.PrefabUtility.SaveAsPrefabAsset(gameObject, localPath, out bool success); } catch (Exception ex1) { ex = ex1; } if (prefabGo == null) { ex = new NullReferenceException("Prefab is null."); savedPrefab = null; return false; } // Attempt to get the component of type T from the saved prefab. if (prefabGo.TryGetComponent(out T prefabComponent)) { ex = null; savedPrefab = prefabComponent; return true; } else { // Handle the case where the component of type T can't be found on the prefab. ex = new Exception($"Can't get Type '{typeof(T).Name}' from GameObject '{prefabGo.name}'."); savedPrefab = null; return false; } #endif // Handle cases outside of Editor mode. ex = new Exception("Unsupported in not-Editor mode."); savedPrefab = null; return false; } /// /// Checks if the provided UnityEngine.Object is part of any prefab. /// /// The UnityEngine.Object to check. /// True if the object is part of a prefab, otherwise false. public static bool IsPartOfAnyPrefab(this UnityEngine.Object gameObject) { if (gameObject == null) return false; #if UNITY_EDITOR return UnityEditor.PrefabUtility.IsPartOfAnyPrefab(gameObject); #endif return false; } /// /// Checks if any instance of the provided MonoBehaviour type exists on the scene. /// /// Type of MonoBehaviour to check for. /// True if at least one instance of T exists on the scene, otherwise false. public static bool IsExistsOnScene() where T : MonoBehaviour { int count = MonoBehaviour.FindObjectsOfType().Length; return count != 0; } /// /// Destroying Unity GameObject, but as an extension. /// Works in Editor and Playmode. /// /// public static bool Destroy(this UnityEngine.Object @object) { if (@object == null) return false; try { if (@object != null) { //Debug.LogError($"Destroy | {unityObject.name}"); } #if UNITY_EDITOR UnityEngine.Object.DestroyImmediate(@object); #else UnityEngine.Object.Destroy(@object); #endif return true; } catch { return false; } } /// /// /// /// /// /// /// Returns whether a component of the input type has been added. public static bool TryAddComponent(this GameObject gameObject, out T component, bool supportMultiInstance = false) where T : UnityEngine.Component { if (gameObject.TryGetComponent(out component) && !supportMultiInstance) { return true; } else { component = gameObject.AddComponent(); return false; } } public static bool TryGetComponent(this GameObject gameObject, out T component) where T : UnityEngine.Component { try { component = gameObject.GetComponent(); string _ = component.name; return true; } catch { component = default; return false; } } /// /// /// /// /// /// Found or added graphic component. /// Returns whether a component of the input type has been added. public static bool TryAddGraphic(this GameObject gameObject, out T graphic) where T : Graphic { if (gameObject.TryGetComponent(out graphic)) { return false; } else if (gameObject.TryGetComponent(out Graphic _graphic)) { return false; } else { graphic = gameObject.AddComponent(); return true; } } public static bool TryDestroyComponent(this GameObject gameObject) where T : UnityEngine.Component { if (gameObject.TryGetComponent(out T component)) { component.Destroy(); return true; } else { return false; } } /// /// Marks target object as dirty, but as an extension. /// /// The object to mark as dirty. public static void SetDirtyExt(this UnityEngine.Object @object) { #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(@object); #endif } public static void MakeGameObjectSelectedInHierarchy(this GameObject activeGameObject) { #if UNITY_EDITOR UnityEditor.Selection.activeGameObject = activeGameObject; #endif } public static GameObject CreateEmptyGameObject(string name = null, Transform parent = null) { GameObject tempGO = new GameObject(); GameObject emptyGO; if (parent == null) { emptyGO = UnityEngine.Object.Instantiate(tempGO); } else { emptyGO = UnityEngine.Object.Instantiate(tempGO, parent); } if (name != null) { tempGO.name = name; } tempGO.Destroy(); return emptyGO; } } }