Unity初心者です。
現在2Dでカードゲームを作成しているのですが、作成にあたり困ったことが発生しました。
どうやらUnityではデフォルトでGIFをサポートしていないようでした。
自分はエフェクトは有料のものを購入しているのですが、大体がGIFか連続したPNGなので、どうやってゲーム内で表示すれば良いのか迷いました。
エフェクトはパーティクルなどを使うのが一般的のようですが、正直さっぱりだったので、結論としては自作でイメージを連続表示するクラスを作成しました。
エフェクトの画像がGIFの場合はPNGに分割する
前述したとおり、どうやらGIFはUnityでサポートされていないようなので画像をバラす必要がありました。
調べるとフォトショなどで簡単にできるらしいですが、そんな高価なソフトは持ち合わせていない…。
幸いGIFを分解してくれるWebサイトを見つけたのでこちらを利用することにしました。
画像ファイルをアップロードするだけでフレームごとに画像を分解してくれます。
この分解された画像を連続して表示することで、エフェクトのアニメーションを作成しようと思います。
とりあえずエフェクトの用のオブジェクトを作成
とりあえず、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");
コメント