【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/
本章节添加了循环播放的BGM,并且给武器攻击加上了音效
音频管理器
AudioManager.cs
1. 类的功能
- 核心目标 :管理游戏中的音频播放,包括:
- 播放和停止 音效(SFX)。
- 播放、停止或随机播放 背景音乐(BGM)。
- 单例模式 :确保在场景中只有一个
AudioManager
实例。
2. 核心逻辑
Awake()
- 确保单例模式:
- 如果已有一个
AudioManager
实例,则销毁新创建的实例,避免重复。 - 如果没有实例,则将当前实例设为唯一实例。
- 如果已有一个
Update()
- 每帧检查
playBgm
:- 如果
playBgm
为 false,停止所有背景音乐。 - 如果
playBgm
为 true 且当前音乐未播放,则播放指定的背景音乐。
- 如果
PlaySFX(int _sfxIndex)
- 播放指定索引的音效:
- 随机调整音调(
pitch
),让音效有更多变化感(范围:0.85
到1.15
)。 - 播放指定音效。
- 随机调整音调(
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioManager : MonoBehaviour
{
public static AudioManager instance;
[SerializeField] private AudioSource[] sfx;//音效
[SerializeField] private AudioSource[] bgm;//背景音乐
public bool playBgm;
private int bgmIndex;
private void Awake()
{
if(instance != null)
Destroy(instance.gameObject);
else
instance = this;
}
private void Update()
{
if (!playBgm)
StopAllBGM();
else
{
if(!bgm[bgmIndex].isPlaying)//如果背景音乐没有播放
PlayBGM(bgmIndex);
}
}
public void PlaySFX(int _sfxIndex)//播放音效
{
if (_sfxIndex < sfx.Length)
{
sfx[_sfxIndex].pitch = Random.Range(.85f, 1.15f);//设置音效的音调
sfx[_sfxIndex].Play();
}
}
public void StopSFX(int _index) => sfx[_index].Stop();//停止音效
public void PlayRandomBGM()//播放随机背景音乐
{
bgmIndex = Random.Range(0, bgm.Length);
PlayBGM(bgmIndex);
}
public void PlayBGM(int _bgmIndex)//播放背景音乐
{
bgmIndex = _bgmIndex;
StopAllBGM();
bgm[bgmIndex].Play();
}
public void StopAllBGM()
{
for (int i = 0; i < bgm.Length; i++)
{
bgm[i].Stop();
}
}
}
为了防止听相同的音效听腻,所以加上了随机音调的效果
cs
sfx[_sfxIndex].pitch = Random.Range(.85f, 1.15f);//设置音效的音调
PlayerAnimationTriggers.cs
添加了攻击触发的音效
cs
AudioManager.instance.PlaySFX(2);//播放音效
cs
using UnityEngine;
public class PlayerAnimationTriggers : MonoBehaviour
{
private Player player => GetComponentInParent<Player>();
private void AnimationTrigger()
{
player.AnimationTrigger();
}
private void AttackTrigger()//攻击触发函数
{
AudioManager.instance.PlaySFX(2);//播放音效
Collider2D[] colliders = Physics2D.OverlapCircleAll(player.attackCheck.position, player.attackCheckRadius);//检测区域内的敌人
foreach (var hit in colliders)//遍历检测到的对象
{
if (hit.GetComponent<Enemy>() != null)
{
EnemyStats _target = hit.GetComponent<EnemyStats>();//判断是否是敌人
if (_target != null) //对敌人造成伤害
player.stats.DoDamage(_target);
ItemData_Equipment weaponData = Inventory.instance.GetEquipment(EquipmentType.Weapon);
if (weaponData != null)//应用武器特殊效果
weaponData.Effect(_target.transform);
}
}
}
private void ThrowSword()
{
SkillManager.instance.sword.CreateSword();
}
}