【Unity】Prefabで生成したインスタンスのメソッドを呼ぶ
Unityで落ちゲーを作ろうとしていて、ブロックの消去アニメーション的な事をやりたくなりました。
そこで、試しにブロックに状態を持たせて、その状態が”消去中”になっていたらブロックを小さくしていく方法を考えます。
※ これはUnityやゲーム開発の勉強中での覚書的なTips的なことをツラツラと書く記事です
呼び出すメソッド
ブロックに紐づけるオブジェクトのコードはこんな感じ
int型(enumの方が良いかな?)のstatus変数を用意して、その値によって更新(Update)の時の処理を行うだけです
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Block : MonoBehaviour
{
// ブロックの状態
// 0: 初期状態、1: 落下中、2: 消去中、3: 削除待ち (仮決め)
int status = 0;
private int count = 0;
void Update()
{
if (status == 2)
{
// 消去処理(20フレーム毎に小さく)
if (count % 20 == 19)
{
// 75%ずつ小さくする
Vector3 scale = transform.localScale;
transform.localScale = new Vector3(scale.x * 0.75f, scale.y * 0.75f, scale.z * 0.75f);
// サイズが最小になったら、状態を削除待ちにする
if (scale.x < 0.1) SetWaitDeleteState();
}
count++;
} else if (status == 3)
{
// 完全に消える時に何かしたいなら、ここでやる
}
}
public void SetFallingState()
{
SetStatus(1);
}
public void SetDeletingState()
{
SetStatus(2);
}
public void SetWaitDeleteState()
{
SetStatus(3);
}
private void SetStatus(int status)
{
this.status = status;
}
}
やりたい記述
やりたいのは、前述のクラスのSetWaitDeleteState() など
を外部から呼び出すことです。
ですが…どうやって呼び出せるのでしょう?
// Prefabからインスタンス生成(blockPrefabはブロックのPrefab)
currentBlock = Instantiate(blockPrefab, new Vector3(0, 0, 0), Quaternion.identity);
// ↓ こんな感じで呼び出したい
currentBlock.SetDeletingState();
↑な感じをイメージしますが、これだとcurrentBlock
はGameObjectクラスなので呼び出すことは出来ません。
なので、Blockクラスにキャスト出来ないか考えたのですけど……BlockクラスはGameObjectの派生では無いっぽいので無理でした。
↓ みたいな感じでやりたかった ……
(currentBlock as Block).SetDeletingState();
SendMessageメソッド
リファレンスを見ていたらGameObjectにSendMessage
というメソッドがあります。
どうやらこれを使えば呼び出す事ができそう…
// これで、呼び出しできる
currentBlock.SendMessage("SetDeletingState");
これで、一応は呼び出す事ができました。
けど、これって安全な呼び出しではないし、パフォーマンスも悪そう…
(Javaのリフレクションに近い感じ?)
まぁ、これはこれで一つの方法として置いておいて、もっとちゃんと呼び出せる方法を調べました。
GetComponentメソッド
たぶん、Unityのスクリプトを書いていたらよく出てくると思われるメソッド…
GameObjectに付与しているコンポーネントを取得するメソッドですね。
最終的には、このメソッドで簡単に取得することができました。
Block block = currentBlock.GetComponent<Block>();
block.SetDeletingState();
GetComponent<T>()
のT
部分にクラス名を入れるだけでOK!
これでやりたい事ができました。\ヤッタネ/
(もちろん、あらかじめ対象のPrefabにスクリプトを付与しておいてくださいね)
エラー処理
今回は、明らかに取得できることが分かっているので省いていますが、場合によっては取得できなかった場合のnullチェックをしておきましょう。
Block block = currentBlock.GetComponent<Block>();
// 取得できない場合はnullになるので、nullじゃ無い時にだけ実行する
if (currentBlock != null) block.SetDeletingState();
まとめ
オブジェクトに付与しているコンポーネントは GetComponent<T>()
で取得できて、スクリプトもコンポーネントの1種なので、同様に取得できるという事ですね。
分かれば単純な事ですけど、理解していないと悩んでしまいますね。😓
ディスカッション
コメント一覧
まだ、コメントがありません