Add BeatPulseController for music synchronization and event handling
This commit is contained in:
66
Assets/Scripts/Infrastructure/Unity/BeatPulseController.cs
Normal file
66
Assets/Scripts/Infrastructure/Unity/BeatPulseController.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Infrastructure.Unity
|
||||
{
|
||||
public class BeatPulseController : MonoBehaviour
|
||||
{
|
||||
[Header("Music Settings")]
|
||||
[Tooltip("Beats Per Minute of your track")]
|
||||
[SerializeField] private float bpm = 90f;
|
||||
[Tooltip("Delay in seconds to sync the first beat with the music start")]
|
||||
[SerializeField] private float startDelay = 0.0f;
|
||||
|
||||
[Header("Events")]
|
||||
public UnityEvent OnBeat; // Fires every beat (1, 2, 3, 4)
|
||||
public UnityEvent OnMeasure; // Fires every 4th beat (The Drop)
|
||||
|
||||
private float _beatInterval;
|
||||
private float _timer;
|
||||
private int _beatCount;
|
||||
private bool _isRunning;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (bpm > 0) _beatInterval = 60f / bpm;
|
||||
}
|
||||
|
||||
public void BeginTracking()
|
||||
{
|
||||
_timer = -startDelay;
|
||||
_beatCount = 0;
|
||||
_isRunning = true;
|
||||
}
|
||||
|
||||
public void StopTracking()
|
||||
{
|
||||
_isRunning = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isRunning) return;
|
||||
|
||||
_timer += Time.deltaTime;
|
||||
|
||||
if (_timer >= _beatInterval)
|
||||
{
|
||||
_timer -= _beatInterval;
|
||||
Pulse();
|
||||
}
|
||||
}
|
||||
|
||||
private void Pulse()
|
||||
{
|
||||
_beatCount++;
|
||||
|
||||
OnBeat?.Invoke();
|
||||
|
||||
if (_beatCount % 4 == 0)
|
||||
{
|
||||
OnMeasure?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e65ed2be995f4ab9b6205cbca1a6ad22
|
||||
timeCreated: 1765582012
|
||||
@@ -46,5 +46,9 @@ namespace Infrastructure.Unity
|
||||
_shakeTimer = duration;
|
||||
_shakeMagnitude = magnitude;
|
||||
}
|
||||
|
||||
public void ShakeLight() => Shake(.1f, .1f);
|
||||
public void ShakeMedium() => Shake(.15f, .3f);
|
||||
public void ShakeHeavy() => Shake(.1f, .5f);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ namespace Infrastructure.Unity
|
||||
[SerializeField] private DeathPlaneAdapter deathPlanePrefab;
|
||||
[SerializeField] private SoundManager soundManager;
|
||||
[SerializeField] private RumbleManager rumbleManager;
|
||||
[SerializeField] private BeatPulseController beatPulseController;
|
||||
[SerializeField] private CameraController cameraController;
|
||||
[SerializeField] private NpcController npcPrefab;
|
||||
[SerializeField] private HunterNpcController hunterNpcPrefab;
|
||||
@@ -181,6 +182,9 @@ namespace Infrastructure.Unity
|
||||
private void HandleGameOver()
|
||||
{
|
||||
_isGameRunning = false;
|
||||
|
||||
if (beatPulseController) beatPulseController.StopTracking();
|
||||
|
||||
if (gameOverUi) gameOverUi.SetActive(true);
|
||||
|
||||
StartCoroutine(RestartRoutine());
|
||||
@@ -253,6 +257,8 @@ namespace Infrastructure.Unity
|
||||
{
|
||||
soundManager.PlayGameStart();
|
||||
soundManager.PlayMusic();
|
||||
|
||||
if (beatPulseController) beatPulseController.BeginTracking();
|
||||
}
|
||||
|
||||
if (_playerInstance)
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Infrastructure.Unity
|
||||
|
||||
private MaterialPropertyBlock _propBlock;
|
||||
private static readonly int ColorProperty = Shader.PropertyToID("_BaseColor");
|
||||
private static readonly int EmissionIntensity = Shader.PropertyToID("_EmissionIntensity");
|
||||
|
||||
private Action<TileViewAdapter> _onReturnToPool;
|
||||
|
||||
@@ -108,6 +109,12 @@ namespace Infrastructure.Unity
|
||||
_linkedTile?.StepOn();
|
||||
}
|
||||
|
||||
public void PulseEmission(float intensity)
|
||||
{
|
||||
StartCoroutine(PulseEmissionRoutine(intensity, 0.2f));
|
||||
StartCoroutine(PulseScaleRoutine());
|
||||
}
|
||||
|
||||
private void SetColor(Color color)
|
||||
{
|
||||
meshRenderer.GetPropertyBlock(_propBlock);
|
||||
@@ -157,5 +164,26 @@ namespace Infrastructure.Unity
|
||||
_linkedTile.OnStateChanged -= OnTileStateChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator PulseScaleRoutine()
|
||||
{
|
||||
var original = transform.localScale;
|
||||
transform.localScale = original * 1.05f;
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
transform.localScale = original;
|
||||
}
|
||||
|
||||
private IEnumerator PulseEmissionRoutine(float intensity, float duration)
|
||||
{
|
||||
meshRenderer.GetPropertyBlock(_propBlock);
|
||||
var originalIntensity = _propBlock.GetFloat(EmissionIntensity);
|
||||
_propBlock.SetFloat(EmissionIntensity, intensity);
|
||||
meshRenderer.SetPropertyBlock(_propBlock);
|
||||
|
||||
yield return new WaitForSeconds(duration);
|
||||
|
||||
_propBlock.SetFloat(EmissionIntensity, originalIntensity);
|
||||
meshRenderer.SetPropertyBlock(_propBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user