【バイオハザード風のゲームを作ってみよう。その14】

今回も下記動画をやっていきます。
youtu.be


今回は弾数の表示/計算とリロードアニメーションを実装していきます。

・弾数を表示させるUIを作ります。

・弾数を設定する変数を定義します。

public class WeaponItem : Item //EP4追加 M1911にアタッチ.
{
    (省略)
    [Header("Ammo")]
    public int remainingAmmo = 0; //EP14追加
}

・弾数表示に使用するText変数を定義します。

public class PlayerUIManager : MonoBehaviour //EP6追加 Canvasにアタッチ
{
    [Header("Crosshair")]
    public GameObject crosshair;

    [Header("Ammo")]
    public Text currentAmmoCountText;   //EP14追加 //現在装備している銃の残弾数を表示
    public Text reservedAmmoCountText;  //EP14追加 //現在装備している銃の残弾数の総数表示
}

・画面上にスタート時の弾数を表示させます。

public class PlayerEquipmentManager : MonoBehaviour //EP4追加.playerにアタッチ
{
    PlayerManager playerManager;        //EP14追加
  (省略)
    private void Awake()
    {
        playerManager = GetComponent<PlayerManager>(); //EP14追加
        LoadWeaponLoaderSlots();
    }

 void LoadCurrentWepon()
    {
        //LOAD THE WEPON ONTO PLAYERS HANDS
        weaponLoaderSlot.LoadWeaponModel(weapon);

        //CHANGE OUR PLAYERS MOVEMENT/IDLE ANIMSTIONS TO THE WEPONS MOVEMENT/IDLE ANIMATIONS
        playerManager.animatorManager.animator.runtimeAnimatorController = weapon.weponAnimatior;

        weaponAnimator = weaponLoaderSlot.currentWeaponModel.GetComponentInChildren<WeaponAnimatorManager>(); //EP7追加

        //EP5追加
        //右手/左手の武器の子オブジェクトRightHandIk/LeftHandIkを取得。
        rightHandIk = weaponLoaderSlot.currentWeaponModel.GetComponentInChildren<RightHandIkTarget>();
        leftHandIk = weaponLoaderSlot.currentWeaponModel.GetComponentInChildren<LeftHandIkTarget>();
        playerManager.animatorManager.AssignHandIK(rightHandIk ,leftHandIk); //EP14変更
        playerManager.playerUIManager.currentAmmoCountText.text = weapon.remainingAmmo.ToString(); //EP14追加
    }

}

・発砲時の弾数の計算と表示を行います。

public class PlayerManager : MonoBehaviour
{
(省略)
 public void UseCurrentWeapon() 
    {
        if (isPreformingAction)
            return;

        if (playerEquipmentManager.weapon.remainingAmmo > 0) //EP14追加
        {
            //残弾数の計算と表示
            playerEquipmentManager.weapon.remainingAmmo = playerEquipmentManager.weapon.remainingAmmo - 1;      //EP14追加
            playerUIManager.currentAmmoCountText.text = playerEquipmentManager.weapon.remainingAmmo.ToString(); //EP14追加

            //In the future wil and the option to use knives also
            playerEquipmentManager.weaponAnimator.ShootWeapon(playerCamera);
        }
        else
        {
            Debug.Log("CLICK(you are out of Ammo,RELOAD)");
        }   
    }
}

・リロードアニメーションがmixamoに無かったので、Very Animationアセットで自作します。
(はじめてVery Animationを使うので、とりあえず仮で作りました。)

Very Animation公式のクイックスタート動画
youtu.be

また、こちらも参考になります。
youtu.be

mixamoのpistol Idleアニメーションを元に作ることにします。

外部アニメーション編集方法
youtu.be

・作成したアニメーション(Pistol Reload)をPlayer ControlsアニメーターコントローラーのOverrideLayerに設定します。

・InPut ActionでキーボードRをリロードに設定します。

・リロードアニメーションの実装します。

public class AnimatorManager : MonoBehaviour
{
 (省略)
 //EP14追加 //指定したアニメーションを実行
    public void PlayAnimation(string targetAnimation, bool isPreformingAction)
    {
        animator.SetBool("isPreformingAction", isPreformingAction);
        //animator.SetBool("disableRootMotion", true);
        animator.CrossFade(targetAnimation, 0.2f);
    }

    //EP14追加 Called upon during action, allowa the HAND IK to release so the animation can take over
    public void ClearHandIKWeights()
    {
        rightHandIK.data.targetPositionWeight = 0;
        rightHandIK.data.targetRotationWeight = 0;

        leftHandIK.data.targetPositionWeight = 0;
        leftHandIK.data.targetRotationWeight = 0;
    }


    //EP14追加 Called when action are complete, allows hand IK to take ahold again
    public void RefreshHandIKWeights()
    {
        rightHandIK.data.targetPositionWeight = 1;
        rightHandIK.data.targetRotationWeight = 1;

        leftHandIK.data.targetPositionWeight = 1;
        leftHandIK.data.targetRotationWeight = 1;
    }
}
public class InputManager : MonoBehaviour
{
 (省略)
private void OnEnable() //OnEnableはオブジェクトが有効になったときに呼び出されます.
    {
        if(playerControls == null)
        {
            playerControls = new PlayerControls();

            //アクション実行中コールバック
            //~.performedにiを登録.
          (省略)
            playerControls.PlayerActions.Reload.performed += i => reloadInput = true; //EP14追加

        }

        playerControls.Enable();
    }

 public void HandleAllInputs()
    {
       (省略)
        HandReloadInput();      //EP14追加
    }

 //EP14追加 リロードアニメーションを再生
    private void HandReloadInput()
    {
        //We do not want to be able to reload while being damaged, shooting, quick turning etc
        if (playerManager.isPreformingAction)
            return;

        if (reloadInput)
        {
            reloadInput = false;
            playerManager.animatorManager.ClearHandIKWeights();
            playerManager.animatorManager.PlayAnimation("Pistol Reload", true); 
            //PLACE MORE AMMO IN THE WEAPON
            playerManager.playerEquipmentManager.weapon.remainingAmmo = 12;
            playerManager.playerUIManager.currentAmmoCountText.text = playerManager.playerEquipmentManager.weapon.remainingAmmo.ToString();
            //UPDATE RESERVED AMMO COUNT
            //SUBTRACT THE PLACED AMMO OUR INVENTORY

        }
    }
}

プレイ動画です。
youtu.be


今回は以上です。