ue3d如何在 Unity 中播放音频

如何在 Unity 中播放音频

分类:

在 Unity 中播放音频有几种不同的方法,每种方法都有其独特的优势和用例,在本文中,将详细解释每种方法的工作原理,并提供一些可以在游戏中播放音频使用的示例。

如何在 Unity 中播放音频

播放音频有5种方法

  • audioSource.Play – 从脚本开始单个剪辑
  • audioSource.PlayOneShot – 播放重叠、重复和非循环的声音
  • AudioSource.PlayClipAtPoint – 在 3D 位置播放剪辑,无需音频源
  • audioSource.PlayDelayed 或 audioSource.Playscheduled – 以在将来一次播放剪辑
  • 或者通过在音频源上选择 Play on Awake 以在加载对象时自动播放剪辑

如何使用播放

//播放音频源
audioSource.Play();

从脚本调用 Play 以启动音频源:

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource;
    void Start()
    {
        audioSource.Play();
    }
}

调用 Play 将触发在音频源上设置的任何音频剪辑,这是最常见的触发音频的方法,最适合播放循环声音和音乐。

这是因为其他一些方法,例如 Play One Shot,无法触发循环声音,还因为使用 Play 将只允许从该音频源一次播放一个剪辑。

在已播放的音频源上调用 Play 将停止音频源并重新开始剪辑。

如何使用 Play One Shot

//在音频源上播放特定剪辑一次
audioSource.PlayOneShot(AudioClip audioClip, Float volumeScale);

Play One Shot 可能是在音频源上触发声音的鲜为人知的方法,但对于触发声音效果非常有用。

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource;
    public AudioClip clip;
    public float volume=0.5f;
    void Start()
    {
        audioSource.PlayOneShot(clip, volume);
    }
}

在 Audio Source 上调用 Play One Shot,并获取要播放的音频剪辑的参数。这意味着必须在调用 PlayOneShot 时指定要播放的剪辑。

但是,如果只想播放音频源上的任何剪辑,那么可以像这样传递对该剪辑的引用:

audioSource.PlayOneShot(audioSource.clip, volume);

还可以在调用 Play One Shot 时设置可选的音量比例。这需要一个介于 0 和 1 之间的浮点值,并将相对于音频源的音量调整剪辑的音量。

这对于变化非常有用,因为这意味着可以传入一个随机的音量值,或者以不同的音量播放两个不同的剪辑,而无需更改音频源本身的整体音量。

Play One Shot 是音效的理想选择,尤其是重复的声音。在已经播放的音频源上触发 Play One Shot 将重叠声音,而不是像 Play 那样中断它。

这使得 Play One Shot 特别适合重复声音,但要注意,尽量不要让太多的声音同时重叠。

尽管仅从一个音频源播放,但通过 Play One Shot 触发的两个声音将计为两个声音。尽管最大语音限制可以从默认的 32 个语音增加,但不同平台有不同的限制,因此最好尽量保持语音总数尽可能低,以避免声音被剔除。

如何使用 Play Clip At Point

//在特定位置播放一次剪辑,没有音频源
AudioSource.PlayClipAtPoint(AudioClip clip, Vector3 playPosition, Float volume);

Play Clip at Point 的工作方式与 Play One Shot 类似,但有很大不同。它不需要音频源即可工作。

这对于一次性声音非常有用,因为不需要向对象添加音频源组件,只需从场景中的指定位置触发一次声音,而无需模糊不透。

public class PlayAudio : MonoBehaviour
{
    public AudioClip clip;
    public float volume=1;
    void Start()
    {
        AudioSource.PlayClipAtPoint(clip, transform.position, volume);
    }
}

请注意 AudioSource 中的大写 A,因为 Play Clip at Point 使用 Audio Source 类,而不是 Audio Source 的实例。

还必须传递音频剪辑将从其播放的位置。在这个例子中,使用了这个脚本附加到的对象的位置。

