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

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

今回はゾンビのダメージシステムとライフ0の際の動作を実装していきます。

・ハンドガンが与えるダメージ量を設定します。

public class WeaponItem : Item //EP4追加.Pistolアセットにアタッチ.
{
    [Header("Weapon Animation")]
    public  AnimatorOverrideController weponAnimatior; //今ある Animator Controllerの拡張を可能にするアセット

    [Header("Weapon Damage")]
    public int damage = 20; //EP13追加
}

・ゾンビのアニメーションを変更するメソッドを作ります。

public class ZombieAnimationManager : MonoBehaviour //EP12追加 ゾンビにアタッチ
{
   (省略)
    //EP13追加
    public void PlayTargetActionAnimation(string actionAnimation)
    {
        zombieManager.animator.applyRootMotion = true;
        zombieManager.isPerformingAction = true;
        zombieManager.animator.CrossFade(actionAnimation, 0.2f);
    }
}

・ゾンビ各部位のダメージ計算をするクラスを作ります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ZombieStatManager : MonoBehaviour //EP13追加
{
    ZombieManager zombie;

    [Header("Damage Modidiers")]
    public float headShotDamageMultiplier = 1.5f;
    //TORSO MODIFIER(Maybe is multiplies damage so it does a little less overall?)
    //ARM DAMAGE MODIFIER
    //LEG DAMAGE MODIFIER

    [Header("Overall Health")]
    public int overallHealth=100;       //If this health reaches 0, the zzombie dies

    [Header("Head Health")]
    public int headHealth=100;          //If this health reaches below a certain %, the head will have a chance to explode, causing instant death 

    [Header("Upperbody Health")]
    public int torsoHealth=100;         //Aside from the head, this is the best place to hit to lower overall heath
    public int leftArmHealth=100;       //does not detract from overall health, however has a chance to destroy the limb after reaching a certain %
    public int rightArmHealth=100;      //does not detract from overall health, however has a chance to destroy the limb after reaching a certain %

    [Header("Lower Body Health")]
    public int leftLegHealth=100;       //does not detract from overall health, however has a chance to destroy the limb after reaching a certain %
    public int rightLegHealth=100;      //does not detract from overall health, however has a chance to destroy the limb after reaching a certain %

    private void Awake()
    {
        zombie = GetComponent<ZombieManager>();
    }

    public void DealHeadShotDamage(int damage)
    {
        headHealth = headHealth - Mathf.RoundToInt(damage * headShotDamageMultiplier);
        overallHealth=overallHealth- Mathf.RoundToInt(damage * headShotDamageMultiplier);
        CheckForDeath();
    }

    public void DealTorsoDamage(int damage)
    {
        torsoHealth = torsoHealth - damage;
        overallHealth = overallHealth - damage;
        CheckForDeath();
    }

    public void DealArmDamage(bool leftArmDamage, int damage)
    {
        //Arm damage does not substract from actuak zombie health
        if (leftArmDamage)
        {
            leftArmHealth = leftArmHealth - damage;
        }
        else
        {
            rightArmHealth = rightArmHealth - damage;
        }
        CheckForDeath();
    }

    public void DealLegDamage(bool leftLegDamage, int damage)
    {
        //Arm damage does not substract from actuak zombie health
        if (leftLegDamage)
        {
            leftLegHealth = leftLegHealth - damage;
        }
        else
        {
            rightLegHealth = rightLegHealth - damage;
        }
        CheckForDeath();
    }

    public void CheckForDeath()
    {
        if (overallHealth <= 0)
        {
            overallHealth = 0;
            zombie.isDead = true;
            zombie.ZombieAnimationManager.PlayTargetActionAnimation("Zombie Dying");
        }
    }
}

・ゾンビが被弾した時のダメージ計算メソッドを呼び出します。

public class WeaponAnimatorManager : MonoBehaviour //EP7追加 武器にアタッチ
{
    PlayerManager player; //EP13追加
    
    Animator weaponAnimator;

    [Header("weapon FX")]
    public GameObject weaponMuzzleFlashFX; //The muzzle flash FX that is instantiated when the weapon is fired.
    public GameObject weaponBulletCaseFX; //The bullet case FX that is ejected from the weapon, when the weapon is fired.

