ゴマちゃんフロンティア

気まぐれと勢いで作るUnityゲーム開発日記です

【開発メモ】敵キャラクターの被ダメージ処理の実装

time 2016/01/29

というわけで、仕事の案件の納期が近づいてきており、なかなか時間がとれないりべるんです。
Symfony2とかDoctrineとか・・・まだまだ分からないことが多く厳しい日々が続きます。

shot2ss20160129211817219

前回まででプレイヤー側のダメージ処理が終わったので、今回は敵キャラクターのダメージ処理を実装していきます!
プレイヤーキャラとは扱いが違うため、ダメージ処理でやるべきことも変わります。
敵キャラクターがダメージ時にどうなるか(ノックバックorスーパーアーマーなど)はゲーム性に直結する重要な要素だと思いますが、難しいことは考えずにやります!

基本的な仕様

「アクションゲームの敵キャラ」ということを踏まえ、実装内容を考えてみます。

・ダメージ発生時にプレイヤーの体力値を減らす
これはプレイヤー側と一緒ですね。
ただしダウン中など「特定の条件の時にダメージを減衰させる」といった要素は入れるかも。

・ダメージ後の無敵時間はなし
プレイヤー側と最も異なる部分でしょうか。
連続攻撃や多段ヒット攻撃がある関係上、敵キャラクターにはダメージ後の無敵時間を入れない予定です。

・ダメージ発生時にダメージモーションを行う
これもプレイヤーと同じですが、ダメージモーション中に再度ダメージを受けた場合、再度ダメージモーションを行います。
つまり連続でダメージを受けている場合、ダメージモーションを取り続けて行動できなくなります。
また、ダメージ時のノックバックもありません。

・吹き飛ばし攻撃を受けるとダウンする
これまたプレイヤーと同じく、吹き飛ばし攻撃を受けたら「ダウン→着地→起き上がり」と遷移します。
ただ、所謂ボスや中ボスに相応する敵が吹き飛びまくるのも問題なので、キャラクターによっては条件を付けると思います。

・ダメージエフェクトで体色を赤くする
現状ではダメージを与えているか分かりにくいので、ダメージ時に一瞬だけ体を赤くします。
自分の知っているゲームでは「メトロイドプライム」シリーズのエフェクトに近いです。

・体力が0になったら大きく吹き飛ぶ
体力が0になった後に攻撃を受けた場合、その敵キャラは大きく吹き飛びます。
所謂「敵を倒す快感」が欲しかったので、派手に吹っ飛んでもらいます。
合わせて大き目のエフェクトを付けるとよさそうですね。

・・・ということを考慮しつつ、実際に作っていきます!
ボスキャラなどの特殊なケースは後回しとして、一般的な雑魚敵の場合を想定して実装してみます。

ダメージ処理

攻撃判定などの「ダメージを与えるもの」に関しては前回の記事で紹介しているため割愛させて頂きます。
詳しくは↓の記事をご参照下さい。

【開発メモ】被ダメージ処理とダウン状態の実装

敵キャラクターは全てEnemyクラスをスーパークラスとして持ちます。
その中にdamage()を実装します。
今はあまり関係ありませんが、インターフェース「ICharacter」でdamageの実装を強制させています。

public virtual void damage(IDamageGenerator damageGenerator){
    life -= damageGenerator.getPower();
    Vector3 force = damageGenerator.getForce();

    if(life <= 0){
        life = 0;

        // フェードアウト
        iTween.FadeTo(gameObject, iTween.Hash(
            "alpha", 0,
            "time", 0.5f,
            "oncomplete", "EnemyDestroy",
            "oncompletetarget", gameObject
        ));

        // 吹き飛ばし処理
        if (force != Vector3.zero) {
            rb.AddForce(force * 100, ForceMode.Impulse);
        } else {
            rb.AddForce(-transform.forward * 100, ForceMode.Impulse);
        }
    }

    // ダメージエフェクト
    if (!gameObject.GetComponent<iTween>()) {
        iTween.ColorFrom(gameObject, iTween.Hash(
            "color", new Color(255, 0, 0),
            "time", 0.5f,
            "delay", 0.01f
        ));
    }

    // forceが指定されている場合はダウン処理
    if (force != Vector3.zero) {
        // ダウンモーション
        motionChange("Down", true, true);

        // 吹き飛ばし処理
        iTween.MoveTo(gameObject, iTween.Hash(
            "position", transform.position + force,
            "speed", damageGenerator.getForceSpeed(),
            "easetype", iTween.EaseType.easeOutCubic
        ));
    } else {
        // ダメージモーション
        animator.SetTrigger("Damage");
    }
}

