はじめに
少し前に書いたコードがメモ帳にあったので、Qiitaを始めたついでに投稿してみる
カウントダウンやカウントアップができる簡単なタイマークラス KitchenTimer を作ってみた
「N秒に1回 〜する」 のような処理を簡単に試したい時に使う。
結論
完成形がこちら。使い方は下の方で説明。
KitchenTimer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// Unity で簡単に使えるタイマークラス
public class KitchenTimer: MonoBehaviour
{
//-----------------------------------------------------
/// [CountUp] 0秒からカウントアップ, u秒毎にeveryUが呼ばれる
public void CountUp(float u, Action<float> everyU)
{
isCountUp = true;
this.currentTime = 0; // 正確に保持している秒
StartCoroutine(this.IECountUp(u, everyU));
}
//-----------------------------------------------------
/// [CountDown] c秒からカウントダウン, d秒毎にeveryDが呼ばれる
public void CountDown(float c, float d, Action<float> everyD, Action timeOver)
{
isCountUp = false;
this.currentTime = c; // 正確に保持している秒
StartCoroutine(this.IECountDown(c, d, everyD, timeOver));
}
//-----------------------------------------------------
/// [StopCount] カウントをストップ
public float StopCount()
{
this.isTimeRunning = false;
return this.currentTime;
}
//-----------------------------------------------------
/// [RestartCount] ストップのあとで、もう一度カウント再開
public void RestartCount()
{
this.isTimeRunning = true;
if(isCountUp)
{
StartCoroutine(this.IECountUp(this.tempInterval, this.tempAction));
}
else
{
this.CountDown(this.currentTime, this.tempInterval, this.tempAction, this.tempTimeOver);
}
}
//-----------------------------------------------------
/// [Wait] W秒間待ったあとで実行
public void Wait(float w, Action action)
{
this.action = action;
Invoke("DoAction",w);
}
//-----------------------------------------------------
/// [Repeat] 実行 -> r秒待つ -> 実行 を繰り返す
public void Repeat(float r, Action action)
{
this.action = action;
InvokeRepeating("DoAction",0f, r);
}
//-----------------------------------------------------
/// [WaitAndRepeat] Wait と Repeat を両方する
public void WaitAndRepeat(float waitTime, float intervalTime, Action action)
{
this.action = action;
InvokeRepeating("DoAction", waitTime, intervalTime);
}
//-----------------------------------------------------
/// [Dispose] 使い終わった タイマー を捨てる
public void Dispose()
{
CancelInvoke();
Destroy(this);
}
//*******************************************************************
// その他
//*******************************************************************
/// 時間を保持するプロパティ
private float currentTime;
/// カウントを進めて良いかどうか(時間が進んでいるか)
private bool isTimeRunning = true;
/// カウントアップ中かダウン中か
private bool isCountUp;
/// メソッドを保持するプロパティ
private Action action;
// 中断中のカウントの変数を一時保持する
private float tempInterval;
private Action<float> tempAction;
private Action tempTimeOver;
/// 保持したメソッドを実行する
private void DoAction()
{
this.action();
}
/// カウントアップ用のIE
private IEnumerator IECountUp(float u, Action<float> everyU)
{
// 中断用の一時変数を保存
this.tempAction = everyU;
this.tempInterval = u;
var count = 0f;
while(currentTime < 600f) // 限界は600秒までとする
{
if (isTimeRunning)
{
this.currentTime += Time.deltaTime;
count += Time.deltaTime;
}
else
{
break;
}
if(count > u)
{
everyU(this.currentTime);
count -= u;
}
yield return null;
}
if (isTimeRunning)
{
// 最後に忘れず、一時変数をnullに
this.tempAction = null;
}
}
/// カウントダウン用のIE
private IEnumerator IECountDown(float c, float d, Action<float> everyD, Action timeOver)
{
// 中断用の一時変数を保存
this.tempInterval = d;
this.tempAction = everyD;
this.tempTimeOver = timeOver;
var count = 0f;
while(currentTime > 0)
{
if (isTimeRunning)
{
this.currentTime -= Time.deltaTime;
count += Time.deltaTime;
}
else
{
break;
}
if(count > d)
{
everyD(this.currentTime);
count -= d;
}
yield return null;
}
if (isTimeRunning)
{
timeOver(); // 中断以外でここに来た場合はタイムオーバーということ
// 最後に忘れず、一時変数をnullに
this.tempAction = null;
this.tempTimeOver = null;
}
}
}
使い方
1. KitchenTimer.cs をProjectウィンドウの中の好きなところに置く
2. timerインスタンスの生成
新しいタイマーを作る。
※このスクリプトを貼り付けたオブジェクトが消滅すると、タイマーもなくなるので注意。
var timer = this.gameObject.AddComponent<KitchenTimer>();
カウントアップ(0, 1, 2 ...) timer.StartCountUp
1.0秒に1回、処理をする例
time には、その時の時間が少数まで入っている。 「1.13」 「2.04」
場合に合わせて四捨五入して使う
timer.StartCountUp(1.0f,
(time) =>
{
// ここに1秒に1回やりたい処理を書く
Debug.Log(time);
}
);
カウントダウン(30, 29, 28 ...) timer.StartCountDown
残り30秒からスタートして、1秒に1回処理をする例。
timer.StartCountDown(30.0f, 1.0f,
(time) =>
{
// ここに1秒に1回やりたい処理を書く
Debug.Log(time);
},
() =>
{
// 30.0秒のカウントダウンが終わったらここに来る
Debug.Log("時間切れ");
}
);
一時ストップ timer.Stop
timer.Stop(
(time)=>
{
// time にはタイマーが止まった時の時間が入っている
Debug.Log(time);
}
);
ストップ時点から再開 timer.StartFromStopPoint
timer.StartFromStopPoint();
最初から測り直し timer.ResetAndReStart
timer.ResetAndReStart();
タイマーを捨てる(メモリ開放を明示的にしたいとき) timer.Dispose
timer.Dispose();
さいごに
時間の単位は全て 「秒」 です。変換クラスと上手いこと合わせて使ってやってください。
以上です!
それにしても「キッチンタイマー」て。。。変な命名にハマる時期ってありますよね。。