    [Header("weapon FX Transform")]
    public Transform weaponMuzzleFlashTransform; //The location the muzzle flash FX will instantiate
    public Transform weaponBulletCaseTransform; //The location the bullet case will instantiate

    [Header("Weapon Bullet Range")]
    public float bulletRange = 100f; //EP11追加

    [Header("Shootable Layers")]
    public LayerMask shootableLayers; //EP11追加

    private void Awake()
    {
        weaponAnimator = GetComponentInChildren<Animator>();
        player = GetComponentInParent<PlayerManager>(); //EP13追加
    }

    public void ShootWeapon(PlayerCamera playerCamera)
    {
        //ANIMATE THE WEAPON
        weaponAnimator.Play("Shoot");

        //INSTANTIATE MUZZLE FLASH FX
        GameObject muzzleFlash = Instantiate(weaponMuzzleFlashFX.gameObject, weaponMuzzleFlashTransform);
        muzzleFlash.transform.parent = null;


        //INSTANTIATE EMPTY BULLET CASE
        //  GameObject bulletCase = Instantiate(weaponBulletCaseFX, weaponBulletCaseTransform);
        //  bulletCase.transform.parent = null;

        //SHOOT SOMETHING
        // public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo)
        // origin:ワールド座標でのレイの開始地点, direction:レイの方向, hitInfo:衝突した相手オブジェクトの情報
        RaycastHit hit;
        if(Physics.Raycast(playerCamera.cameraObject.transform.position, playerCamera.cameraObject.transform.forward,out hit,
            bulletRange,shootableLayers)) //EP11追加
        {
            Debug.Log(hit.collider.gameObject.layer); //EP11変更

            ZombieEffectManager zombie = hit.collider.gameObject.GetComponentInParent<ZombieEffectManager>(); //EP11追加

            //EP11追加
            if (zombie != null)
            {
                if (hit.collider.gameObject.layer == 8)
                {
                    zombie.DamageZombieHead(player.playerEquipmentManager.weapon.damage);       //EP13追加
                }
                else if (hit.collider.gameObject.layer == 9)
                {
                   zombie.DamageZombieTorso(player.playerEquipmentManager.weapon.damage);        //EP13追加
                }
                else if (hit.collider.gameObject.layer == 10)
                {
                    zombie.DamageZombieRightArm(player.playerEquipmentManager.weapon.damage);   //EP13追加
                }
                else if (hit.collider.gameObject.layer == 11)
                {
                    zombie.DamageZombieLeftArm(player.playerEquipmentManager.weapon.damage);    //EP13追加
                }
                else if (hit.collider.gameObject.layer == 12)
                {
                    zombie.DamageZombieRightLeg(player.playerEquipmentManager.weapon.damage);   //EP13追加
                }
                else if (hit.collider.gameObject.layer == 13)
                {
                    zombie.DamageZombieLeftLeg(player.playerEquipmentManager.weapon.damage);    //EP13追加
                }

            }
        }
    }
}
public class ZombieEffectManager : MonoBehaviour //EP11追加 ゾンビにアタッチ
{
    (省略)
    public void DamageZombieHead(int damage) //EP13変更
    {
       (省略)
    }

    public void DamageZombieTorso(int damage) //EP13変更
    {
        (省略)
    }

    public void DamageZombieRightArm(int damage) //EP13変更
    {
       (省略)
    }

    public void DamageZombieLeftArm(int damage) //EP13変更
    {
        (省略)
    }

    public void DamageZombieRightLeg(int damage) //EP13変更
    {
        (省略)
    }

    public void DamageZombieLeftLeg(int damage) //EP13変更
    {
        (省略)
    }
}

・ゾンビのライフが0でない場合、以前に実装した動作を続けさせる。

public class ZombieManager : MonoBehaviour //EP8追加 ゾンビオブジェクトにアタッチ
{
   (省略)
    public ZombieStatManager zombieStatManager; //EP13追加
    public bool isDead;             //EP13追加
 private void Awake()
    {
        (省略)
        zombieStatManager = GetComponent<ZombieStatManager>(); //EP13追加
    }

    private void FixedUpdate()
    {
        if (!isDead) //EP13追加
        {
            HandleStateMachine();
        }
    }

}

プレイするとこんな感じです
youtu.be

今回は以上です。