ParticleEffectForUGUI/Scripts/Utils.cs

267 lines
8.5 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Coffee.UIParticleExtensions
{
public static class Vector3Extensions
{
public static Vector3 Inverse(this Vector3 self)
{
self.x = Mathf.Approximately(self.x, 0) ? 1 : 1 / self.x;
self.y = Mathf.Approximately(self.y, 0) ? 1 : 1 / self.y;
self.z = Mathf.Approximately(self.z, 0) ? 1 : 1 / self.z;
return self;
}
public static Vector3 GetScaled(this Vector3 self, Vector3 other1)
{
self.Scale(other1);
return self;
}
public static Vector3 GetScaled(this Vector3 self, Vector3 other1, Vector3 other2)
{
self.Scale(other1);
self.Scale(other2);
return self;
}
public static Vector3 GetScaled(this Vector3 self, Vector3 other1, Vector3 other2, Vector3 other3)
{
self.Scale(other1);
self.Scale(other2);
self.Scale(other3);
return self;
}
public static bool IsVisible(this Vector3 self)
{
return 0 < Mathf.Abs(self.x * self.y * self.z);
}
}
internal static class SpriteExtensions
{
#if UNITY_EDITOR
2023-08-17 08:43:02 +08:00
private static readonly Type s_SpriteEditorExtensionType =
Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor")
?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor");
2023-08-17 08:43:02 +08:00
private static readonly MethodInfo s_GetActiveAtlasTextureMethodInfo = s_SpriteEditorExtensionType
.GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic);
public static Texture2D GetActualTexture(this Sprite self)
{
if (!self) return null;
if (Application.isPlaying) return self.texture;
2023-08-17 08:43:02 +08:00
var ret = s_GetActiveAtlasTextureMethodInfo.Invoke(null, new object[] { self }) as Texture2D;
return ret
? ret
: self.texture;
}
#else
internal static Texture2D GetActualTexture(this Sprite self)
{
return self ? self.texture : null;
}
#endif
}
public static class ParticleSystemExtensions
{
2022-06-15 08:09:56 +08:00
private static ParticleSystem.Particle[] s_TmpParticles = new ParticleSystem.Particle[2048];
public static ParticleSystem.Particle[] GetParticleArray(int size)
{
if (s_TmpParticles.Length < size)
{
2023-08-17 08:43:02 +08:00
while (s_TmpParticles.Length < size)
2022-06-15 08:09:56 +08:00
{
size = Mathf.NextPowerOfTwo(size);
}
2023-08-17 08:43:02 +08:00
2022-06-15 08:09:56 +08:00
s_TmpParticles = new ParticleSystem.Particle[size];
}
2023-08-17 08:43:02 +08:00
2022-06-15 08:09:56 +08:00
return s_TmpParticles;
}
public static bool CanBakeMesh(this ParticleSystemRenderer self)
{
// #69: Editor crashes when mesh is set to null when `ParticleSystem.RenderMode = Mesh`
if (self.renderMode == ParticleSystemRenderMode.Mesh && self.mesh == null) return false;
// #61: When `ParticleSystem.RenderMode = None`, an error occurs
if (self.renderMode == ParticleSystemRenderMode.None) return false;
return true;
}
public static ParticleSystemSimulationSpace GetActualSimulationSpace(this ParticleSystem self)
{
var main = self.main;
var space = main.simulationSpace;
if (space == ParticleSystemSimulationSpace.Custom && !main.customSimulationSpace)
2023-08-17 08:43:02 +08:00
{
space = ParticleSystemSimulationSpace.Local;
2023-08-17 08:43:02 +08:00
}
return space;
}
2023-08-17 08:43:02 +08:00
public static bool IsLocalSpace(this ParticleSystem self)
{
return GetActualSimulationSpace(self) == ParticleSystemSimulationSpace.Local;
}
public static bool IsWorldSpace(this ParticleSystem self)
{
return GetActualSimulationSpace(self) == ParticleSystemSimulationSpace.World;
}
public static void SortForRendering(this List<ParticleSystem> self, Transform transform, bool sortByMaterial)
{
self.Sort((a, b) =>
{
2020-10-28 11:21:34 +08:00
var aRenderer = a.GetComponent<ParticleSystemRenderer>();
var bRenderer = b.GetComponent<ParticleSystemRenderer>();
// Render queue: ascending
2023-08-17 08:43:02 +08:00
var aMat = aRenderer.sharedMaterial ? aRenderer.sharedMaterial : aRenderer.trailMaterial;
var bMat = bRenderer.sharedMaterial ? bRenderer.sharedMaterial : bRenderer.trailMaterial;
if (!aMat && !bMat) return 0;
if (!aMat) return -1;
if (!bMat) return 1;
if (sortByMaterial)
2023-08-17 08:43:02 +08:00
{
return aMat.GetInstanceID() - bMat.GetInstanceID();
2023-08-17 08:43:02 +08:00
}
2020-10-28 11:21:34 +08:00
if (aMat.renderQueue != bMat.renderQueue)
2023-08-17 08:43:02 +08:00
{
2020-10-28 11:21:34 +08:00
return aMat.renderQueue - bMat.renderQueue;
2023-08-17 08:43:02 +08:00
}
2020-10-28 11:21:34 +08:00
// Sorting layer: ascending
if (aRenderer.sortingLayerID != bRenderer.sortingLayerID)
2023-08-17 08:43:02 +08:00
{
return SortingLayer.GetLayerValueFromID(aRenderer.sortingLayerID) -
SortingLayer.GetLayerValueFromID(bRenderer.sortingLayerID);
}
2020-10-28 11:21:34 +08:00
// Sorting order: ascending
if (aRenderer.sortingOrder != bRenderer.sortingOrder)
2023-08-17 08:43:02 +08:00
{
2020-10-28 11:21:34 +08:00
return aRenderer.sortingOrder - bRenderer.sortingOrder;
2023-08-17 08:43:02 +08:00
}
2020-10-28 11:21:34 +08:00
// Z position & sortingFudge: descending
var aTransform = a.transform;
var bTransform = b.transform;
2023-08-17 08:43:02 +08:00
var aPos = transform.InverseTransformPoint(aTransform.position).z + aRenderer.sortingFudge;
var bPos = transform.InverseTransformPoint(bTransform.position).z + bRenderer.sortingFudge;
2020-10-28 11:21:34 +08:00
if (!Mathf.Approximately(aPos, bPos))
2023-08-17 08:43:02 +08:00
{
return (int)Mathf.Sign(bPos - aPos);
2023-08-17 08:43:02 +08:00
}
2020-10-28 11:21:34 +08:00
return (int)Mathf.Sign(GetIndex(self, a) - GetIndex(self, b));
2020-10-28 11:21:34 +08:00
});
}
2020-10-28 01:08:31 +08:00
2021-01-06 16:43:14 +08:00
private static int GetIndex(IList<ParticleSystem> list, Object ps)
2020-10-28 11:21:34 +08:00
{
for (var i = 0; i < list.Count; i++)
2020-10-28 11:21:34 +08:00
{
2023-08-17 08:43:02 +08:00
if (list[i].GetInstanceID() == ps.GetInstanceID())
{
return i;
}
2020-10-28 11:21:34 +08:00
}
return 0;
}
public static Texture2D GetTextureForSprite(this ParticleSystem self)
{
if (!self) return null;
// Get sprite's texture.
var tsaModule = self.textureSheetAnimation;
if (!tsaModule.enabled || tsaModule.mode != ParticleSystemAnimationMode.Sprites) return null;
for (var i = 0; i < tsaModule.spriteCount; i++)
{
var sprite = tsaModule.GetSprite(i);
if (!sprite) continue;
return sprite.GetActualTexture();
}
return null;
}
public static void Exec(this List<ParticleSystem> self, Action<ParticleSystem> action)
{
self.RemoveAll(p => !p);
self.ForEach(action);
}
}
2023-08-17 08:43:02 +08:00
internal static class Misc
{
public static void Destroy(Object obj)
{
if (!obj) return;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj);
}
}
public static void DestroyImmediate(Object obj)
{
if (!obj) return;
#if UNITY_EDITOR
if (Application.isEditor)
{
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj);
}
}
2023-08-18 14:08:49 +08:00
#if !UNITY_2021_2_OR_NEWER || UNITY_2020_3_45 || UNITY_2020_3_46 || UNITY_2020_3_47 || UNITY_2020_3_48
public static T GetComponentInParent<T>(this Component self, bool includeInactive) where T : Component
{
if (!self) return null;
if (!includeInactive) return self.GetComponentInParent<T>();
var current = self.transform;
while (current)
{
var component = current.GetComponent<T>();
if (component) return component;
current = current.parent;
}
return null;
}
#endif
2023-08-17 08:43:02 +08:00
}
2021-01-06 16:43:14 +08:00
}