GWが明けて
GW明けということもあり、きっと色んな職場や学校では期間中にどこへ行っただとか、何々を観てきただとかの話題が飛び交って賑やかなことだと思うのですが、私は静かです。お土産とかもらってばかりだし。
休みの間にやったことと言えば、Unityでゲームを作ったり、Unityでゲームを作ったり、Unityでゲームを作ったりしてました。テレビも観ずに部屋に閉じこもってばかりいたので、いつの間にかTOKIOが四人になっていてビックリ、とかそんな状況です。まるでGW中は意識が一時停止していたみたいな間隔。
一時停止といえば・・・
CutieCircuitのアップデートで一時停止機能を作ろうと思い色々を調べたのですが、結構面倒くさい。
真っ先に出てくる方法といえばTime.timeScaleを0のする方法ですが、これが意外と使えない。
まず、何から何まで止まってしまうので、例えばボタンにクリック時のアニメーションとか設定していても止まってしまう。にも関わらず、Update関数は止まらずに呼ばれるので、Update関数で入力処理やタイマー処理とか実装していたら当然動いてしまう。
(注:FixedUpdate関数は呼ばれなくなります)
なのでこの方法はパスするとして、他にないか調べると以下の方法が
- レンダラ以外のコンポーネントをenable=0にする
ああ、なるほど、面倒くさい
面倒くさいのヤダ
といわけで、面倒くさい事はできるだけ避けてきた人生なので、もっと楽に実装できないかとあれこれ考えて、以下の結論に達しました。
- UI系は止めずに一時停止中は触れないようにする。
- タイマー処理はフラグを参照してスキップする。
- オブジェクトの動作はDOTweenを一時停止する。
要は絶対停止してほしい物だけを止めて、あとはユーザが操作できなければ良い、という思想
1.UI系は止めずに一時停止中は触れないようにする。
これは簡単。ScreenSpace-Overlayの最上位CanvasにRayCast Targetを設定したPanelを全面に表示するだけ。
最前面のPanelにRayCastが飛ぶので、その下にあるボタンやらのUIにはイベントが通知されなくなります。
Canvasを最上位するにはSortOderの値を大きくしてあげれば大丈夫です。
2.タイマー処理はフラグを参照してスキップする。
これも簡単。一時停止フラグみたいな変数を作ってUpdate関数の最上位で参照するだけ。
3.オブジェクトの動作はDOTweenを一時停止する
Cutie CircuitはUI系はiTween、それ以外のオブジェクトはDoTweenで動作させています。
別に一時停止機能の為にそうした訳ではなくて、ただiTweenのMoveFrom系がUIのスライド表示に便利で使っていただけなのですが、使い分けが出来ていたのでDoTweenの一時停止でUI以外は全て止めることができます。
DoTweenって何?って方は以下の記事を参照してください。
DoTweenの一時停止はPauseAll、RestartAllで行うことができますし、timeScaleを0にしても止める事が出来ます。
DOTween.PauseAll();
DOTween.RestartAll();
DOTween.timeScale = 0.0f;
今回の場合は、TogglePauseAllを使用して実装しました。これは一回呼ぶと停止、二回目呼ぶと再開、という超便利関数。
DOTween.TogglePauseAll();
これを一時停止ボタンのクリック時に呼び出すだけ!めっちゃ楽!
で、これらの対応で一時停止の機能を実装するとこんな感じになります。
UI系は止まってないので、一時停止を押してもテキストの表示等が行うことが出来ます。
注意事項
これで大体想定どおりの動きになったのですが注意事項もあって、DOTweenのPause関数で止める事が出来るのは現在動作中のTweenのみです。例えばコルーチン等でPause関数の呼び出し後にDOTweenを呼ぶとそのtweenは動いてしまいます。
追記:
アニメーションを止める場合は各オブジェクトのAnimatorのspeedを0にする必要があります。
ん~、これはこれで結構面倒くさいかも・・・"(-""-)"