using System; using UnityEngine; public enum RhythmNoteType { Paw, Fish, Music } [RequireComponent(typeof(RectTransform))] public class RhythmNote : MonoBehaviour { [Header("Note")] [SerializeField] private RhythmNoteType noteType = RhythmNoteType.Paw; [Header("Runtime")] [SerializeField] private float moveSpeed = 360f; [SerializeField] private float hitZoneLocalX; [SerializeField] private float autoMissDistance = 90f; private RectTransform rectTransform; private bool initialized; private bool judged; public RhythmNoteType NoteType => noteType; public bool IsJudged => judged; public float HitZoneLocalX => hitZoneLocalX; public RectTransform RectTransform => rectTransform; public event Action PassedHitZone; private void Awake() { rectTransform = GetComponent(); } private void Update() { if (!initialized || judged) return; MoveNote(); CheckAutoMiss(); } public void Initialize(float speed, float targetHitZoneLocalX, float missDistance) { if (rectTransform == null) rectTransform = GetComponent(); moveSpeed = speed; hitZoneLocalX = targetHitZoneLocalX; autoMissDistance = Mathf.Max(0f, missDistance); judged = false; initialized = true; gameObject.SetActive(true); } private void MoveNote() { Vector2 position = rectTransform.anchoredPosition; position.x += moveSpeed * Time.deltaTime; rectTransform.anchoredPosition = position; } private void CheckAutoMiss() { if (rectTransform.anchoredPosition.x <= hitZoneLocalX + autoMissDistance) return; MarkJudged(); PassedHitZone?.Invoke(this); } public float GetDistanceToHitZone() { if (rectTransform == null) rectTransform = GetComponent(); return Mathf.Abs(rectTransform.anchoredPosition.x - hitZoneLocalX); } public void MarkJudged() { judged = true; initialized = false; } public void Remove() { MarkJudged(); Destroy(gameObject); } }