在Unity中将动画与bpm同步

问题描述 投票:0回答:1

我创建了一个 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;
    }
}

我正在考虑测量延迟并将其应用于启动音频剪辑或节拍器动画,但我不确定当前延迟是否特定于硬件,我可以想象在较慢/较快的电脑上它可能会有所不同。

unity-game-engine audio synchronization
1个回答
0
投票

尝试使用FixedUpdate而不是Update也许。

https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html

© www.soinside.com 2019 - 2024. All rights reserved.