unityでライフHPとダメージ処理を実装してみたメモ。敵コライダーに当たったらライフを減らす

unity ライフゲージ 攻撃 減らす 3Dゲームの作り方
※記事内に広告が含まれています。

バーチャル3Dクリエイター神部まゆみです(*^-^*)

この記事はunityでライフ(HP)とダメージ処理を実装してみたメモです。

前回の記事はこちら。

動かしてみたバージョンはunity2022.3.22です。

アーカイブをダウンロード
アーカイブをダウンロード

まぁ特に新しい処理を使ったりはしていないはずだから、最近のunityバージョンなら大抵は動くと思います。

●PRスペース●
■PR■

現在人気商品が最大90%以上オフで買えるAmazonプライム感謝祭先行セールをやってるみたいです(2025/10/10 23:59まで )。

Amazonプライム感謝祭 先行セール開催中 最大90%以上オフ

燃えにくく安全性の高いエレコム ナトリウムイオンモバイルバッテリーがかなり安くなっているので私も買いました。

エレコム ナトリウムイオン モバイルバッテリー

品薄だからか配送まで一ヶ月くらいかかるみたいですが、そろそろモバイルバッテリーが消耗している人におススメです。

エレコム モバイルバッテリー 9000mAh 45W 【世界初】ナトリウムイオン電池 USB PD対応

〇まゆみマート|BOOTH

BOOTHでVRoidテクスチャやVRChat向けオブジェクトなどを販売しています。いいねしてくれると励みになります(*^-^*)

やりたいこと 敵のコライダーに当たったらライフを減らす

リアルにしたければ敵の腕とか銃の弾にコライダーを設定して、攻撃中のコライダーに当たったらライフを減らす…みたいにしたほうが良いんだろうけど。

とりあえず簡単なスフィアみたいなヤツを敵に見立ててゴールまでの道に配置し、当たったら食らうようにします。

とりあえず悲鳴っぽい効果音も鳴らすようにするw

ChatGPT先輩に聞いてみる

とりあえず彼に聞いておけば間違いないだろう…。

unity ライフゲージ 攻撃 減らす
神部まゆみ
神部まゆみ

unityでTPSゲーム製作をしています。プレイヤーにHPを設定して(初期値100)、敵のコライダーに当たったら効果音を流してライフを減らすスクリプトが欲しいです。
HPの他にも後々攻撃力や防御力などのパラメーターを付与することになると思うので、プレイヤーのパラメーターを設定するスクリプトと、ライフを減らすスクリプトは分けてください。どちらのスクリプトもプレイヤーにアタッチする予定です。

ChatGPT
ChatGPT

それでは、プレイヤーのパラメーターを管理するスクリプトと、ライフを減らすスクリプトのサンプルコードを提供します。

コード

プレイヤーのパラメーターを管理するスクリプト PlayerStats.cs

using UnityEngine;

public class PlayerStats : MonoBehaviour
{
    public int maxHP = 100;
    public int currentHP;
    public int attackPower = 10;
    public int defensePower = 5;

    void Start()
    {
        currentHP = maxHP;
    }

    public void TakeDamage(int damage)
    {
        int damageToTake = Mathf.Max(0, damage - defensePower);
        currentHP -= damageToTake;
        if (currentHP <= 0)
        {
            currentHP = 0;
            Die();
        }
    }

    void Die()
    {
        Debug.Log("Player is Dead");
        // 死亡時の処理をここに記述
    }
}

ライフを減らすスクリプト PlayerCollision.cs

using UnityEngine;

public class PlayerCollision : MonoBehaviour
{
    public AudioClip damageSound;
    private AudioSource audioSource;
    private PlayerStats playerStats;

    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        playerStats = GetComponent<PlayerStats>();
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Enemy"))
        {
            playerStats.TakeDamage(10); // ここでダメージ量を調整
            if (damageSound != null)
            {
                audioSource.PlayOneShot(damageSound);
            }
        }
    }
}
ChatGPT
ChatGPT

以下はスクリプトの説明です。

スクリプトの説明

PlayerStats.cs:
プレイヤーのHP、攻撃力、防御力などのパラメーターを管理します。
TakeDamage メソッドでダメージを計算し、HPを減らします。
HPが0以下になると Die メソッドが呼び出されます。

PlayerCollision.cs:
OnTriggerEnter メソッドで敵のコライダーに当たったことを検出します。
敵に当たった際に TakeDamage メソッドを呼び出してダメージを与えます。
ダメージ音を再生します。