那么这到底是如何工作的呢?

使用 Play Clip At Point 时,Unity 会创建一个临时音频源来播放剪辑。
使用 Play Clip At Point 时,Unity 会创建一个临时音频源来播放剪辑。

在后端 Unity音频 会创建一个新的临时源来播放剪辑,并在剪辑完成后将其处理掉,在编辑器中,会看到一个新的游戏对象出现并在这种情况下消失,这使得 Play Clip at Point 在不能使用音频源组件时特别有用。

例如,在物体被破坏时播放声音。

如果音频源位于被破坏的对象上,声音通常会被切断,或者它可能永远没有机会开始,因为音频源现在不再存在。

相反,使用 Play Clip at Point 可以让声音在对象被破坏后继续播放,该音频源在声音结束后会被整齐地处理掉。

然而,Play Clip at Point 还是存在一点点问题的。

在 Point 处使用 Play Clip 的缺点

由于播放剪辑的音频源是在运行时创建的,因此无法选择更改任何音频源的设置,音频源是使用默认设置创建的,空间混合除外,它将设置为完全 3D。

这也意味着不能将 Play Clip at Point 与混音器一起使用,默认情况下,输出将直接发送到音频侦听器。

如果确实需要更改任何音频源的设置,有一些方法可以解决这个问题,通过创建自己的 Play Clip at Point 功能的修改版本。但是,在这种情况下,简单地使用常规音频源可能会容易得多。

如何使用 Play Delayed 和 Play Scheduled

Play DelayedPlay Scheduled 允许在未来以两种不同的方式播放音频源。

播放延迟

//延迟后播放音频源
AudioSource.PlayDelayed(float delay);

第一个,Play Delayed,以秒为单位延迟,是延迟音频剪辑的最简单方法。

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource;
    public float delay=4;
    void Start()
    {
        // Plays an Audio Clip after 4 seconds
        audioSource.PlayDelayed(delay);
    }
}

此方法易于使用,非常适合快速更改音频源的时序。

使用此功能的示例包括延迟音乐的开始、触发它们的事件之后发生的声音效果,例如闪电和雷声,以及其他时间调整和随机化。

Play Delayed 非常适合简单的计时,但不适合更精确的计时,例如将两个剪辑拼接在一起或节拍匹配的音频剪辑。

为此,需要 PlayScheduled。

播放预定

//在精确的时间播放音频源
AudioSource.PlayScheduled(double timeToPlay);

Play Scheduled 与 Play Delayed 的工作方式略有不同,但它非常精确。

这是因为它使用实际的音频引擎时间运行并采用高精度的双精度值,而不是浮点数。

要使用它,需要指定音频源应该启动的时间,而不是延迟。这对应于AudioSettings.dspTime,即音频引擎已运行的秒数。

Play Scheduled 是精确音频定时任务的理想选择,例如将音频剪辑排队以准确地依次播放,或进行节拍匹配。

下面的示例说明如何在另一个剪辑完成后将剪辑排队以无缝播放。

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource1;
    public AudioSource audioSource2;
    void Start()
    {
        audioSource1.PlayScheduled(AudioSettings.dspTime);
        double clipLength = audioSource1.clip.samples / audioSource1.clip.frequency;
        audioSource2.PlayScheduled(AudioSettings.dspTime + clipLength);
    }

可以使用 PlayScheduled 做很多事情,其中包括如何排队剪辑、节拍匹配音频以及如何用音乐刺痛结束循环的示例。

调度音频时使用 isPlaying 不起作用

使用任一方法调度音频时,音频源被视为在调度后立即播放,直到完成之后。这会在音频源排队时发生,而不是在声音开始时发生,因此 isPlaying 将为真,即使尚未发出声音。

这意味着,在安排音频时,无法使用 isPlaying 检查音频是否已启动或停止。

如何使用 Play on Awake

