ボタンを押すと2秒間隔でカウントが進み、右クリックあるいは画面クリックでカウント停止。
Unityのスクリプトで、特定の処理を遅延させたり、
時間間隔を指定して繰り返し実行したい場面で「Invoke」を使うことがあります。
さらに、メソッドに引数を渡すことや、途中で処理を停止・中断する場面も少なくありません。
しかし、Invokeは基本的に引数をサポートしていないため、ちょっとした工夫が必要です。
本記事では、Invokeを活用する方法や引数の渡し方、
途中で処理を中断するテクニックについて解説します。
- UnityのInvokeを使って処理を遅延させたい人
- Invokeに引数を渡す方法を探している人
- コルーチンとの違いを理解したい人
- Invoke処理を途中で停止・中断したい人
- ゲーム内のUIボタンの動作をカスタマイズしたい人
Invoke
Invokeは、指定された時間の経過後にメソッドを呼び出すための機能です。
使用することで、一定の遅延後に実行したり、繰り返し実行することができます。
単発の処理には、Invokeを使用します。
delayTimeで指定された時間(秒単位)の経過後にMethodNameというメソッドが呼び出されます。
Invoke("MethodName", delayTime);
繰り返しの処理には、InvokeRepeatingを使用します。
initialDelayで指定された時間(秒単位)の遅延後に初回のメソッド呼び出しを行い、
以降はrepeatRateで指定された時間の間隔でメソッドが繰り返し実行されます。
InvokeRepeating("MethodName", initialDelay, repeatRate);
Invokeの処理を停止するには、CancelInvokeを使用します。
これにより、開始されたInvokeやInvokeRepeatingの実行を止めることが可能です。
CancelInvoke("MethodName");
別のアプローチとして、onClickのクリックイベントを拡張する方法で、
「.onClick.Invoke()」を使用しています。
参考ページ:「UI.Button-onClick – Unity スクリプトリファレンス」
Invoke("呼び出す関数",秒数);
一例として、Invokeで、関数sec()を2秒後に、
表示までにかかる時間を表示する動作を実行します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InvokeMove : MonoBehaviour
{
void Start()
{
Invoke("sec", 2); //sec関数を2秒後に実行
}
void sec()
{
Debug.Log("表示時間:::::" + Time.time);
}
}
実際の動作はこちらになります。
Invokeに引数を渡す
UnityのInvokeメソッドは直接的に引数を渡すことはできませんが、
引数を持ったメソッドを実行したい場合は、ラムダ式や無名関数を使う方法があります。
using UnityEngine;
public class InvokeArguments : MonoBehaviour
{
void Start()
{
// 3秒後にメソッドを引数と共に実行
Invoke("CallMethodWithArguments", 3f);
}
// 引数を使う場合は、Invoke内でラムダ式を利用する方法
void CallMethodWithArguments()
{
int number = 10;
Invoke(() => MyMethod(number), 0f); // 引数を使ってMyMethodを呼び出す
}
// 引数を受け取るメソッド
void MyMethod(int value)
{
Debug.Log("引数として渡された値: " + value);
}
}
このコードを実行すると、3秒後に「10」がdebugされます。
コールチンとの違い
Invokeは単純に遅延処理を行いますが、
コルーチン(Coroutine)は、より複雑な処理をフレーム単位で細かく制御することができます。
例えば、Invokeでは処理が一度だけ実行されるのに対し、
コルーチンでは処理を一時停止したり、再開したりすることが可能です。
上記のInvokeと同じ処理をコールチンでします。
ポイントは、StartCoroutineを使ってコルーチンを開始します。
この場合、sec()というコルーチンを開始しています。
IEnumerator型のメソッドを定義して、yield returnで処理を途中、一時停止できます。
2秒間待ってから次の処理が実行されます。sec()を使うことで、指定の時間待機が可能です。
void Start()
{
// コルーチンを開始
StartCoroutine(sec());
}
// コルーチンメソッド
IEnumerator sec()
{
Debug.Log("処理開始");
// 2秒待つ
yield return new WaitForSeconds(2f);
// 2秒後に表示
Debug.Log("表示時間:::::" + Time.time);
}
両者を使い分けることで、ゲーム内のシーンやアニメーションの流れをスムーズに調整できます。
ボタンを押すとカウントアップ、画面を押すとカウント停止
UnityのUIシステムを使ったシンプルな例として、ボタンを押すとカウントがアップし、
画面をタップするとそのカウントが停止する仕組みを紹介します。
このシステムにはInvokeやCancelInvokeを使って実装できます。
ボタンの.onClick.Invoke()でカウントアップ処理を呼び出し、画面タッチの入力によってCancelInvokeを使い、途中で処理を中断する方法を解説します。
このシステムはノベルゲームのオート機能で有効です。
Autoボタンを押すと数秒ごとにテキストや立ち絵、セリフが進み、
画面やマウスの右クリックで動作が止まります。
ソースコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//追加
public class AutoFn : MonoBehaviour
{
public Text Count;
public Button btn;
bool Auto;
int i;
//Auto機能
public void Autobtn()
{
Invoke("Autocount", 2); //Autocount関数を2秒後に実行
Auto = true;
Debug.Log("開始!"+ Auto);
btn.image.color = Color.gray;
}
void Autocount()
{
i++;
Count.text = i.ToString();//変数iを文字列に変換
btn.onClick.Invoke(); //btnを押し続ける
}
void Update()
{
if (Auto == true && Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
{
//Auto Cancel
CancelInvoke("Autocount");
Auto = false;
Debug.Log("停止!" + Auto);
btn.image.color = Color.white;
}
}
}
UdemyでUnityを学習
Udemyは、オンデマンド式の学習講座です。
趣味から実務まで使えるおすすめの講座を紹介します。
- 【Unity C# ゲーム開発超入門】7つのミニゲームを作っておぼえる!UnityとC#講座
Unityで頻出の機能を実際のゲーム作りで学習。
何か作りたい、今後の開発で役立てたい初心者におすすめ
- 【Unity C# ゲーム開発初心者レベルアップ】7つのトランプゲームを作っておぼえる!UnityとC#講座
トランプやボードゲーム作りに特化している講座。
テーブルゲームを作りたい人におすすめ。
- 【全行程を網羅!最初に学びたい総合学習】Unityワールド制作講座
Unityワールド制作の全工程を学習できる講座。
RPGを作りたい人におすすめ。
- Unity ゲーム開発:インディーゲームクリエイターが教える C#の基礎からゲームリリースまで【スタジオしまづ】
C#の文法やApp StoreとGoogle Playへゲームをリリース方法を解説。
ゲームを出品したい人におすすめ。
解説
初めに、名前空間「using UnityEngine.UI;」を追加します。
上から3行はUnityにてスクリプトを生成するとデフォルトで取得できます。
しかし、今回はボタンとテキストのUIを使うので、入力が必要です。
追加しないと、UIが使えないので注意してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//追加
続いて、変数を定義します。
「Count」と「btn」はそれぞれテキストとボタンのUIです。
「Auto」はTrue・Falseの真偽値を代入するbool型です。
int型で変数を0,1にして真偽を分ける方法でも代用可能です。
「i」は、単にint型の変数で、後にこの変数を文字列に変換します。
public Text Count;
public Button btn;
bool Auto;
int i;
ここで、Invokeを用いて、Auto機能を実装します。
ボタン(Autobtn)を押すと、2秒後に関数Autocount()を実行します。
また、AutoがTrue(真)になり、ボタンの背景が白からグレーになります。
関数Autocount()では、変数iを1増やして、変数iを文字列(Count)に変換します。btn.onClick.Invoke(); でボタン(btn)を押します。つまり、Autobtn()へ戻ります。
//Auto機能
public void Autobtn()
{
Invoke("Autocount", 2); //Autocount関数を2秒後に実行
Auto = true;
Debug.Log("開始!"+ Auto);
btn.image.color = Color.gray;
}
void Autocount()
{
i++;
Count.text = i.ToString();//変数iを文字列に変換
btn.onClick.Invoke(); //btnを押し続ける
}
最後に、Auto機能の停止するコードを追加します。
if文でbool型変数AutoがTrue(真)であり、
左クリックあるいは右クリックしたときは、関数Autocount()を停止します。
また、bool型変数AutoがFaulse(偽)になり、ボタンの背景がグレーから白になります。
void Update()
{
if (Auto == true && Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
{
//Auto Cancel
CancelInvoke("Autocount");
Auto = false;
Debug.Log("停止!" + Auto);
btn.image.color = Color.white;
}
}
実演
ソースコードが完成しましたら、スクリプトをHierarchyウィンドウにアタッチして、
Inspectorウィンドウからテキスト・ボタンUIの項目をそれぞれアタッチします。
つづいて、ボタンにAutobtn()を実装します。
HierarchyウィンドウからOnclickを選択します。
この中に、AutoBtnメソッドを追加してください。
シーン再生をすると、冒頭で紹介した動作をします。
まとめ
UnityでAuto機能の実装するには、Invokeを使います。
Invokeは、ある関数を数秒後に実行するものです。
「btn.onClick.Invoke();」は、ボタンを押すコードで、
「CancelInvoke(“関数”);」は、関数の動作を停止するものです。