我创建了一个 Metronome 脚本,使用 MusicController 脚本中的 bpm 变量计算节拍间隔。当节拍前进时,我设置动画触发器以切换到节拍器 UI 的另一个精灵。
我发现节拍器动画有一点延迟,我不知道如何减少它的延迟,使其与音乐相匹配。关于如何修复它有什么想法吗?
除此之外,我还有方法 IsOnBeat() ,它在节拍更改后在一个小beatWindow 中返回 true。我在 EnvironmentBeat 类中使用该方法,该方法现在控制对象的比例以随着节拍“跳舞”。我发现它有点问题,事实中的对象会随着节拍缩放,但有时它们会出现故障,您可以看到它们缩放 2-3 倍,而 IsOnBeat 为 true。
节拍器课:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Metronome : MonoBehaviour
{
[Header("Metronome Settings")]
public float bpm;
public float beatWindow = 0.2f;
public float delayStart;
private float _beatInterval;
private float _timer;
private int _currentBeat = 1;
private float _lastBeatTime;
private bool _canStart;
[Header("References")]
public AudioSource audioSource;
public MusicController musicController;
private Animator _animator;
private void Start()
{
_canStart = false;
audioSource = GetComponent<AudioSource>();
_animator = GetComponent<Animator>();
StartCoroutine(CheckBpm(delayStart / 3));
StartCoroutine(DelayStart(delayStart));
}
private void Update()
{
if (_canStart)
{
_timer += Time.deltaTime;
if (_timer >= _beatInterval)
{
_timer -= _beatInterval;
AdvanceBeat();
}
}
}
private void AdvanceBeat()
{
_animator.SetTrigger("NextBeat");
audioSource.Play();
_currentBeat++;
if (_currentBeat > 4)
{
_currentBeat = 1;
}
_lastBeatTime = Time.time;
}
private void CalculateBeatInterval()
{
_beatInterval = 60f / bpm;
}
public void SetBpm(int newBpm)
{
bpm = newBpm;
CalculateBeatInterval();
}
public int GetCurrentBeat()
{
return _currentBeat;
}
public bool IsOnBeat()
{
float timeSinceLastBeat = Time.time - _lastBeatTime;
return timeSinceLastBeat <= beatWindow;
}
public int BeatMultiplier()
{
switch (_currentBeat)
{
case 1:
return 5;
case 2:
return 2;
case 3:
return 5;
case 4:
return 2;
}
return 2;
}
private IEnumerator DelayStart(float delay)
{
yield return new WaitForSeconds(delay);
_canStart = true;
_timer = 0;
musicController.audioSourceA.Play();
}
private IEnumerator CheckBpm(float delay)
{
yield return new WaitForSeconds(delay);
bpm = musicController.currentTrack.bpm;
CalculateBeatInterval();
}
}
EnvironmentBeat 类:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnvironmentBeat : MonoBehaviour
{
[Header("Settings")]
public bool isScaling;
public bool isJumping;
[Header("References")]
public Metronome metronome;
private Vector3 _originalScale;
private void Start()
{
_originalScale = transform.localScale;
}
private void Update()
{
if (metronome.IsOnBeat())
{
if (isScaling)
{
BeatScaling();
}
}
if (isJumping)
{
Debug.Log("Not Implemented");
}
}
private void BeatScaling()
{
float scaleMultiplier = 1.2f;
transform.localScale = _originalScale * scaleMultiplier;
StartCoroutine(ResetScaleAfterDelay(0.1f));
}
private IEnumerator ResetScaleAfterDelay(float delay)
{
yield return new WaitForSeconds(delay);
transform.localScale = _originalScale;
}
}
我正在考虑测量延迟并将其应用于启动音频剪辑或节拍器动画,但我不确定当前延迟是否特定于硬件,我可以想象在较慢/较快的电脑上它可能会有所不同。
尝试使用FixedUpdate而不是Update也许。
https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html