ProjectDDD/Packages/SLUnity/SLResourceObject.cs
2025-07-08 19:46:31 +09:00

188 lines
5.4 KiB
C#

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<string, Transform> transforms; // 자주 안쓰일듯해 필요할때 캐싱
public void Init()
{
anims = GetComponentsInChildren<Animator>();
renderers = GetComponentsInChildren<Renderer>().Where(r => r is MeshRenderer || r is SkinnedMeshRenderer).ToArray();
particles = GetComponentsInChildren<ParticleSystem>();
trails = GetComponentsInChildren<TrailRenderer>();
stateControllers = GetComponentsInChildren<SLStateController>();
contextControllers = GetComponentsInChildren<SLContextController>();
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<string, Transform>();
foreach (var t in GetComponentsInChildren<Transform>())
{
if (transforms.ContainsKey(t.name)) continue;
transforms[t.name] = t;
}
}
if (transforms.ContainsKey(name))
{
return transforms[name];
}
return transform; // 없다면 Root
}
}
}