IDamageGeneratorインターフェースから攻撃判定の攻撃力や吹き飛ばすベクトルを取得します。
基本的な部分は前回と変わらないので、敵固有の処理だけをまとめていきます!
ノックバックや無敵時間などプレイヤーキャラにあるデリケートな仕様がないので、処理だけならあちらより単純だったりします。

ダメージモーションの上書き

敵キャラの場合、ダメージモーション中でも連続してダメージモーションを再生します。
他のステートからダメージへの遷移はAnimator.Play()でOKです。
(またはAnyStateからDamageステートへの条件を設定して遷移させる方法もあります)
が、既に再生中のダメージモーションを中断して再実行するにはAnimatorController側から設定が必要です。
具体的には「Damageステートの遷移先として自身を設定」します。

shot2ss20160129212624334

同ステートへの再遷移条件用にDamageというTriggerパラメータを作成し、Conditionに設定します。
また、hasExitTimeのチェックは外しておきます。
あとはdamage()内のSetTrigger()でパラメータをONにすれば、モーションを割り込んでDamageステートの最初から再生されます。

ダメージエフェクトの実装

UnityでエフェクトといえばiTweenですね!
最早何度もお世話になっている神ライブラリです。
JavaScriptでいうjQuery的な、画期的なアセットだと思います!

ということで、iTween.ColorFrom()でオブジェクトの色を変化させます。
ColorTo()では変化させた後戻せなくなるのでNG
てっきりiTween側にreset的なものがあると思っていましたが、どうやらそれっぽいパラメータは存在しないようです。
Fromなら変化した後に元の色に戻ります。

shot2ss20160129211901283

ここで問題発生orz
画像を見ての通り、Colorが赤くなっていない部分があります。
iTweenのソースをみた感じでは、1オブジェクトに複数のマテリアルが設定されている場合になる気がします。

モデリング時に複数マテリアルを持たないように工夫すれば回避できそうですが、オブジェクトを結合したりテクスチャを貼っているとかなり厳しいです。
現状ではどうしようもないので、とりあえず保留ということで・・・。

体力0時に大きく吹き飛ばす処理の実装

Enemyクラスのフィールド「life」の値が0以下の時にダメージを受けた場合、敵をRigidbody.AddForce()で吹き飛ばします。
攻撃判定のforceが定義されている場合はその方向に、なければ敵キャラの後ろ方向へ力を掛けます。

if (force != Vector3.zero)
    rb.AddForce(force * 100, ForceMode.Impulse);
} else {
    rb.AddForce(-transform.forward * 100, ForceMode.Impulse);
}

「瞬間的な力」を加えるので、AddForceのForceModeには「Impulse」を指定します。
吹き飛ばすと同時にiTween.FateTo()でフェードアウトさせ、oncompleteで指定した関数内でオブジェクトの削除を行っています。

まとめ

・敵キャラクターにはダメージ後の無敵時間はなし
・ダメージモーション中に再度ダメージを受けた場合、モーションを上書きする
・ダメージ発生時にキャラクターの色を一時的に赤くする
・体力がなくなったときに大きく吹き飛ばす

まだ煮詰め切れて部分も多い感じですが、ひとまず形にはなりました!
そのうち「敵キャラのHP表示」「吹き飛ばし時に派手なエフェクト」などもやってみたいです。

次回は敵キャラのロジックを修正しようかと考えています。
が、結構な改修が必要になりそうなので別の話題になるかもしれません。
その場合は今回やり残した部分の実装か、ステージ関連のお話になりそうです。

今日のイラスト

先日描いたランパをちょっと修正してみました!
ランパ自体が水色なので、背景色を濃い青に変更。
スタフィーシリーズと言えば水中ということで、それっぽく泡を付けています。

数年前の描き始めた頃よりかは上達していると思われます!
時間があればブログ上部のメインキャラ3匹も描き直そうかと思います。

ranpa29

スポンサーリンク

down

コメントする



ツイッター