【Unity】無敵の実装【マリオ風】

クリエイティブ
記事内に広告が含まれています。

アクションゲームには無敵アイテムを獲得したとき、ダメージを受けた直後など無敵時間が必要な場面が多いですよね。

初心者の場合だとこのような時間と状態の管理のところでつまづきやすいと思うので簡単な無敵状態の実装方法と考え方を説明します。

無敵時間を実装してみる

Unityで無敵時間を実装するには無敵状態のフラグタイマーが必要です。

public float invincibilityDuration = 10.0f; // 無敵時間(秒)
private float invincibilityTimer = 0.0f;   // 経過時間を格納するタイマー変数(初期値0秒)
private bool isInvincible = false;         // 無敵状態かどうかのフラグ

今回は無敵時間を10.0秒としました。

例えば、マリオのようにスターを取ったときに10秒間無敵状態になるようにしたい場合は以下のようになります。

public void GetStar()
{
    //スターを取ったときに無敵状態フラグをTrueにする
    isInvincible = true;
}

private void Update()
{
    //無敵状態フラグがTrueのときに毎フレーム実行
    if(isInvincible)
    {
     //ここに無敵状態のときの処理を書く
     Debug.Log("無敵状態");

         //毎フレームタイマー変数にTime.deltaTimeを足す
         invincibilityTimer += Time.deltaTime;

         //タイマーが無敵時間(10秒)を超えたとき
         if(invincibilityTimer >= invincibilityDuration)
         {
              Debug.Log("無敵状態終わり");

              //無敵状態フラグをFalseにする
              isInvincible = false;
              //タイマーを0.0秒にリセットする
              invincibilityTimer = 0.0f
         }
    }
}

コードの説明

今回のように特定の状態のときに処理を実行し続けたい(例えば無敵状態のときにダメージを受けないようにしたい)場合はフラグとUpdate関数の使い方が肝になりますね。

まず、前提知識として覚えていただきたいことですが、Update関数の中にタイマー変数にTime.deltaTimeを加算する処理を記述すると、時間をカウントアップすることができます

private void Update()
{
    //時間をカウントアップする
    Timer += Time.deltaTime;
    Debug.Log(Timer);
}
たかし
たかし

よく使うので覚えておきましょう

今回は無敵状態の実装なので、無敵状態のときだけタイマーをカウントアップして10秒経ったら無敵状態を解除するようにしたいですね。

無敵状態のときだけタイマーをカウントアップするには無敵状態フラグTrueのときにタイマーを加算するようにif文で制御してあげるといいです
今回はスターをゲットしたときに呼ばれるGetStar関数が実行されたときに無敵状態フラグをTrueにしています。

public void GetStar()
{
    //スターを取ったときに無敵状態フラグをTrueにする
    isInvincible = true;
}

private void Update()
{
    //無敵状態フラグがTrueのときに毎フレーム実行
    if(isInvincible)
    {
     //ここに無敵状態のときの処理を書く
     Debug.Log("無敵状態");

         //毎フレームタイマー変数にTime.deltaTimeを足す
         invincibilityTimer += Time.deltaTime;
    }
}

次に無敵時間10秒を超えたときに無敵状態を解除するようにしたいです。
そういう場合はカウントアップ中のタイマー変数が無敵時間(10秒)を超えたときに、無敵状態フラグFalseにします

private void Update()
{
    //無敵状態フラグがTrueのときに毎フレーム実行
    if(isInvincible)
    {
     //ここに無敵状態のときの処理を書く
     Debug.Log("無敵状態"); 

         //毎フレームタイマー変数にTime.deltaTimeを足す
         invincibilityTimer += Time.deltaTime;

         //タイマーが無敵時間(10秒)を超えたとき
         if(invincibilityTimer >= invincibilityDuration)
         {
              Debug.Log("無敵状態終わり");

              //無敵状態フラグをFalseにする
              isInvincible = false;
         }
    }
}

これでタイマー変数のカウントアップを止めることはできますが、タイマーが10秒以上の値のままで止まったままなので次にGetStar関数が実行されたときも無敵時間を超えていることになります

よって、次回GetStar関数実行後はすぐに無敵状態フラグがFalseになってしまうので、無敵状態フラグがFalseになったと同時にタイマー変数を0にリセットしましょう

public void GetStar()
{
    //スターを取ったときに無敵状態フラグをTrueにする
    isInvincible = true;
}

private void Update()
{
    //無敵状態フラグがTrueのときに毎フレーム実行
    if(isInvincible)
    {
     //ここに無敵状態のときの処理を書く
     Debug.Log("無敵状態");

         //毎フレームタイマー変数にTime.deltaTimeを足す
         invincibilityTimer += Time.deltaTime;

         //タイマーが無敵時間(10秒)を超えたとき
         if(invincibilityTimer >= invincibilityDuration)
         {
              Debug.Log("無敵状態終わり");

              //無敵状態フラグをFalseにする
              isInvincible = false;
              //タイマーを0.0秒にリセットする
              invincibilityTimer = 0.0f
         }
    }
}

これで無敵時間の実装はOKです。

具体的な使用例

マリオのように無敵になったときに、ぶつかった敵キャラ(Enemyタグを持つ)を倒したい場合は以下のように書けばいいです。

public void GetStar()
{
    //スターを取ったときに無敵状態フラグをTrueにする
    isInvincible = true;
}

private void Update()
{
    //無敵状態フラグがTrueのときに毎フレーム実行
    if(isInvincible)
    {
     Debug.Log("無敵状態");

         //毎フレームタイマー変数にTime.deltaTimeを足す
         invincibilityTimer += Time.deltaTime;

         //タイマーが無敵時間(10秒)を超えたとき
         if(invincibilityTimer >= invincibilityDuration)
         {
              Debug.Log("無敵状態終わり");

              //無敵状態フラグをFalseにする
              isInvincible = false;
              //タイマーを0.0秒にリセットする
              invincibilityTimer = 0.0f
         }
    }

private void OnTriggerEnter2D(Collider2D collider)
{
    //ぶつかった対象がEnemyタグを持っているとき
    if (collider.gameObject.tag == "Enemy")
    {
        //無敵状態のときかどうか
        if(isInvincible)
        {
            //無敵状態のときはぶつかった対象を消す
            Debug.Log("敵を倒した");
            Destroy(collider.gameObject);
        }
        else
        {
            //無敵状態でないときはダメージを受ける
            Debug.Log("ダメージを受けた");
        }
    }
}

まとめ

こんな感じで無敵時間は実装できます。

特定の状態のときになんらかの処理を実行し続けたいという場合は、今回のようなフラグとUpdate関数使い方をすれば大体なんとかなります。

ぜひ使いこなしましょう!

独学に限界を感じているあなたに

ゲーム制作に特化したプログラミングスクール「テックスタジアム」をご紹介します。
テックスタジアムは数あるプログラミングスクールでもゲームに特化しており、「完全オンライン」でUnity、3DCGを学ぶことができます。

また、第一線で活躍する講師に質問し放題。ゲーム業界への無料就職サポートも行っており、就職決定者には、授業料が全額返還される特典も。
オンラインで無料相談が可能なので、独学に限界を感じた場合は検討してみてください。

コメント

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