本章节添加了更多音效案例
源代码
AudioManager.cs
音效可以同时播放(以下代码注释掉)
//防止多个相同音效同时播放
//if (sfx[_sfxIndex].isPlaying)
// return;
完整代码
using UnityEngine;
public class AudioManager : MonoBehaviour
{
public static AudioManager instance;
[SerializeField] private float sfxMinimumDistance;
[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()
{
//播放bgm
if (!playBgm)
StopAllBGM();
else
{
if (!bgm[bgmIndex].isPlaying)
PlayBGM(bgmIndex);
}
}
//播放音效
public void PlaySFX(int _sfxIndex,Transform _source)
{
防止多个相同音效同时播放
//if (sfx[_sfxIndex].isPlaying)
// return;
//音效距离限制
if (_source != null && Vector2.Distance(PlayerManager.instance.player.transform.position, _source.position) > sfxMinimumDistance)
return;
if (_sfxIndex < sfx.Length)
{
//随机音高防止听腻
sfx[_sfxIndex].pitch = Random.Range(.85f, 1.1f);
sfx[_sfxIndex].Play();
}
}
//停止播放音效
public void StopSFX(int _sfxIndex) => sfx[_sfxIndex].Stop();
//播放随机bgm
public void PlayRandomBGM()
{
bgmIndex = Random.Range(0, bgm.Length);
PlayBGM(bgmIndex);
}
//播放bgm
public void PlayBGM(int _bgmIndex)
{
bgmIndex = _bgmIndex;
StopAllBGM();
bgm[bgmIndex].Play();
}
//停止播放所有bgm
public void StopAllBGM()
{
for (int i = 0; i < bgm.Length; i++)
{
bgm[i].Stop();
}
}
}
PlayerMoveState.cs
走路音效
public override void Enter()
{
base.Enter();
//播放走路音效
AudioManager.instance.PlaySFX(14,null);
}
public override void Exit()
{
base.Exit();
//停止走路音效
AudioManager.instance.StopSFX(14);
}
完整代码
public class PlayerMoveState : PlayerGroundState
{
public PlayerMoveState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
{
}
public override void Enter()
{
base.Enter();
//播放走路音效
AudioManager.instance.PlaySFX(14,null);
}
public override void Exit()
{
base.Exit();
//停止走路音效
AudioManager.instance.StopSFX(14);
}
public override void Update()
{
base.Update();
player.SetVelocity(xInput * player.moveSpeed, rb.velocity.y);
if (xInput == 0)
{
stateMachine.ChangeState(player.idleState);
}
}
}
CheckPoint.cs
解锁检查点音效
//若经过的检查点未解锁播放音效
if(!activationStatus)
AudioManager.instance.PlaySFX(5,transform);
完整代码
using UnityEngine;
public class CheckPoint : MonoBehaviour
{
private Animator anim;
public string Id;
public bool activationStatus;
private void Awake()
{
anim = GetComponent<Animator>();
}
private void Start()
{
}
[ContextMenu("生成检查点Id")]
private void GenerateId()
{
Id = System.Guid.NewGuid().ToString();
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.GetComponent<Player>() != null)
{
ActivateCheckPoint();
SaveManager.instance.SaveGame();
}
}
public void ActivateCheckPoint()
{
//若经过的检查点未解锁播放音效
if(!activationStatus)
AudioManager.instance.PlaySFX(5,transform);
activationStatus = true;
anim.SetBool("active", true);
}
}
ItemObject.cs
拾取物品音效
//播放拾取物品音效
AudioManager.instance.PlaySFX(18, transform);
完整代码
using UnityEngine;
public class ItemObject : MonoBehaviour
{
[SerializeField] private Rigidbody2D rb;
[SerializeField] private ItemData itemData;
private void SetupVisuals()
{
if (itemData == null)
return;
GetComponent<SpriteRenderer>().sprite = itemData.icon;
gameObject.name = "Item object - " + itemData.name;
}
public void SetupItem(ItemData _itemData, Vector2 _velocity)
{
itemData = _itemData;
rb.velocity = _velocity;
SetupVisuals();
}
public void PickupItem()
{
if (!Inventory.instance.CanAddItem() && itemData.itemType == ItemType.Equipment)
{
rb.velocity = new Vector2(0, 7);
return;
}
//播放拾取物品音效
AudioManager.instance.PlaySFX(18, transform);
Inventory.instance.AddItem(itemData);
Destroy(gameObject);
}
}
Blackhole_Skill.cs
黑洞技能人物语音及技能音效
//播放人物语音音效
AudioManager.instance.PlaySFX(3, player.transform);
//播放技能音效
AudioManager.instance.PlaySFX(6, player.transform);
完整代码
using UnityEngine;
using UnityEngine.UI;
public class Blackhole_Skill : Skill
{
[SerializeField] private UI_SkillTreeSlot blackHoleUnlockButton;
public bool blackHoleUnlocked { get; private set; }
[SerializeField] private int amountOfAttacks;
[SerializeField] private float cloneAttackCooldown;
[SerializeField] private float blackholeDuration;
[Space]
[SerializeField] private GameObject blackHolePrefab;
[SerializeField] private float maxSize;
[SerializeField] private float growSpeed;
[SerializeField] private float shrinkSpeed;
Blackhole_Skill_Controller currentBlackhole;
private void UnlockBlackHole()
{
if (blackHoleUnlockButton.unlocked)
blackHoleUnlocked = true;
}
public override bool CanUseSkill()
{
return base.CanUseSkill();
}
public override void UseSkill()
{
base.UseSkill();
GameObject newBlackHole = Instantiate(blackHolePrefab, player.transform.position, Quaternion.identity);
currentBlackhole = newBlackHole.GetComponent<Blackhole_Skill_Controller>();
currentBlackhole.SetupBlackhole(maxSize, growSpeed, shrinkSpeed, amountOfAttacks, cloneAttackCooldown, blackholeDuration);
//播放人物语音音效
AudioManager.instance.PlaySFX(3, player.transform);
//播放技能音效
AudioManager.instance.PlaySFX(6, player.transform);
}
protected override void Start()
{
base.Start();
blackHoleUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockBlackHole);
}
protected override void CheckUnlock()
{
base.CheckUnlock();
UnlockBlackHole();
}
protected override void Update()
{
base.Update();
}
public bool SkillCompleted()
{
if (!currentBlackhole)
return false;
if (currentBlackhole.playerCanExitState)
{
currentBlackhole = null;
return true;
}
return false;
}
public float GetBlackholeRadius()
{
return maxSize / 2;
}
}
PlayerGroundState.cs
修复黑洞技能无CD释放bug
if (Input.GetKeyDown(KeyCode.R) && player.skill.blackhole.blackHoleUnlocked)
{
//CD
if (player.skill.blackhole.cooldownTimer > 0)
return;
stateMachine.ChangeState(player.blackholeState);
}
完整代码
using UnityEngine;
public class PlayerGroundState : PlayerState
{
public PlayerGroundState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
{
}
public override void Enter()
{
base.Enter();
}
public override void Exit()
{
base.Exit();
}
public override void Update()
{
base.Update();
if (Input.GetKeyDown(KeyCode.R) && player.skill.blackhole.blackHoleUnlocked)
{
//CD
if (player.skill.blackhole.cooldownTimer > 0)
return;
stateMachine.ChangeState(player.blackholeState);
}
if (Input.GetKeyDown(KeyCode.Mouse1) && HasNoSword() && player.skill.sword.swordUnlocked)
stateMachine.ChangeState(player.aimSwordState);
if (Input.GetKeyDown(KeyCode.Q) && player.skill.parry.parryUnlocked)
stateMachine.ChangeState(player.counterAttack);
if (Input.GetKeyDown(KeyCode.Mouse0))
stateMachine.ChangeState(player.primaryAttack);
if (!player.IsGroundDetected())
stateMachine.ChangeState(player.airState);
if (Input.GetKeyDown(KeyCode.Space) && player.IsGroundDetected())
stateMachine.ChangeState(player.jumpState);
}
private bool HasNoSword()
{
if (!player.sword)
return true;
player.sword.GetComponent<Sword_Skill_Controller>().ReturnSword();
return false;
}
}