注意点
プレイヤーオブジェクトには、PlayerStats と PlayerCollision の両方のスクリプトをアタッチします。
プレイヤーオブジェクトには AudioSource コンポーネントもアタッチしておいてください。
敵オブジェクトには “Enemy” というタグを設定しておきます。
このセットアップにより、プレイヤーが敵に衝突した際にHPが減少し、効果音が再生されます。攻撃力や防御力などの他のパラメーターも後から追加して管理できます。

おお…ChatGPTパイセン有能すぎる…。

でもこれだとライフが表示されなそうなので、ライフの表示も別スクリプトでお願いしてみます。

ライフゲージを表示させるようにしてみる

更に聞いてみます。

unity ライフゲージ 攻撃 減らす

神部まゆみ
神部まゆみ

ライフを表示するようにもしたいのですが、こちらはUI関連の動作として別のスクリプトで管理したほうが良いでしょうか?

生成AI
生成AI

はい、ライフの表示はUI関連の動作として別のスクリプトで管理するのが良いでしょう。この方法で、UIの管理とゲームロジックを分離することができます。以下に、ライフを表示するためのスクリプトを示します。

ライフゲージを表示するコードや説明など

まず、UIを設定します。

Unityエディターでの設定:

①Canvasを作成します。

Canvasの子としてTextオブジェクトを作成し、プレイヤーのライフを表示するために配置します。Textオブジェクトには適切なフォントやサイズを設定します。

次に、ライフを表示するスクリプトを作成します。

PlayerUI.cs

using UnityEngine;
using UnityEngine.UI;

public class PlayerUI : MonoBehaviour
{
    public Text hpText;
    private PlayerStats playerStats;

    void Start()
    {
        playerStats = GetComponent<PlayerStats>();
    }

    void Update()
    {
        hpText.text = "HP: " + playerStats.currentHP;
    }
}

スクリプトの説明

PlayerUI.cs:
hpText 変数には、ライフを表示する Text オブジェクトを設定します。
Start メソッドで PlayerStats コンポーネントを取得します。
Update メソッドでプレイヤーの現在のHPを表示します。

スクリプトのセットアップ
プレイヤーオブジェクトに PlayerUI スクリプトをアタッチします。
Unityエディターでプレイヤーオブジェクトを選択し、PlayerUI スクリプトの HpText フィールドに Text オブジェクトをドラッグ&ドロップします。

このセットアップにより、プレイヤーの現在のライフがリアルタイムでUIに表示されます。これで、プレイヤーのパラメーター管理、ダメージ処理、UI表示のそれぞれが分離され、管理しやすくなります。

さっそく実装してみる

とりあえず言われたとおりにやってみます。

しかしChatGPTパイセンを妄信しているとシレッとウソをつかれて落胆することも結構あるので、ダメなら軌道修正しつつやりますw

とりあえずスクリプトをコピペして作っておく

とりあえずスクリプトをコピペしておく。

スクリプトは向かって右上のボタンを押すとコピーできます!

unity ライフゲージ 減らす

スクリプトをプレイヤーにアタッチする

作ったスクリプト三つをプレイヤーにアタッチして、オーディオソースも追加しておく。

↓プレイヤーのインスペクターはこんな感じです。

unity ライフゲージ 減らす

Player Collisionにオーディオクリップを読み込むところがあるからオーディオソースは必要ないのかと思ったけど、後でやったらオーディオソースないとダメだった。

効果音を探して設定する

検索したら効果音ラボさんのやつがあったからこれにしよう。

”悲鳴”で検索した結果[1]|効果音ラボ
品質を追求した、2000種類以上の無料効果音をダウンロードできます。

↓ダメージを受けたらこの「キャー!」って感じの音声を流そうw

声優さんは音枝優日さんという方らしいです。

それで死んだらこっちの「ギャアアアアア」っていう音声を流そうw

ああ、でも死んだ場合の処理はまだ作っていないから、とりあえずダメージを受けた場合の「キャー!」だけ設定しておきます。

unity ライフゲージ 減らす

キャンバスを作って設定する

キャンバスは前回作ったのでこれを使えばいいかな…。

↓前回キャンバスとテキストを追加した時のやつ。

既にあるテキストは「ゴール!」と表示するのに使うので、コピペして使おうかな。

位置はこのあたりかな。スクリプトで表示するので、Lifeっていうテキストは消しておきます。

unity ライフゲージ 減らす

これでPlayer UIに設定すればOK。

敵を配置する

とりあえずカプセルでいいか…。

彼のコライダーに当たったらダメージを受けるようにしたいので、「トリガーにする(IsTrigger)」にチェックをいれておきます。

unity ライフゲージ 減らす

敵にEnemyタグをつけておく

