using UnityEngine; using UnityEngine.SceneManagement; using Saltosion.OneWeapon.Utils; namespace Saltosion.OneWeapon.Effects { public enum DebrisType { Blood, Structural, Wood } public class DebrisLauncher : MonoBehaviour { private static DebrisLauncher Singleton; private static int SingletonSceneIndex; public GameObject StructuralParticlePrefab; public GameObject WoodParticlePrefab; public GameObject BloodParticlePrefab; public GameObject CensoredBloodParticlePrefab; public Transform ParticleRoot; public int MaxParticles; public bool DebugLaunch = false; public static void Splatter(DebrisType Type, Vector2 origin, Vector2 direction, int particleCount, float force, float degrees, bool sticky = true) { int ParticleCount = (int)(particleCount * (Type == DebrisType.Blood ? Singleton.GetBloodParticleCountMultiplier() : 1)); LaunchParticles(Singleton.GetDebrisPrefab(Type), origin, direction, particleCount, force, degrees, sticky); } private static void LaunchParticles(GameObject prefab, Vector2 origin, Vector2 direction, int particleCount, float force, float degrees, bool sticky) { for (int i = 0; i < particleCount; i++) { if (Singleton.ParticleRoot.childCount >= Singleton.MaxParticles) { Destroy(Singleton.ParticleRoot.GetChild((int)(Random.value * Singleton.ParticleRoot.childCount)).gameObject); } GameObject Obj = Instantiate(prefab, origin, new Quaternion(), Singleton.ParticleRoot); DebrisParticle Particle = Obj.GetComponent(); float Intensity = Mathf.Pow(Random.value, 0.8f) * force; float Cone = degrees / 360.0f; float Offset = Mathf.Atan2(direction.y, direction.x); float Radians = Offset + Mathf.Pow(Cone * (Random.value - 0.5f) * 2f, 2f) * Mathf.PI * 2.0f; Particle.LaunchForce = new Vector2(Mathf.Cos(Radians), Mathf.Sin(Radians)) * Intensity; Particle.GetsStuck = sticky && Random.value < 0.5; } } private void Start() { int Index = SceneManager.GetActiveScene().buildIndex; if (SingletonSceneIndex == Index) { Debug.LogWarning($"The scene '{SceneManager.GetActiveScene().name}' has multiple DebrisLaunchers!\nOnly the last to run Start() will be used."); } SingletonSceneIndex = Index; Singleton = this; } private GameObject GetDebrisPrefab(DebrisType Type) { switch (Type) { case DebrisType.Blood: return Options.CensorGore ? CensoredBloodParticlePrefab : BloodParticlePrefab; case DebrisType.Structural: return StructuralParticlePrefab; case DebrisType.Wood: return WoodParticlePrefab; default: return CensoredBloodParticlePrefab; } } private float GetBloodParticleCountMultiplier() { return Options.CensorGore ? 0.1f : 1.5f; } } }