【Unity】PNGやGIFを連続表示してエフェクトにする

Unity

Unity初心者です。

現在2Dでカードゲームを作成しているのですが、作成にあたり困ったことが発生しました。

どうやらUnityではデフォルトでGIFをサポートしていないようでした。

自分はエフェクトは有料のものを購入しているのですが、大体がGIFか連続したPNGなので、どうやってゲーム内で表示すれば良いのか迷いました。

エフェクトはパーティクルなどを使うのが一般的のようですが、正直さっぱりだったので、結論としては自作でイメージを連続表示するクラスを作成しました。

エフェクトの画像がGIFの場合はPNGに分割する

前述したとおり、どうやらGIFはUnityでサポートされていないようなので画像をバラす必要がありました。

調べるとフォトショなどで簡単にできるらしいですが、そんな高価なソフトは持ち合わせていない…。

幸いGIFを分解してくれるWebサイトを見つけたのでこちらを利用することにしました。

GIFアニメ分解君
GIFアニメ画像を分解コマ割りにして画像を一覧表示します

画像ファイルをアップロードするだけでフレームごとに画像を分解してくれます。

この分解された画像を連続して表示することで、エフェクトのアニメーションを作成しようと思います。

とりあえずエフェクトの用のオブジェクトを作成

とりあえず、Canvas上にImageを作成します。(UI→Image)

それでスクリプトに以下を記載してオブジェクトに貼り付けます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Effect : MonoBehaviour
{
    public Sprite[] sprites;
    public float speed;
}

上記で宣言したspritesという配列に画像を格納することにしました。

↓こんな感じ。

speedは画像がアップデートされる時間を指定する想定ですが、とりあえず適当に50くらいとしました。これは試してみて駄目なら変更します。

コルーチンでPNGファイルを連続表示させる

次にソースを修正して以下のようにしました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Effect : MonoBehaviour
{
    public Sprite[] sprites;
    public float speed;
    private Image image;
    private float current;

    void Start()
    {
        image = GetComponent<Image>();
        image.sprite = sprites[0];
        current = 0f;
        IEnumerator coroutine = updateImg();
        StartCoroutine(coroutine);
    }

    private IEnumerator updateImg()
    {
        int index = 0;
        while (index < sprites.Length - 1)
        {
            current += Time.deltaTime * speed;
            index = (int)(current) % sprites.Length;
            if (index > sprites.Length - 1) index = sprites.Length - 1;
            image.sprite = sprites[index];
            yield return new WaitForSeconds(0.01f);
        }

        Destroy(gameObject);
    }

まず処理が開始されたら画像配列の0番目を設定します。

その後にコルーチンをキックして画像をアップデートしていきます。

エフェクトをPrefab化したりSEを鳴らしたりしてみる

これで一応画像はアニメーションにすることは出来たと思うのですが、エフェクトなのでSEがほしいし、一気に複数表示させたりするのでPrefab化することにしました。

上で作ったオブジェクトをPrefab化して、「Resources\Prefabs\PowerUpEffect」という名前で保存。

ソースを以下のように修正します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Effect : MonoBehaviour
{
    static GameObject _prefab = null;
    public Sprite[] sprites;
    public float speed;
    public AudioClip se;
    private Image image;
    private float current;


    public static void EffectAdd(float x, float y, string name)
    {
        GameObject prefab = Resources.Load("Prefabs/" + name) as GameObject;
        Vector3 pos = new Vector3(x, y, 0);
        GameObject canvas = GameObject.Find("Canvas");
        GameObject g = Instantiate(prefab, pos, Quaternion.identity) as GameObject;
        g.transform.SetParent(canvas.transform, false);
        g.transform.position = pos;
    }

    void Start()
    {
        image = GetComponent<Image>();
        image.sprite = sprites[0];
        current = 0f;
        GetComponent<AudioSource>().PlayOneShot(se);
        IEnumerator coroutine = updateImg();
        StartCoroutine(coroutine);
    }

    private IEnumerator updateImg()
    {
        int index = 0;
        while (index < sprites.Length - 1)
        {
            current += Time.deltaTime * speed;
            index = (int)(current) % sprites.Length;
            if (index > sprites.Length - 1) index = sprites.Length - 1;
            image.sprite = sprites[index];
            yield return new WaitForSeconds(0.01f);
        }

        Destroy(gameObject);
    }
}

エフェクトのゲームオブジェクトにSEを設定できるようになったので、SEも設定します。

以下のような形で呼べば、100,200の座標にエフェクトが表示されます。

Effect.EffectAdd(100, 200, "PowerUpEffect");

コメント

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