i-school - 【UI】Slider の現在値にエフェクトを表示する
 Slider を利用したゲージ機能の演出例です。
 
 例えば HP などのゲージの変動に合わせて、Slider の現在値にエフェクトを表示させる機能を作成します。








作成方法




完成時のヒエラルキー画像



1.Canvas 作成


 RenderMode を Screen Space -Camera- に設定し、MainCamera ゲームオブジェクトをアサインします。

 複数の Canvas を利用している場合には、Order in Layer の値を最も高い値に設定します。





2.Slider 作成


 Canvas の子オブジェクトとして Slider を作成します。
Handle Slide Area ゲームオブジェクトと、その子オブジェクトである Handle ゲームオブジェクトは利用しませんので
非アクティブ状態にするか、削除してください。









 各子オブジェクトの参考値です。
任意のサイズ、色、フレームを適用してください。














3.エフェクトのインポート



エフェクト用サンプルアセット
https://assetstore.unity.com/packages/vfx/particle...












4.エフェクトの配置


 Fill ゲームオブジェクトと連動して移動するようにすることで、Slider の現在値にエフェクトを表示できます。

 なお通常のゲームオブジェクトは Transform コンポーネントがアタッチされていますが、
Canvas で利用するためには UI 用の RectTransform コンポーネントを利用する必要があります。

 インスペクターの Add Component ボタンを押して、RectTransform コンポーネントを追加することで、
Transform コンポーネントを RectTransform コンポーネントに切り替えることが出来ます。
(プレハブの場合には、事前に Unpack してから作業してください。)











 Main モジュール内の Looping のチェックを外しておいてください。(デバッグ時には入れておくと便利ですので、この画像ではチェックを入れています)

 Main モジュール内の PlayOnAwake のチェックを入れておいてください。
このチェックを入れておくことで、ゲームオブジェクトがアクティブ状態になるたびにパーティクルシステムが最初から再生されます。






 Renderer モジュール内の Order in Layer の値を 1 以上に設定して画面表示の優先度を上げておいてください。


 設定は以上です。
採用しているエフェクトにもよりますが、それ以外の部分は初期設定のままで利用できます。


5.タイミングに合わせてエフェクトを表示する


 使い方としては、Slider の更新に合わせてエフェクトを表示させるようにすることで、Slider の現在値にエフェクトを表示できます。

 エフェクトにパーティクルシステムを利用している場合には、ゲームオブジェクトの表示/非表示を切り替えるだけで自動的にエフェクトが再生されます。

 以下にサンプルコードを提示しておきます。
加工して利用してください。(非同期処理には UniTask を利用しています。)


using Cysharp.Threading.Tasks;
using UnityEngine;

public class ParticleController : MonoBehaviour
{
    [SerializeField] private ParticleSystem particleSystem;

  // テスト用
    async UniTaskVoid Start()
    {
    // キャンセル処理用のトークン生成
    var token = this.GetCancellationTokenOnDestroy();

    // デバッグ用。実際にはダメージを受けたタイミング、Slider を更新したタイミングなどで外部クラスから実行する
        // トークンは引数で渡す。メインの処理を停止させる必要はないため、Forget を利用する
        await PlayAndHideParticle(token).Forget();
    }

    // パーティクルシステムの再利用
    public async UniTask PlayAndHideParticle(CancellationToken token)
    {
        // パーティクルシステムのアクティブ化
        particleSystem.gameObject.SetActive(true);

        // パーティクル再生(パーティクルシステム内の PlayOnAwake にチェックを入れておけば、この処理は不要)
        //particleSystem.Play();

        // パーティクル再生が終わるまで待機(パーティクルシステムの Looping のチェックを外しておけば、パーティクルシステムの Duration の時間だけ待機になる)
        // WithCancellation メソッドをチェーンし、token を渡すことでキャンセル処理に対応できるようにしている
        await UniTask.WaitUntil(() => !particleSystem.isPlaying).WithCancellation(token);

        // パーティクルシステムの非アクティブ化
        particleSystem.gameObject.SetActive(false);
    }
}

 パーティクルシステムの Main モジュールの Looping にチェックが入っていると
await UniTask.WaitUntil(() => !particleSystem.isPlaying); の処理が終了しません。


 必ず Looping のチェックを外し、PlayOnAwake のチェックを入れてから動作検証してください。