diff --git a/Editor/UIParticleEditor.cs b/Editor/UIParticleEditor.cs index 8d7bd3c..815a8c6 100644 --- a/Editor/UIParticleEditor.cs +++ b/Editor/UIParticleEditor.cs @@ -13,9 +13,7 @@ using Object = UnityEngine.Object; #if UNITY_2021_2_OR_NEWER using UnityEditor.Overlays; #else -using System; using System.Reflection; -using Object = UnityEngine.Object; #endif #if UNITY_2021_2_OR_NEWER using UnityEditor.SceneManagement; @@ -207,7 +205,10 @@ namespace Coffee.UIExtensions serializedObject.Update(); // Maskable - EditorGUILayout.PropertyField(_maskable); + if (_maskable != null) + { + EditorGUILayout.PropertyField(_maskable); + } // Scale EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4); diff --git a/Runtime/Internal/Extensions/ComponentExtensions.cs b/Runtime/Internal/Extensions/ComponentExtensions.cs index e95c5f6..e28e353 100644 --- a/Runtime/Internal/Extensions/ComponentExtensions.cs +++ b/Runtime/Internal/Extensions/ComponentExtensions.cs @@ -12,6 +12,33 @@ namespace Coffee.UIParticleInternal /// internal static class ComponentExtensions { +#if !UNITY_2019_2_OR_NEWER + public static bool TryGetComponent(this GameObject self, out T component) + where T : Component + { + if (self == null) + { + component = null; + return false; + } + + component = self.GetComponent(); + return component != null; + } + + public static bool TryGetComponent(this Component self, out T component) + where T : Component + { + if (self == null) + { + component = null; + return false; + } + + return self.gameObject.TryGetComponent(out component); + } +#endif + /// /// Get components in children of a specific type in the hierarchy of a GameObject. /// diff --git a/Runtime/Internal/Utilities/FrameCache.cs b/Runtime/Internal/Utilities/FrameCache.cs index ce0a837..48186e1 100644 --- a/Runtime/Internal/Utilities/FrameCache.cs +++ b/Runtime/Internal/Utilities/FrameCache.cs @@ -14,7 +14,7 @@ namespace Coffee.UIParticleInternal UIExtraCallbacks.onLateAfterCanvasRebuild += ClearAllCache; } -#if UNITY_EDITOR +#if UNITY_EDITOR && UNITY_2019_3_OR_NEWER [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void Clear() { diff --git a/Runtime/Internal/Utilities/MaterialRepository.cs b/Runtime/Internal/Utilities/MaterialRepository.cs index b643581..1a55d69 100644 --- a/Runtime/Internal/Utilities/MaterialRepository.cs +++ b/Runtime/Internal/Utilities/MaterialRepository.cs @@ -15,7 +15,7 @@ namespace Coffee.UIParticleInternal public static Func onShaderFind = Shader.Find; -#if UNITY_EDITOR +#if UNITY_EDITOR && UNITY_2019_3_OR_NEWER [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] public static void Clear() { diff --git a/Runtime/Internal/Utilities/Misc.cs b/Runtime/Internal/Utilities/Misc.cs index 11518ee..ce2eba1 100644 --- a/Runtime/Internal/Utilities/Misc.cs +++ b/Runtime/Internal/Utilities/Misc.cs @@ -109,7 +109,7 @@ namespace Coffee.UIParticleInternal { if (Misc.isBatchOrBuilding) return; - var types = TypeCache.GetTypesWithAttribute(); + var types = TypeCache.GetTypesWithAttribute(typeof(IconAttribute)); var scripts = MonoImporter.GetAllRuntimeMonoScripts(); foreach (var type in types) { diff --git a/Runtime/Internal/Utilities/TypeCache.cs b/Runtime/Internal/Utilities/TypeCache.cs new file mode 100644 index 0000000..ea57c7f --- /dev/null +++ b/Runtime/Internal/Utilities/TypeCache.cs @@ -0,0 +1,88 @@ +#if !UNITY_2019_2_OR_NEWER +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Coffee.UIParticleInternal +{ + public static class TypeCache + { + private static readonly object s_Lock = new object(); + private static readonly Dictionary s_DerivedTypesCache = new Dictionary(); + private static readonly Dictionary s_AttributeTypesCache = new Dictionary(); + + public static IEnumerable GetTypesDerivedFrom(Type baseType) + { + lock (s_Lock) + { + if (s_DerivedTypesCache.TryGetValue(baseType, out var cached)) + { + return cached; + } + + var types = new List(); + foreach (var t in GetAllLoadableTypes()) + { + if (t != baseType && baseType.IsAssignableFrom(t)) + { + types.Add(t); + } + } + + return s_DerivedTypesCache[baseType] = types.ToArray(); + } + } + + public static IEnumerable GetTypesWithAttribute(Type attr) + { + lock (s_Lock) + { + if (s_AttributeTypesCache.TryGetValue(attr, out var cached)) + { + return cached; + } + + var types = new List(); + foreach (var t in GetAllLoadableTypes()) + { + if (t.GetCustomAttributes(attr, inherit: true).Length > 0) + { + types.Add(t); + } + } + + return s_AttributeTypesCache[attr] = types.ToArray(); + } + } + + private static IEnumerable GetAllLoadableTypes() + { + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + Type[] types; + try + { + types = assembly.GetTypes(); + } + catch (ReflectionTypeLoadException ex) + { + types = ex.Types; + } + + if (types == null) + { + continue; + } + + foreach (var t in types) + { + if (t != null) + { + yield return t; + } + } + } + } + } +} +#endif diff --git a/Runtime/Internal/Utilities/TypeCache.cs.meta b/Runtime/Internal/Utilities/TypeCache.cs.meta new file mode 100644 index 0000000..aa20b32 --- /dev/null +++ b/Runtime/Internal/Utilities/TypeCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc1207b657ed74ec19e459664d06925f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: