using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Superlazy { public class SLResourceObject : MonoBehaviour { public Animator[] anims; public Renderer[] renderers; public ParticleSystem[] particles; public TrailRenderer[] trails; public SLStateController[] stateControllers; public SLContextController[] contextControllers; public float destroyDelay; private Dictionary transforms; // 자주 안쓰일듯해 필요할때 캐싱 public void Init() { anims = GetComponentsInChildren(); renderers = GetComponentsInChildren().Where(r => r is MeshRenderer || r is SkinnedMeshRenderer).ToArray(); particles = GetComponentsInChildren(); trails = GetComponentsInChildren(); stateControllers = GetComponentsInChildren(); contextControllers = GetComponentsInChildren(); foreach (var a in anims) { a.keepAnimatorStateOnDisable = true; a.updateMode = AnimatorUpdateMode.Normal; a.cullingMode = AnimatorCullingMode.AlwaysAnimate; } // TODO: destroyDelay 를 컨트롤하는 별도의 상수 개념 추가 foreach (var t in trails) { destroyDelay = Mathf.Max(destroyDelay, t.time); } foreach (var p in particles) { var main = p.main; if (main.loop) continue; var lt = main.startLifetime; switch (main.startLifetime.mode) { case ParticleSystemCurveMode.Constant: destroyDelay = Mathf.Max(destroyDelay, lt.constant); break; case ParticleSystemCurveMode.TwoConstants: destroyDelay = Mathf.Max(destroyDelay, lt.constantMax, lt.constantMin); break; case ParticleSystemCurveMode.Curve: case ParticleSystemCurveMode.TwoCurves: destroyDelay = Mathf.Max(destroyDelay, lt.curveMultiplier * main.startLifetimeMultiplier); break; } } foreach (var c in stateControllers) { c.Init(); } foreach (var c in contextControllers) { c.Init(); } } public void OnEnable() { foreach (var r in renderers) { r.enabled = true; } foreach (var p in particles) { p.Clear(); p.Play(); } foreach (var t in trails) { t.Clear(); t.emitting = true; } foreach (var c in stateControllers) { c.Clear(); } foreach (var c in contextControllers) { c.Clear(); } } public void Destroy(bool force = false) { foreach (var r in renderers) { r.enabled = false; } foreach (var p in particles) { p.Stop(); } foreach (var t in trails) { t.emitting = false; } foreach (var c in stateControllers) { c.Clear(); } foreach (var c in contextControllers) { c.Clear(); } if (force == false && destroyDelay > 0.0f && gameObject.activeInHierarchy) { StartCoroutine(DelayEnd()); } else { SLResources.DestroyInstance(this); } } private IEnumerator DelayEnd() { transform.SetParent(null, true); yield return new WaitForSeconds(destroyDelay); transform.localPosition = Vector3.zero; transform.localRotation = Quaternion.identity; transform.localScale = Vector3.one; SLResources.DestroyInstance(this); } public void SetKeyword(string state, bool enable = true) { foreach (var c in stateControllers) { c.EnableKeyword(state, enable); } } public void SetContext(SLEntity context) { foreach (var c in contextControllers) { c.SetContext(context); } } public Transform GetTransform(string name) { if (transforms == null) { transforms = new Dictionary(); foreach (var t in GetComponentsInChildren()) { if (transforms.ContainsKey(t.name)) continue; transforms[t.name] = t; } } if (transforms.ContainsKey(name)) { return transforms[name]; } return transform; // 없다면 Root } } }