Controle o número de efeitos sonoros simultâneos reproduzidos

Página atualizada :
Data de criação de página :

Ambiente de verificação

Windows
  • Janelas 11
Unity Editor
  • 2021.3.3f1
Pacote do sistema de entrada
  • 1.3.0

Pré-requisitos para esta dica

As configurações a seguir foram feitas com antecedência como premissa para a descrição desta dica.

Sobre o material incluído na amostra

Os efeitos sonoros são emprestados dos seguintes sites.

Sobre arquivos de áudio

Os seguintes formatos de arquivo de áudio podem ser reproduzidos com os recursos padrão do Unity: Por favor, prepare-o com antecedência, pois ele será usado nessas dicas.

  • WAV (.wav)
  • OggVorbis (.ogg)
  • MPEG camada 3 (.mp3)

Para obter mais informações, consulte a documentação oficial do Unity.

Sobre o limite superior e o volume de várias reproduções de áudio simultâneas

Nas dicas anteriores, AudioClip agora é possível reproduzir várias vozes reproduzindo-as enquanto prepara AudioSource.PlayOneShot dados de áudio no . No entanto, não há limite para o número de jogos que podem ser jogados, portanto, se você não limitá-lo durante o jogo, um monte de som pode ser jogado e um volume alto pode ser jogado.

Aqui eu gostaria de criar meu próprio programa e controlar o número de efeitos sonoros que podem ser reproduzidos ao mesmo tempo.

Criar o exemplo

Desta vez, o efeito sonoro será reproduzido toda vez que você clicar no botão, portanto, crie a interface do usuário conforme mostrado na figura. Os detalhes são apropriados e bons.

Solte e adicione o arquivo de áudio que você deseja reproduzir em seu projeto.

Até a última vez, a função AudioSource padrão de foi adicionada à hierarquia, Desta vez, vamos adicionar um script porque vamos colocar nosso próprio controle. SoundPlayManager Deixe o nome como .

Crie o script da seguinte maneira:

using System.Collections.Generic;
using UnityEngine;

/// <summary>音声再生管理クラスです。</summary>
public class SoundPlayManager : MonoBehaviour
{
  /// <summary>1つの種類の音声の再生情報を保持するクラスです。</summary>
  private class PlayInfo
  {
    /// <summary>再生している AudioSource の一覧です。</summary>
    public AudioSource[] AudioSource { get; set; }

    /// <summary>現在の再生インデックスです。</summary>
    public int NowIndex { get; set; }
  }

  /// <summary>再生しようとしている音声データのキューです。</summary>
  private HashSet<AudioClip> Queue = new HashSet<AudioClip>();

  /// <summary>再生している音声を管理している一覧です。</summary>
  private Dictionary<AudioClip, PlayInfo> Sources = new Dictionary<AudioClip, PlayInfo>();

  /// <summary>
  /// 同一音声同時再生最大数。
  /// </summary>
  [SerializeField, Range(1, 32)] private int MaxSimultaneousPlayCount = 2;

  protected void Update()
  {
    foreach (var item in Queue)
    {
      AudioSource source;
      if (Sources.ContainsKey(item) == false)
      {
        // 一度も再生されていない Clip がある場合は PlayInfo を生成します
        var info = new PlayInfo()
        {
          AudioSource = new AudioSource[MaxSimultaneousPlayCount],
        };
        for (int i = 0; i < MaxSimultaneousPlayCount; i++)
        {
          var s = gameObject.AddComponent<AudioSource>();
          s.clip = item;
          info.AudioSource[i] = s;
        }
        Sources.Add(item, info);
        source = info.AudioSource[0];
      }
      else
      {
        // 再生に使用する AudioSource を順番に取得します
        var info = Sources[item];
        info.NowIndex = (info.NowIndex + 1) % MaxSimultaneousPlayCount;
        source = info.AudioSource[info.NowIndex];
      }

      source.Play();
    }
    Queue.Clear();
  }

  /// <summary>
  /// 効果音を再生します。
  /// </summary>
  public void Play(AudioClip clip)
  {
    // 同一フレームで複数再生しないようにすでにキューに入っているか確認します
    if (Queue.Contains(clip) == false)
    {
      Queue.Add(clip);
    }
  }

  public void OnDestroy()
  {
    // 不要になった参照をすべて外します
    foreach (var source in Sources)
    {
      source.Value.AudioSource = null;
    }
    Sources.Clear();
    Queue.Clear();
  }
}

Como o script é longo, a explicação detalhada é omitida, mas tem as seguintes funções.

  • AudioClip Você pode reproduzir áudio passando
  • Quando o mesmo tipo de áudio é reproduzido um sobre o outro, se você tentar reproduzir mais de um determinado número de vozes, os dados de reprodução antigos param (o valor inicial é de até 2 reproduções).
  • Não é permitida a reprodução sobreposta no mesmo quadro

Isso evita que o volume aumente quando o mesmo áudio é reproduzido consecutivamente. Em termos de funcionalidade, apenas o mínimo está incluído, então adicione-o se precisar.

O script é anexado ao EventSystem.

Em seguida, crie um script para o botão.

Crie o script da seguinte maneira:

using UnityEngine;

public class ButtonEvent : MonoBehaviour
{
  /// <summary>再生する音声データ。</summary>
  [SerializeField] private AudioClip AudioClip;

  /// <summary>自作した音声再生管理クラス。</summary>
  [SerializeField] private SoundPlayManager SoundPlayManager;

  /// <summary>ボタンをクリックしたとき。</summary>
  public void OnClick()
  {
    SoundPlayManager.Play(AudioClip);
  }
}

O processo de reprodução é feito pelo próprio self-made SoundPlayManager , então, no evento de botão, basta passar os dados de áudio e reproduzi-lo.

O script é anexado ao EventSystem. A gestão de anexos não é o tema principal desta Dicas, por isso é apropriado.

Para o clipe de áudio, defina o arquivo de áudio a ser reproduzido. Defina o Gerenciador de Reprodução de Som para o SoundPlayManager objeto ao qual você está anexando. Como estamos anexando ao EventSystem, definiremos o EventSystem.

Finalmente, atribua ao evento de clique no OnClick botão.

Execute o jogo quando terminar. Por padrão, o número máximo de reproduções simultâneas é definido como 2, então clique no botão novamente enquanto dois sons estão sendo reproduzidos e certifique-se de que o primeiro som desapareça.

O programa criado desta vez tem um limite superior no número de tempos de reprodução para cada tipo de som, por isso soa natural, mesmo se você entrelaçar outros efeitos sonoros. No entanto, dependendo do tipo de som, o limite superior de 2 pode não ser suficiente, por isso pode ser uma boa ideia ser capaz de definir um limite superior para cada tipo de som. Bem, eu não sei se há essa oportunidade de camuflar o som, mas...