Files
bansonic_beta_main/Assets/scripts/gamePlay_gameplay/NoteController.cs
T

123 lines
3.6 KiB
C#

using System.Collections;
using UnityEngine;
public class NoteController : MonoBehaviour
{
private float speed;
private bool isMoving = true;
private bool isInJudgeZone = false; // 判定范围内
private ParticleSystem hitEffect;
private Note linkedNote;
// For absolute position tracking instead of relative translate
private Vector3 spawnPosition;
private float activationTime = -1f; // When the note should start moving (hitTime - travelTime)
private float baseSpawnYOffset = 0f; // Initial Y offset from compensation at spawn time
private void Awake()
{
hitEffect = GetComponentInChildren<ParticleSystem>();
linkedNote = GetComponent<Note>();
spawnPosition = transform.position;
}
private void Update()
{
if (isMoving && activationTime >= 0f)
{
// Use absolute positioning based on elapsed time since activation
float elapsedSinceActivation = Time.time - activationTime;
float travelDistance = speed * Mathf.Max(0f, elapsedSinceActivation);
// Position = spawnPoint + initial offset + downward travel
Vector3 newPos = spawnPosition;
newPos.y -= (baseSpawnYOffset + travelDistance);
transform.position = newPos;
}
}
public void SetSpeed(float newSpeed)
{
speed = newSpeed;
}
public void StopMovement()
{
isMoving = false;
}
public void PlayHitEffect()
{
if (hitEffect != null)
{
hitEffect.Play();
}
}
/// <summary>
/// Configure timing for absolute position tracking.
/// Call this from NoteSpawner after the note is spawned.
/// </summary>
public void ConfigureAbsolutePositioning(Vector3 initialSpawnPos, float hitTime, float travelTime, float initialYOffset)
{
spawnPosition = initialSpawnPos;
activationTime = hitTime - travelTime;
baseSpawnYOffset = initialYOffset;
if (GameConfig.verboseLogs)
Debug.Log($"[NoteController] Configured: spawnPos={spawnPosition}, activationTime={activationTime:F3}, initialYOffset={initialYOffset:F4}");
}
public void ResetState()
{
speed = 0f;
isMoving = true;
isInJudgeZone = false;
activationTime = -1f;
baseSpawnYOffset = 0f;
spawnPosition = transform.position;
if (hitEffect != null)
{
hitEffect.Stop();
hitEffect.Clear();
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("JudgmentLine"))
{
if (linkedNote != null)
{
isInJudgeZone = true;
// register note by instance id so TrackKeyManager can prioritize
// tap notes are short notes without hold
TrackKeyManager.Instance.RegisterKey(linkedNote.GetTrackIndex(), linkedNote.gameObject.GetInstanceID().ToString(), "tap");
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("JudgmentLine"))
{
if (linkedNote != null)
{
isInJudgeZone = false;
TrackKeyManager.Instance.UnregisterKey(linkedNote.GetTrackIndex(), linkedNote.gameObject.GetInstanceID().ToString());
linkedNote.SetJudgeZone(isInJudgeZone);
}
}
}
/// <summary>
/// Query Note whether it's in judge zone
/// </summary>
public bool IsInJudgeZone()
{
return isInJudgeZone;
}
}