質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.30%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1748閲覧

UniRxを使い、変数がtrueになっている間の経過時間を取得したい

hamalt

総合スコア23

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2022/03/08 16:07

UnityでUniRxを使い、変数がtrueになっている間の経過時間を取得したく思い、以下コードを記述してみましたが上手く行きませんでした。

C#

1using System; 2using UnityEngine; 3using UniRx; 4using UniRx.Triggers; 5 6public class SampleClass : MonoBehaviour 7{ 8 // 状態 9 private bool IsState { get; set; } = false; 10 11 // 経過時間をここに保存したらできる? 12 TimeSpan totalTimeSpan; 13 14 void Awake() 15 { 16 // IsStateがtrueの間の経過時間を計算しtotalTimeSpanに入れる 17 var inputObservable = gameObject.UpdateAsObservable().Where(_ => IsState); 18 19 // TODO: 以下だとゲーム起動からの時間を計算してしまう 20 Observable.TimeInterval(inputObservable) 21 .Do(x => 22 { 23 totalTimeSpan = totalTimeSpan.Add(x.Interval); 24 Debug.Log($"経過時間:{totalTimeSpan.Seconds}"); 25 }) 26 .Subscribe(); 27 } 28 29 // SampleObjに衝突したらIsStateをtrueに 30 void OnTriggerEnter2D(Collider2D col) 31 { 32 if (col.gameObject.CompareTag("SampleObj")) 33 { 34 IsState = true; 35 } 36 37 } 38} 39コード

Observable.TimeIntervalDo引数に前回フレームからの経過時間が入ってくるので、x.Intervalを合計していけば経過時間を取得できると思いました。
しかしこれだと、ゲーム起動からの経過時間がログに出力されます。

IsState = trueになっている間の経過時間を測る方法に詰まってしまいました。

勉強し始めのコード内容で恐縮です。
どなたかお力添え願えますでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

UpdateAsObservableTimeIntervalをとって、それをWhereでフィルタリングしてScanで足す(Doでもいい。)


補足
何が起きていたか:

補足

投稿2022/03/08 23:35

編集2022/03/09 07:49
ozwk

総合スコア13553

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hamalt

2022/03/09 03:11 編集

ご回答ありがとうございます。 ごめんなさい、頂いた内容のWhereやScanを理解しようと思い書籍を購入しましたがすぐには理解できず実装も上手くいきませんでした。 (正確には、時間をWhereでフィルタリングする良い方法が判明しませんでした) なのでUpdateメソッド内で簡易的に計算することにしました。 ``` void Update() { if (IsState) { // true状態の時間経過を計測する totalTime += Time.deltaTime; Debug.Log(totalTime); } } ``` イベント発行&別クラスで時間経過を計測し疎結合を図ろうと思いましたが、実力不足でした。 上記で対応してみます。 この度はありがとうございました。
ozwk

2022/03/09 04:04

Observable.TimeInterval( gameObject.UpdateAsObservable().Where(_ => IsState) ) ではなくて Observable.TimeInterval( gameObject.UpdateAsObservable() ).Where(_ => IsState)にしてはどうでしょうということでした
hamalt

2022/03/09 07:05

再度ご回答ありがとうございます! 少し不格好ですが、試しに以下のようにやってみたら正常に計測できました! Start()内で: Observable.TimeInterval(gameObject.UpdateAsObservable()) .Where(_ => IsState) .Scan((pre, cur) => { totalTimeSpan = pre.Interval.Add(cur.Interval); cur.Interval = pre.Interval.Add(cur.Interval); Debug.Log(totalTimeSpan.Seconds); return cur; }) .Subscribe(); 大変たすかりました。 この度はありがとうございましたm(_ _)m
hamalt

2022/03/09 08:46

とても分かりやすい補足もありがとうございます。 大変合点がいきました…! こうして見ると最初のコードの間違いが丸わかりですね。。 この度は本当にありがとうございました🙇‍♂️
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問