Play on awake 是触发声音的最简单方法,因为它不需要任何脚本。

启用了 Play on Awake
启用了 Play on Awake

默认启用,Play on Awake 将在对象启用后立即启动音频源,如果游戏对象已经启用,这通常是场景的开始,或者,如果它被禁用,则在游戏对象或音频源激活时 Play on Awake 将立即触发。

这对于在加载对象时自动启动音频很有用,例如场景开始时的音乐或对象初始化时播放的声音。

例如,要在创建新对象时添加声音,只需将 Audio Source 组件添加到该对象的 prefab 并确保选中 Play on Awake。然后,当对象被添加到场景中时,声音就会播放。

有关可以从音频源调用的不同方法的更多信息,请尝试 Unity官方音频源文档

其他选项

虽然 Unity 处理音频的内置选项比以前好得多,但如果想轻松访问高级音频功能 或者 只是想节省一些时间,可能需要考虑第三方 Unity源码

例如, Master Audio 长期以来一直是音频管理器资产不错的选择标准,功能齐全且支持良好,它提供了高级功能,例如音频遮挡,所以使用该工具可以挑战性的多人游戏音频变得更加容易。

音频触发示例

通过以上内容我们大概知道了在 Unity 中触发音频的不同方法,那么将在下面谈谈一些常见音频触发器的示例,可以将它们复制并粘贴到自己的项目中。

如何播放随机声音

Unity 中选择随机声音的最佳方法是什么?首先,创建一个音频源和一组音频剪辑。

public AudioSource audioSource;
public AudioClip[] audioClipArray;

回到 Unity,将不同​​的音频剪辑添加到数组中

AudioClip 数组
AudioClip 数组

接下来,编写一个返回类型为 Audio Clip 的函数,以随机选择其中一个剪辑。

AudioClip RandomClip(){
    return audioClipArray[Random.Range(0, audioClipArray.Length)];
}

然后,每当想使用随机音频剪辑时,请传入通常会传入剪辑名称的函数:

void Start() {
    audioSource.PlayOneShot(RandomClip());
}

如何触发随机声音,不重复

为防止同一声音连续触发两次,请将前一个声音存储在一个变量中,并使用 while 语句对其进行检查,如下所示:

public class PlayAudio : MonoBehaviour 
{
  public AudioSource audioSource;
  public AudioClip[] audioClipArray;
  AudioClip lastClip;
  void Start() 
  {
    audioSource.PlayOneShot(RandomClip());
  }
  AudioClip RandomClip()
  {
    int attempts = 3;
    AudioClip newClip = audioClipArray[Random.Range(0, audioClipArray.Length)];
    while (newClip == lastClip && attempts > 0) 
    {
      newClip = audioClipArray[Random.Range(0, audioClipArray.Length)];
      attempts--;
    }
    lastClip = newClip;
    return newClip;
  }
}

如何播放重复的声音

下面是一个如何在 Unity 中重复触发声音的示例,在例子中为每 0.25 秒发射一次的声音。

还使用上一个示例中的 Audio Clip 数组在每次射击时使用随机声音。

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource;
    public AudioClip[] audioClipArray;
    public float timeBetweenShots = 0.25f;
    float timer;
    void Update()
    {
        timer += Time.deltaTime;
        if (timer > timeBetweenShots)
        {
            audioSource.PlayOneShot(RandomClip());
            timer = 0;
        }
    }
    AudioClip RandomClip()
    {
        return audioClipArray[Random.Range(0, audioClipArray.Length-1)];
    }
}

按下按钮时如何播放声音

Unity 有一个内置方法,用于在按下按钮时触发事件,其中包括播放音频剪辑的选项。

只需创建一个 On Click 事件触发器,将一个游戏对象拖到对象字段并从下拉菜单的音频源部分选择 PlayOneShot(AudioClip)

