今天实现的内容:
枪械功能的继续实现:
在这个项目中弹药装填被设计为当弹仓中还有子弹时换弹会多一发子弹的情况。其实我很想设计成换弹就直接将整个弹匣扔掉,这样显得硬核一点。但是还是设计成大多数竞技射击游戏那样,弹匣少了多少弹药就补充多少弹药的形式。
// 装填
protected override void Reload()
{
// 首先要有子弹可以换
if (currentAmmoCarried > 0)
{
// 其次是确实需要换弹并且没有在换弹
if(currentAmmoInMag <= ammoInMag && !m_isReloading)
{
// 将换弹layer的权重设置为1
gunAnimator.SetLayerWeight(1, 1);
// 判断当前弹仓里是否有子弹
m_isBulletLeft = (currentAmmoInMag > 0);
// 当前需要播放哪个动画?
gunAnimator.SetTrigger(m_isBulletLeft ? "ReloadLeft" : "ReloadOutOfAmmo");
// 设置状态
m_isReloading = true;
// 将所有的子弹放到currentAmmoCarried
currentAmmoCarried += currentAmmoInMag;
// 将currentAmmoInMag设置为0 一是为了方便接下来的计算 二是为了让换弹时无法射击
currentAmmoInMag = 0;
// 开始执行换弹协程 只有动画快要播放完成时才真正换弹
StartCoroutine(CheckReloadAmmoAnimationEnd());
}
else
{
// 不需要换弹
#if UNITY_EDITOR
Debug.Log("Dont need to reload!");
#endif
}
}
else
{
// 备用子弹打光了
#if UNITY_EDITOR
Debug.Log("Out of Ammo!");
#endif
return;
}
}
首先,在没有子弹可以换的时候,在确实需要换弹,也就是子弹没有装满的时候,在正在换弹的时候,我们是不会执行换弹的。Reload函数仅仅是播放动画,设置状态m_isReloading,将所有子弹都放到currentAmmoCarried,将currentAmmoInMag清零,以及开启真正的换弹方法,该方法是一个协程。
// 检查换弹动画是否播放完成
// 如果播放完成了就可以从逻辑上换弹了
private IEnumerator CheckReloadAmmoAnimationEnd()
{
while (true)
{
yield return null;
// 一定要在每帧赋值 才能得到current state
gunStateInfo = gunAnimator.GetCurrentAnimatorStateInfo(1);
if (gunStateInfo.IsTag("ReloadAmmo")) //这个基本上肯定是true 因为我们先设置了播放换弹动画
{
if (gunStateInfo.normalizedTime >= 0.9f) //当换弹动画快要播完时
{
if(m_isBulletLeft) //如果我们装填时弹仓中有子弹
{
// 剩下的子弹能不能填满完整个弹匣?
currentAmmoInMag = (currentAmmoCarried > ammoInMag + 1) ? ammoInMag + 1 : currentAmmoCarried;
// 装了多少就减多少
currentAmmoCarried -= currentAmmoInMag;
}
else //如果我们装填时弹仓中没子弹
{
// 剩下的子弹能不能填满完整个弹匣?
currentAmmoInMag = (currentAmmoCarried > ammoInMag) ? ammoInMag : currentAmmoCarried