using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; public class ParticleGroupView : MonoBehaviour { [SerializeField] private Text displayName; [SerializeField] private List _targets = new(); [SerializeField] private Dictionary _childParticleSaver = new(); [SerializeField] private int _currentIndex; [SerializeField] private Canvas _canvas; [SerializeField] private RectTransform _uiParent; private void OnValidate() { if (Application.isEditor) { _targets = new List(); _childParticleSaver = new Dictionary(); int count = transform.childCount; for (int i = 0; i < count; i++) { Transform child = transform.GetChild(i); ParticleSystem ps = child.GetComponent(); if (ps != null) { _targets.Add(ps); } else { bool loopBreak = false; for (int inner = 0; inner < child.childCount; inner++) { Transform nextChild = child.GetChild(inner); ps = nextChild.GetComponent(); if (ps != null) { _targets.Add(ps); _childParticleSaver.Add(ps, child.gameObject); break; } else { for (int tail = 0; tail < nextChild.childCount; tail++) { Transform last = nextChild.GetChild(tail); ps = last.GetComponent(); if (ps != null) { _targets.Add(ps); _childParticleSaver.Add(ps, child.gameObject); loopBreak = true; break; } } if (loopBreak) break; } } } } } if (_canvas == null) { GameObject canvasObject = new GameObject("UI Main Canvas"); _canvas = canvasObject.AddComponent(); _canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvasObject.AddComponent(); canvasObject.AddComponent(); } if (_uiParent == null) { GameObject parent = new GameObject("UI Items", typeof(RectTransform)); parent.transform.SetParent(_canvas.transform); _uiParent = parent.transform as RectTransform; _uiParent.localScale = Vector3.one; _uiParent.anchorMin = Vector3.zero; _uiParent.anchorMax = Vector3.one; _uiParent.offsetMin = Vector3.zero; _uiParent.offsetMax = Vector3.zero; } if (displayName == null) { GameObject textViewer = new GameObject("Text Viewer"); textViewer.transform.SetParent(_uiParent.transform); Text text = textViewer.AddComponent(); text.rectTransform.anchorMin = new Vector2(0, 1); text.rectTransform.anchorMax = new Vector2(1, 1); text.rectTransform.pivot = new Vector2(0.5f, 1); text.rectTransform.anchoredPosition = new Vector3(0, -50); text.fontSize = 55; text.alignment = TextAnchor.MiddleCenter; displayName = text; } if (FindObjectOfType() == null) { GameObject eventSystem = new GameObject("Event System"); eventSystem.AddComponent(); eventSystem.AddComponent(); } } private void Start() { _currentIndex = 0; CleanupDestroyedTargets(); foreach (var particle in _targets) { if (particle != null) particle.gameObject.SetActive(false); } if (_targets.Count > 0 && _targets[_currentIndex] != null) { _targets[_currentIndex].gameObject.SetActive(true); _targets[_currentIndex].Play(true); UpdateDisplayParticleName(); } } private void CleanupDestroyedTargets() { _targets.RemoveAll(p => p == null); } private void UpdateDisplayParticleName() { if (displayName != null && _targets.Count > 0 && _targets[_currentIndex] != null) { displayName.text = _targets[_currentIndex].name; } } private void Update() { if (_targets == null || _targets.Count == 0) return; // 🔹 혹시 Destroy된 ParticleSystem이 리스트에 남아 있다면 제거 CleanupDestroyedTargets(); if (_targets.Count == 0) return; // ← 방향 if (Input.GetKeyDown(KeyCode.LeftArrow)) { SwitchParticle(-1); } // → 방향 if (Input.GetKeyDown(KeyCode.RightArrow)) { SwitchParticle(1); } // 스페이스 재생 if (Input.GetKeyDown(KeyCode.Space)) { var particle = _targets[_currentIndex]; if (particle != null) { particle.Simulate(0, true, true); particle.Play(true); } } } private void SwitchParticle(int direction) { if (_targets.Count == 0) return; var current = _targets[_currentIndex]; if (current != null) { if (_childParticleSaver.TryGetValue(current, out var prevParent) && prevParent != null) prevParent.SetActive(false); current.gameObject.SetActive(false); } _currentIndex = (_currentIndex + direction + _targets.Count) % _targets.Count; var next = _targets[_currentIndex]; if (next != null) { if (_childParticleSaver.TryGetValue(next, out var currentParent) && currentParent != null) currentParent.SetActive(true); next.gameObject.SetActive(true); next.Play(true); UpdateDisplayParticleName(); } } }