ゴマちゃんフロンティア

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

【Unity】体力ゲージを一定時間のみ表示する制御の実装

time 2017/06/25

というわけで、今回はUnity上で「体力ゲージを一定時間のみ表示する」のお話です。

「ダークソウルシリーズの敵キャラクターの体力ゲージ」と言うと、分かる人には分かると思います。普段は体力ゲージを表示せず、被ダメージ時のみ表示され、一定時間後にまた非表示になります。ボスクラスの敵は常に表示されていますが、あれは例外です。
自作ゲームで言えば、敵キャラクターの体力ゲージで必要になりました。敵の数は多めにする予定なので、常に表示していると邪魔でしょうがないです。ここは「ダメージ後の一定時間のみ表示」するようにしてみましょう。

ただし、「ダメージ発生時の処理」まで書くとあれこれ長くなるので、本記事ではインスタンス化されて呼び出された後の、表示・非表示の処理のみ紹介します。あらかじめご了承ください。

体力ゲージのオブジェクト構成

敵キャラクターの体力ゲージの構成はこんな感じです。

「EnemyLifeGage」に今回紹介する関数を実装したクラス、子オブジェクトに「Image」を設定しています。

ダメージ時の表示制御

「表示」をどう捉えるかによりますが、本記事では「透明度によるフェードイン・アウト」で表現してみます。アニメーションにはiTweenを使うのが手っ取り早いですが、UI系コンポーネントなのでFadeTo()を使うことができません。なのでValueTo()で透明度を変えてあげます。
ここで問題になるのが体力ゲージの構成です。マイ体力ゲージは「フレーム」「赤ゲージ」「緑ゲージ」を重ねて表現しているため、その全ての透明度を同時に変化させる必要があります。出来ないことはありませんが、ちょっと面倒ですね。

…と思ったら、「CanvasGroup」なんていいコンポーネントがあるみたいですよ!

「透明にしたい子オブジェクトの親オブジェクト」にこれを追加し、alphaをいじれば一括で変更みたいです。今回の例でいえば「EnemyLifeGage」に設定します。

お次はスクリプトです。ダメージ時の表示制御用としてshowLifeGage()という関数を作っておきます。

 
public void showLifeGage() {
    // フェードアウト
    iTween.ValueTo(gameObject, iTween.Hash(
        "from", canvasGroup.alpha,
        "to", 1.0f,
        "time", feed_speed,
        "easetype", iTween.EaseType.linear,
        "onupdate", "changeAlpha",
        "onupdatetarget", gameObject
    ));
}

同クラス内にonupdateで呼び出す関数も作ります。
(クロージャ使えればよいのですが、iTweenで使うのはちょっと修正がいるみたいです)

private void changeAlpha(float alpha) {
    canvasGroup.alpha = alpha;
}

ValueTo()ChangeAlpha()を呼び出し、CanvasGroup.alphaの値を変えます。あらかじめインスペクター上で0に設定しておき、ダメージ時に0→1になるような設定にしておけばOKです。

「一定時間のみ表示」の制御

これだけだと一度表示されたらされっぱなしになるので、一定時間後に透明度を戻す処理を入れます。再度ValueTo()を実行し、delayで表示時間を指定します。

public void showLifeGage() {
    // フェードアウト
    iTween.ValueTo(gameObject, iTween.Hash(
        "from", canvasGroup.alpha,
        "to", 1.0f,
        "time", feed_speed,
        "easetype", iTween.EaseType.linear,
        "onupdate", "changeAlpha",
        "onupdatetarget", gameObject
    ));

    // フェードイン
    iTween.ValueTo(gameObject, iTween.Hash(
        "from", 1.0f,
        "to", 0f,
        "time", feed_speed,
        "easetype", iTween.EaseType.linear,
        "delay", show_time,
        "onupdate", "changeAlpha",
        "onupdatetarget", gameObject
    ));
}

delayで指定した秒数経過後に透明になるはずです。

連続でダメージ発生時の表示制御

これでダメージ後の一定時間は表示されるようになりましたが、連続でダメージを受けた場合にiTweenが重複して実行されてしまいます。特に他に動かすiTweenコンポーネントがない場合、実行前にiTween.Stop()で止めてしまいましょう。

呼び出す際にオーバーロードで候補がいくつかありますが、ここではiTween.Stop(GameObject)を使用します。引数なし版はシーン内全てのiTweenを止めようとするので気をつけましょう。

public void showLifeGage() {
    // 一度Tweenを全てストップ
    iTween.Stop(gameObject);

    // フェードアウト
    iTween.ValueTo(gameObject, iTween.Hash(
        "from", canvasGroup.alpha,
        "to", 1.0f,
        "time", feed_speed,
        "easetype", iTween.EaseType.linear,
        "onupdate", "changeAlpha",
        "onupdatetarget", gameObject
    ));

    // フェードイン
    iTween.ValueTo(gameObject, iTween.Hash(
        "from", 1.0f,
        "to", 0f,
        "time", feed_speed,
        "easetype", iTween.EaseType.linear,
        "delay", show_time,
        "onupdate", "changeAlpha",
        "onupdatetarget", gameObject
    ));
}

停止直後にフェードアウトのValueTo()が実行されますが、fromに現在の透明度を参照するようにしているため、中途半端なタイミングで停止→実行された場合でも違和感なく変わってくれます。

もし他にiTweenを実行している場合はiTween.StopByName()で自身のGameObjectと止めるiTween名を指定することも可能です。その場合、iTween.Hashの中でnameを設定してあげましょう。

動作テスト

実際に動かすとこんな感じ。
feed_speedの値は0.15、show_timeは0.5に設定してあります。

フレームレートが低いので分かりにくいですが、連続で叩いた場合でも問題なさそうです。

あとがき

そんなわけで、体力ゲージを一定時間のみ表示するようにしてみました。
久しぶりにiTweenを使いましたが、やはりとっても便利です。ひそかにDOTweenに浮気していたりもしましたが、シンプルなアニメーションであればiTweenの方がやりやすい印象です。

スポンサーリンク

down

コメントする



ツイッター