これタグを分けておくと、特定のタグが付いたオブジェクトだけ動作させたりできる。

Enemyはなかったので追加した。

unity ライフゲージ 減らす

プラスボタンを押して名前を入力してsaveすれば追加できます。

unity ライフゲージ 減らす

これで動いた!

我ながらうるさw ※音が出ます

HPが0になった場合の処理はまだ作ってないです。

ちょっと気になる部分を直す

だいたいこれでも良いのだけど、ちょっと気になる部分があるので直します。

ここまででも良いならこれ以降は読む必要はありません。

敵をすり抜けてしまうのを直す

これはコライダーをトリガーにするとすり抜けてしまうようなので、もう一つコライダーを設置したら解決しました。

トリガーにするコライダーにちゃんと当たるよう、追加するコライダーは半径をちょっと小さめにしました。

unityライフゲージ減少

敵に張り付いたままだと一度しかダメージ受けないのを直す

なんかずっと無敵時間みたいになっているので、敵に張り付いたままでも2~3秒程度の無敵時間経過後にまたダメージを受けるようにします。

ChatGPTパイセンに聞いたらすぐやってくれましたΣ(゚Д゚)有能すぎる…。

unityライフゲージ減少
神部まゆみ
神部まゆみ

敵に接触したままの状態だと、最初にダメージを受けるだけで以降ダメージを受けることがありません。ダメージを受けてから2秒程度の無敵時間があるのは良いと思いますが、敵にずっと張り付いていても一度しかダメージを受けないのはちょっと不自然です。

生成AI
生成AI

敵に接触したままの状態で一定の間隔でダメージを受けるようにするには、無敵時間の設定とダメージを受けるタイミングを管理する機能を追加する必要があります。これを実現するために、ダメージを受けた後に一定時間ダメージを受けないようにするクールダウンタイムを実装します。

以下は、無敵時間の設定を含む修正された PlayerCollision スクリプトの例です。

無敵時間を考慮して修正した PlayerCollision.cs のコード

PlayerCollision.csのスクリプトを↓に書き換えればOK。

using UnityEngine;

public class PlayerCollision : MonoBehaviour
{
    public AudioClip damageSound;
    public float invincibilityDuration = 2.0f; // 無敵時間
    public int damageAmount = 10; // ダメージ量

    private AudioSource audioSource;
    private PlayerStats playerStats;
    private bool isInvincible = false;
    private float invincibilityTimer = 0.0f;

    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        playerStats = GetComponent<PlayerStats>();
    }

    void Update()
    {
        if (isInvincible)
        {
            invincibilityTimer -= Time.deltaTime;
            if (invincibilityTimer <= 0)
            {
                isInvincible = false;
            }
        }
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Enemy"))
        {
            ApplyDamage();
        }
    }

    void OnTriggerStay(Collider other)
    {
        if (other.gameObject.CompareTag("Enemy"))
        {
            ApplyDamage();
        }
    }

    private void ApplyDamage()
    {
        if (!isInvincible)
        {
            playerStats.TakeDamage(damageAmount);
            if (damageSound != null)
            {
                audioSource.PlayOneShot(damageSound);
            }
            isInvincible = true;
            invincibilityTimer = invincibilityDuration;
        }
    }
}

スクリプトの説明

・新しい変数:

invincibilityDuration は無敵時間の長さ(秒)です。
damageAmount は受けるダメージの量です。
isInvincible は現在無敵状態かどうかを示します。
invincibilityTimer は無敵状態の残り時間を管理します。

・Updateメソッド:

isInvincible が true のときに invincibilityTimer を減らします。タイマーが0以下になると、無敵状態が解除されます。

・OnTriggerEnterおよびOnTriggerStayメソッド:

敵のコライダーに当たったとき、または当たっている間に ApplyDamage メソッドを呼び出します。

・ApplyDamageメソッド:

無敵状態でないときにダメージを適用し、無敵状態に移行します。

このスクリプトにより、プレイヤーが敵に接触し続けている間、一定の間隔でダメージを受けるようになります。また、ダメージを受けた直後に短い無敵時間が設定されるので、過度なダメージを防ぐことができます。

これで無敵時間を指定するパラメーター(Invincibility Duration)が追加されていました。

unityライフゲージ減少

これで敵に張り付いたままでも、無敵時間経過後にまたダメージ判定がされるようになりました。

おわりに

案外簡単に実装出来て良かった。

まぁ優秀なChatGPT氏のおかげだけど(;^_^A

あとはライフゲージをハートにしてUIを凝ったり、敵を動かしたりすればゲームっぽくなるかな…。

まぁもう少しいじってみます(*^-^*)

タイトルとURLをコピーしました