ものららい 2022/01/31 14:19

Unityでコルーチンを使って一定時間後に処理を走るようにするやつ


(前回と変わり映えしないスクショ)

今回はUnityでコルーチンを使って一定時間後に指定の処理を走らせる処理について。
※あくまで自身の学習用なので粗があってもおおめにみてね🦝


とりあえずソース。
TimerFunc.cs

using System;
using System.Collections;
using UnityEngine;

//コルーチンを使った指定時間後登録した処理をするやつ
public class TimerFunc : MonoBehaviour
{
	IEnumerator _coroutine;
	bool _activeFlag;
	bool _pauseFlag;
	float _setTime;
	float _startTime;
	Action _setFunc;
	
	
	//処理のセット
	public void SetFunc (float time, Action func)
	{
		//処理が設定されているとき
		if(func != null)
		{
			//すでに登録されてる処理を停止
			Stop();
			
			_activeFlag = true;
			_setFunc = func;
			_setTime = time;
			_startTime = Time.realtimeSinceStartup;
			
			//処理の予約
			_coroutine = Coroutine(time, func);
			StartCoroutine(_coroutine);
		}
	}
	
	
	//処理の実行
	IEnumerator Coroutine (float time, Action func)
	{
		//0秒以上であれば指定時間待つ
		if(time > 0)
		{
			yield return new WaitForSeconds(time);
		}
		
		//登録情報の初期化
		Stop();
		
		//登録した処理実行
		func();
	}
	
	
	//処理の停止
	public void Stop ()
	{
		if(_coroutine != null)
		{
			StopCoroutine(_coroutine);
			
			_coroutine = null;
			_activeFlag = false;
			_pauseFlag = false;
			_setTime = 0;
			_startTime = 0;
			_setFunc = null;
		}
	}
	
	
	//処理の一時停止
	public void Pause ()
	{
		if(CheckActive() == true && _pauseFlag == false)
		{
			_pauseFlag = true;
			StopCoroutine(_coroutine);
			
			//経過時間分減らした設定時間を求める
			_setTime -= Time.realtimeSinceStartup - _startTime;
		}
	}
	
	
	//処理の一時停止解除
	public void Unpause ()
	{
		if(CheckActive() == true && _pauseFlag == true)
		{
			_pauseFlag = false;
			
			//処理の再登録
			_coroutine = Coroutine(_setTime, _setFunc);
			StartCoroutine(_coroutine);
		}
	}
	
	
	//動作中か確認
	public bool CheckActive ()
	{
		if(_coroutine != null && _activeFlag == true)
		{
			return true;
		}
		
		return false;
	}
	
	
	//破棄される時に強○停止
	void OnDestroy ()
	{
		Stop();
	}
}

実際に使用するときはこんな感じに記述します。
Main.cs

using System;
using UnityEngine;
using UnityEngine.UI;

public class Main : MonoBehaviour
{
	void Awake ()
	{
		//セット
		TimerFunc _timerFunc = gameObject.AddComponent<TimerFunc>();
		
		//3秒後に処理
		_timerFunc.SetFunc(3, () => 
		{
			Debug.Log("こんにちは!");
		});
	}
}

まず、コルーチンってなぁに?って話ですがちょっと間違いがなく説明できる自信ないので、下記リンクで詳細見てもらえると助かります。
Unity ユーザーマニュアル コルーチン


一応、今回の使用の範囲で平たく平たく説明すると、

yield return new WaitForSeconds(time);

の部分で一度処理の流れ自体を停止して、指定時間後に停止した以降の処理を再開するみたいな物になります。

ただ、停止するといっても順番に処理が行われる通常の流れと違う非同期処理で動いているので最初は若干混乱するかもしれませんが、慣れてしまえば何秒後に何々してその何秒後に何々みたいなUpdateの中に毎フレームたくさん判定とるような処理を書くのをだいぶ減らせると思うので、だいぶすっきりした記述にできると思います。


便利ではありますが、コルーチンの記述自体を使用したい場所のクラスとか色んな箇所に書くと管理が大変なので、こういうタイマー機能を作ってそちらで処理させるのがうっかりさんにはおすすめです。


あと最後に、コルーチンを動かしているときにそのコルーチンの処理のコンポーネントがついてるGameObjectを破棄するとエラーが出るので、動作中の場合は下記の記述みたいに動作を停止してから破棄してください。

//(例
void OnDestroy ()
{
	StopCoroutine("コルーチン");
}

ちなみにコルーチンでこんなこともできます。
0.5秒ごとに呼ばれるループを作ってキャラクターのUVを更新して待機モーションっぽい事をしてます。


実際動作するアセットフォルダも置いておきますので、アセットフォルダを空プロジェクトに入れれば確認できます。(Script/Main.csに使用例があります)

2022_01_31_Assets.zip (76.15kB)

ダウンロード

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

最新の記事

記事のタグから探す

月別アーカイブ

記事を検索