带有音频源的对象拖到按钮 On Click 事件,然后选择 PlayOneShot(AudioClip) 选项。
带有音频源的对象拖到按钮 On Click 事件,然后选择 PlayOneShot(AudioClip) 选项

选择播放一个后,在出现的新字段中选择要播放的音频剪辑。通过使用 Play One Shot,可以让不同的按钮仅使用一个音频源播放不同的声音。

但是,也可以从 PlayPlayDelayed 中进行选择,就像从脚本播放时一样。

进入区域时如何启动音乐

如何在 Unity 中制作当角色进入特定区域时触发的音乐触发器?

首先创建触发器:

  • 创建一个形状,例如一个盒子,作为场景中的触发区域。
  • 如果有网格渲染器,请删除它,不需要。
  • Collider 组件上确保 Is Trigger 设置为 true
  • 如果 Player 对象还没有,需要添加一个刚体组件才能使其工作。
  • 最后,在 Player 对象上,选择 Player Tag
add tag
add tag

接下来,将此脚本添加到触发区域:

public class PlayOnCollision : MonoBehaviour
{
    public AudioSource audioSource;
    void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Player" && !audioSource.isPlaying)
        {
            audioSource.Play();
        }
    }
}

如何在 2D 中创建触发声音

要在 2D 项目中创建相同的效果,只需使用 2D Collider2D Rigidbody,确保更新脚本以匹配:

void OnTriggerEnter2D(Collider2D other)
{
    if (other.tag == "Player" && !audioSource.isPlaying)
    {
        audioSource.Play();
    }
}

与物体碰撞时如何播放声音

就像进入一个区域一样,可以在两个物体发生碰撞时触发声音,对象需要有一个刚体组件才能工作。

将此脚本放在移动对象上:

public class PlayOnCollision : MonoBehaviour
{
    public AudioSource audioSource;
    void OnCollisionEnter(Collision collision)
    {
        audioSource.Play();
    }
}

为了防止轻微碰撞触发声音,可以通过检查碰撞的速度只播放较大碰撞的声音:

public class PlayOnCollision : MonoBehaviour
{
    public AudioSource audioSource;
    void OnCollisionEnter(Collision collision)
    {
        if(collision.relativeVelocity.magnitude > 1)
            audioSource.Play();
    }
}

或者,为了获得更自然的碰撞声音,可以根据碰撞力改变音量。

public class PlayOnCollision : MonoBehaviour
{
    public AudioSource audioSource;
    public float maxForce = 5;
    void OnCollisionEnter(Collision collision)
    {
        float force = collision.relativeVelocity.magnitude;
        float volume = 1;
        if (force <= maxForce)
        {
            volume = force / maxForce;
        }
        audioSource.PlayOneShot(audioSource.clip, volume);
    }
}

音量值决定了什么样的冲击力会产生最大的声音量,超过最大的值只会以最大音量播放。

如何在 2D 中创建碰撞声音

可以使用相同的方法在 2D 游戏中使用 2D Colliders2D Rigidbody 和更新脚本类来创建碰撞音效,如下所示:

void OnCollisionEnter2D(Collision2D collision)
{
    audioSource.Play();
}

如何在破坏物体时播放声音

要在对象被破坏后继续播放声音,一种选择是使用 Play Clip at Point,如下所示:

public class PlayOnDestroy : MonoBehaviour
{
    public AudioClip audioClip;
    void DestroyObject()
    {
        AudioSource.PlayClipAtPoint(audioClip, transform.position);
        Destroy(gameObject);
    }
}

这通过创建一个在对象的最后一个位置播放的临时音频源来工作,即使原始对象已经消失。

以上涵盖的音频基础知识,可以轻松地了解更多信息,以便在未来进行研究或为未来的音频开发更先进的思路,都是可以的。

相关信息

  • 类型:知识
  • 字数:3043
  • 字符:11842
  • 适用软件:Unity
  • 说明:无
  • 编号:61452

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!