/
TON618OFF
/
Unity-Project-RTU
Обзор
Документация
Войти
/
TON618OFF
/
Unity-Project-RTU
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Library/PackageCache/com.unity.visualscripting@1.9.4/Runtime/VisualScripting.Core/Utilities/UnityObjectUtility.cs
159 строк
5 KB
TON618OFF
release
03 окт 2024, 22:20
03 окт 2024, 22:20
7c70e9f
Код
Авторство
О чём код?
using System; using System.Collections.Generic; using System.Linq; using UnityEngine.SceneManagement; using UnityObject = UnityEngine.Object; namespace Unity.VisualScripting { public static class UnityObjectUtility { public static bool IsDestroyed(this UnityObject target) { // Checks whether a Unity object is not actually a null reference, // but a rather destroyed native instance. return !ReferenceEquals(target, null) && target == null; } public static bool IsUnityNull(this object obj) { // Checks whether an object is null or Unity pseudo-null // without having to cast to UnityEngine.Object manually return obj == null || ((obj is UnityObject) && ((UnityObject)obj) == null); } public static string ToSafeString(this UnityObject uo) { if (ReferenceEquals(uo, null)) { return "(null)"; } if (!UnityThread.allowsAPI) { return uo.GetType().Name; } if (uo == null) { return "(Destroyed)"; } try { return uo.name; } catch (Exception ex) { return $"({ex.GetType().Name} in ToString: {ex.Message})"; } } public static string ToSafeString(this object obj) { if (obj == null) { return "(null)"; } if (obj is UnityObject uo) { return uo.ToSafeString(); } try { return obj.ToString(); } catch (Exception ex) { return $"({ex.GetType().Name} in ToString: {ex.Message})"; } } public static T AsUnityNull<T>(this T obj) where T : UnityObject { // Converts a Unity pseudo-null to a real null, allowing for coalesce operators. // e.g.: destroyedObject.AsUnityNull() ?? otherObject if (obj == null) { return null; } return obj; } public static bool TrulyEqual(UnityObject a, UnityObject b) { // This method is required when checking two references // against one another, where one of them might have been destroyed. // It is not required when checking against null. // This is because Unity does not compare alive state // in the CompareBaseObjects method unless one of the two // operators is actually the null literal. // From the source: /* bool lhsIsNull = (object) lhs == null; bool rhsIsNull = (object) rhs == null; if (rhsIsNull && lhsIsNull) return true; if (rhsIsNull) return !Object.IsNativeObjectAlive(lhs); if (lhsIsNull) return !Object.IsNativeObjectAlive(rhs); return lhs.m_InstanceID == rhs.m_InstanceID; */ // As we can see, Object.IsNativeObjectAlive is not compared // across the two objects unless one of the operands is actually null. // But it can happen, for example when exiting play mode. // If we stored a static reference to a scene object that was destroyed, // the reference won't get cleared because assembly reloads don't happen // when exiting playmode. But the instance ID of the object will stay // the same, because it only gets reserialized. So if we compare our // stale reference that was destroyed to a new reference to the object, // it will return true, even though one reference is alive and the other isn't. if (a != b) { return false; } if ((a == null) != (b == null)) { return false; } return true; } public static IEnumerable<T> NotUnityNull<T>(this IEnumerable<T> enumerable) where T : UnityObject { return enumerable.Where(i => i != null); } public static IEnumerable<T> FindObjectsOfTypeIncludingInactive<T>() { for (int i = 0; i < SceneManager.sceneCount; i++) { var scene = SceneManager.GetSceneAt(i); if (scene.isLoaded) { foreach (var rootGameObject in scene.GetRootGameObjects()) { foreach (var result in rootGameObject.GetComponentsInChildren<T>(true)) { yield return result; } } } } } } }