🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Unity

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

Q&A

解決済

1回答

1819閲覧

Time.deltatimeが経過時間を測ってくれない

ShuFRe

総合スコア4

C#

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

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Unity

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

0グッド

0クリップ

投稿2021/03/06 04:17

前提・実現したいこと

UnityでRPGの会話ウインドウにTextのUIを使って、セリフが1字ずつ表示されるような仕組みを作っています。色々調べ、時間を空けて処理をする方法にコルーチンとTime.deltatimeの2種類の方法が見つかりました。

発生している問題・エラーメッセージ

コルーチンを使ったプログラムでは指定した秒間で1字ずつ表示され、やりたいことを実現できたのですがTime.deltatimeを使った方法は1字ずつ表示されているようには見えず、全文一度に表示されるように見えます。
そこで本当に指定した時間が経過した後に処理がされているのか確かめるために経過時間をConsoleに表示させてみましたが明らかに10秒はたっていないのに10.00884が文字数分表示されました。
イメージ説明
人物と接触したらenterが表示され、指定したキーを押すと文字を表示する処理が入ります。下の画像は接触した後、2秒後に指定したキーを押した瞬間に経過時間が10.00884と表示されたものです。

Time.deltatimeの使い方が間違っているのでしょうか?それとも別の問題があるのでしょうか?

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class windowController : MonoBehaviour 7{ 8 [SerializeField] Text messageText; //messageTextを取得する。テキストを書き換えるのにつかう。 9 [SerializeField] GameObject windowPanel; //windowPanelを取得する。windowPanelのアクティブ化に使う。 10 private int nowLetterNum = 0; //現在の文字番号(文字数) 11 [SerializeField] float speed; //1文字あたりの表示される時間 12 private float elapsedTime = 0; //経過時間 13 private int dummy = 0; 14 15 // Start is called before the first frame update 16 void Start() 17 { 18 19 } 20 21 public void DisplayMessage(string ms) 22 { 23 messageText.text = ""; 24 windowPanel.SetActive(true); //windowPanelをアクティブにする。 25 for (nowLetterNum=0; nowLetterNum<ms.Length; dummy++) ←dummyはテキトーな変数です。 26 { 27 if (elapsedTime > speed) 28 { 29 Debug.Log(elapsedTime); 30 messageText.text += ms[nowLetterNum]; //入ってきたメッセージを表示する。 31 nowLetterNum++; 32 elapsedTime = 0; 33 } 34 elapsedTime += Time.deltaTime; 35 36 } 37 38 } 39 40 // Update is called once per frame 41 void Update() 42 { 43 44 } 45 46 47} 48 49

別のスクリプトからDisplayMessageを引数にセリフを入れて呼び出すようにしてます。
PanelのwindowPanelには子要素として会話ウインドウのImage、TextのmessageTextが取り付けられています。そのためPanelをアクティブにすることで会話ウインドウとTextがアクティブになります。

試したこと

Consoleに経過時間を表示してみた。

補足情報(FW/ツールのバージョンなど)

Unity
m_EditorVersion: 2019.4.17f1
m_EditorVersionWithRevision: 2019.4.17f1 (667c8606c536)

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

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

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

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

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

guest

回答1

0

ベストアンサー

DisplayMessage()の中に、1フレーム待機するという処理はどこにもありません。
また、Unityでは関数に一定期間待機するという処理は入れてはいけませんので、ここではコルーチンを使うのが適切でしょう。

C#

1 public void DisplayMessage(string ms) 2 { 3 StartCoroutine(DisplayMessageCoroutine(ms)); 4 } 5 6 IEnumerator DisplayMessageCoroutine(string ms) 7 { 8 messageText.text = ""; 9 windowPanel.SetActive(true); //windowPanelをアクティブにする。 10 for (nowLetterNum=0; nowLetterNum<ms.Length; ) 11 { 12 if (elapsedTime > speed) 13 { 14 Debug.Log(elapsedTime); 15 messageText.text += ms[nowLetterNum]; //入ってきたメッセージを表示する。 16 nowLetterNum++; 17 elapsedTime = 0; 18 } 19 elapsedTime += Time.deltaTime; 20 21 yield return null; //1フレーム待機 22 } 23 }

もし、コルーチンを使いたくないのであれば、以下のように毎フレームごとに関数を終わらせる必要があります。

C#

1 bool isDisplayMessage = false; // 表示中かどうか 2 string tempMs; // メッセージ本文(いい名前が思いつかなかった) 3 4 public void DisplayMessage(string ms) 5 { 6 messageText.text = ""; 7 windowPanel.SetActive(true); //windowPanelをアクティブにする。 8 9 isDisplayMessage = true; 10 tempMs = ms; 11 } 12 13 void Update() 14 { 15 if (isDisplayMessage) 16 { 17 if (elapsedTime > speed) 18 { 19 Debug.Log(elapsedTime); 20 messageText.text += tempMs[nowLetterNum]; //入ってきたメッセージを表示する。 21 nowLetterNum++; 22 elapsedTime = 0; 23 } 24 elapsedTime += Time.deltaTime; 25 } 26 }

(なお、コードは未検証なので、エラーやバグがあれば、適宜修正してください)

投稿2021/03/06 04:45

編集2021/03/06 04:48
fiveHundred

総合スコア10152

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

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

ShuFRe

2021/03/06 05:35

なるほど、1フレーム経ったことが分かるような処理がないと計測できないのですね。 他の方法の提示など、丁寧にありがとうございました!
ShuFRe

2021/03/06 10:21

すみません。Time.deltatimeを使ったコードをUpdate内で書いてみましたがやはり10秒経たずに結果が返ってきます....なにがいけないのでしょうか…
fiveHundred

2021/03/06 10:26

コードは私の記載したものの通りですか?
ShuFRe

2021/03/06 10:33

繰り返し文をいれてしまっていたせいでUpdate関数が終わってませんでした! すみません。修正して、きちんと動いて解決しました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問