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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

943閲覧

テキスト表示を動かしたい

Um_kok

総合スコア39

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2021/01/08 09:24

こんにちは、テキストを表示してすこし動かすためにコードを書きました。
コードです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class StartCountTime : MonoBehaviour 7{ 8 // レース開始の合図 9 [SerializeField] private Text startCountNumber; 10 private int orderNumbers = 3; 11 12 void Start() 13 { 14 StartCoroutine(StartCountThreeTime(startCountNumber, 3)); 15 } 16 17 /// <summary> 18 /// レース開始の時間を三つ数える 19 /// </summary> 20 /// <returns></returns> 21 private IEnumerator StartCountThreeTime(Text numberText,int displayNumbers) 22 { 23 if (numberText == null) {// null ならばコルーチンを抜ける 24 25 yield break; 26 } 27 28 // 表示する文字 29 numberText.text = displayNumbers.ToString(); 30 31 // 大小サイズを決めておく 32 Vector3 initialSize = new Vector3(20, 20, 20); 33 Vector3 minimumSize = new Vector3(2, 2, 2); 34 35 var time = 0f; // 時間を数える 36 var countTime = 1; // 時間を指定 37 var size = 0f; // テキストのサイズ 38 var speed = 0.07f; // テキストの縮小スピード 39 40 41 numberText.enabled = true; 42 43 // 文字を小さくする 44 while (time <= countTime) { 45 46 time += Time.deltaTime; 47 numberText.transform.localScale = Vector3.Lerp(initialSize, minimumSize, size); 48 size += speed; 49 50 yield return null; 51 } 52 53 // 一応最小値をいれておく 54 numberText.transform.localScale = minimumSize; 55 56 var alpha = 1f; // α値を設定 57 58 // 文字が小さくなったならば、ゆっくり消える 59 if (numberText.transform.localScale == minimumSize) { 60 while(alpha >=0) {// α値を減らす 61 62 alpha -= Time.deltaTime; 63 numberText.color = new Color(numberText.color.r, numberText.color.g, numberText.color.b, alpha); 64 65 yield return null; 66 } 67 } 68 69 // 終わったら非表示 70 numberText.enabled = false; 71 72 // α値を戻す 73 alpha = 1; 74 75 // 次の文字へ 76 orderNumbers--; 77 78 // 2,3を表示 79 switch (orderNumbers) { 80 81 case 2: 82 StartCoroutine(StartCountThreeTime(numberText, orderNumbers)); 83 break; 84 85 case 1: 86 StartCoroutine(StartCountThreeTime(numberText, orderNumbers)); 87 break; 88 } 89 90 // コルーチンを抜ける 91 yield break; 92 93 94 95 /* 96 表示が終わったら、何かで 97 AIとPlayerに知らせて、動くようにする 98 */ 99 } 100}

やったこと

やりたいこととしましては、でかい文字から、小さい文字にして(最小値あり)透明度を低くして、消すのを
カウント式にやりたいです。大体はできたのですが、2,1 の表示が可笑しくなっています。なので処理が終わった後にα値に1を代入しているのですが、うまくいきません。どうかよろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

回答依頼ありがとうございます。

カウントダウンのアプローチについて

見た感じですが、スタート前のカウントダウンの処理でしょうか?

3、2、1、スタート!

を行うわけですね。

しかし、それをわざわざプログラムでやる必要はないと思います。
汎用性が必要であるならばまだしも、普通にカウントダウン用のアニメーションを作成し、それを再生した方が早いかと。

アニメーションにはイベント機能が備わっており、アニメーション依存で関数を呼ぶことも可能です。
試してみる価値はあるかと。

アニメーションイベントの使用

追記: カウントダウン処理

どうしてもプログラムで実装したいのであれば、仕方がありませんね…。

まず、繰り返しはforを使うといいと思います。
指定回数ループさせるのにはちょうどいい処理です。
forの中で大きさ変更、フェードアウトなどの処理を実装しましょう。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class CountdownCoroutine : MonoBehaviour 7{ 8 // レース開始の合図 9 // [SerializeField] private Text startCountNumber; 10 // private int orderNumbers = 3; 11 12 // 変数名変更しました。 13 [SerializeField] private Text counterText; 14 [SerializeField] private int startCount = 3; 15 [Space(5), Header("[ ! ] reduceTime + fadeTime + intervalTime = 1f になるように")] 16 [SerializeField, Range(0, 1)] private float reduceTime = 0.5f; // テキストの縮小に使う時間 17 [SerializeField, Range(0, 1)] private float fadeTime = 0.4f; // テキストのフェードアウトに使う時間 18 [SerializeField, Range(0, 1)] private float intervalTime = 0.1f; // 次のカウントに行くまでの待ち時間 19 20 /// <summary> 21 /// reduceTime、fadeTime、intervalTimeについて 22 /// 23 /// 処理の基本としては、 24 /// 1. テキストの大きさを縮小 25 /// 2. テキストをフェードアウト 26 /// 3. 少し待つ 27 /// の繰り返しです。 28 /// 29 /// なので、reduceTime、fadeTime、intervalTimeをすべて足して1になるようにしないと 30 /// カウントダウンが1秒ごとにならないので気を付けてください。 31 /// </summary> 32 33 void Start() { 34 // ↑せっかく変数を用意しているので、わざわざ引数を使う必要はない 35 StartCoroutine("StartCountThreeTime"); 36 } 37 38 /// <summary> 39 /// レース開始の時間を三つ数える 40 /// </summary> 41 /* private IEnumerator StartCountThreeTime(Text numberText, int displayNumbers) { 42 if (numberText == null) {// null ならばコルーチンを抜ける 43 44 yield break; 45 } 46 47 // 表示する文字 48 numberText.text = displayNumbers.ToString(); 49 50 // 大小サイズを決めておく 51 Vector3 initialSize = new Vector3(20, 20, 20); 52 Vector3 minimumSize = new Vector3(2, 2, 2); 53 54 var time = 0f; // 時間を数える 55 var countTime = 1; // 時間を指定 56 var size = 0f; // テキストのサイズ 57 var speed = 0.07f; // テキストの縮小スピード 58 59 60 numberText.enabled = true; 61 62 // 文字を小さくする 63 while (time <= countTime) { 64 65 time += Time.deltaTime; 66 numberText.transform.localScale = Vector3.Lerp(initialSize, minimumSize, size); 67 size += speed; 68 69 yield return null; 70 } 71 72 // 一応最小値をいれておく 73 numberText.transform.localScale = minimumSize; 74 75 var alpha = 1f; // α値を設定 76 77 // 文字が小さくなったならば、ゆっくり消える 78 if (numberText.transform.localScale == minimumSize) { 79 while (alpha >= 0) {// α値を減らす 80 81 alpha -= Time.deltaTime; 82 numberText.color = new Color(numberText.color.r, numberText.color.g, numberText.color.b, alpha); 83 84 yield return null; 85 } 86 } 87 88 // 終わったら非表示 89 numberText.enabled = false; 90 91 // α値を戻す 92 alpha = 1; 93 94 // 次の文字へ 95 orderNumbers--; 96 97 // 2,3を表示 98 switch (orderNumbers) { 99 100 case 2: 101 StartCoroutine(StartCountThreeTime(numberText, orderNumbers)); 102 break; 103 104 case 1: 105 StartCoroutine(StartCountThreeTime(numberText, orderNumbers)); 106 break; 107 } 108 109 // コルーチンを抜ける 110 yield break; 111 112 113 114 // 表示が終わったら、何かでAIとPlayerに知らせて、動くようにする 115 116 }*/ 117 118 private IEnumerator StartCountThreeTime() { 119 if (counterText == null) {// null ならばコルーチンを抜ける 120 yield break; 121 // エラーを想定できていていいと思います。 122 } 123 124 Debug.Log("カウントダウン開始"); 125 126 counterText.enabled = true; 127 128 // startCount分繰り返す 129 // startCountの大きさから1ずつ引いていくforで繰り返し 130 for (var currentCount = startCount; currentCount > 0; currentCount--) { 131 132 // テキスト表示を更新 133 counterText.text = currentCount.ToString(); 134 135 // 2回目のカウント以降、アルファ値が変更後そのままなので大きさを変更する前にアルファ値もリセットしておく 136 counterText.color = new Color(counterText.color.r, counterText.color.g, counterText.color.b, 1.0f); 137 138 // 大きさ変更のコルーチン 139 // yield return StartCoroutine()を使うことで、コルーチン処理が終わるまで待機できる 140 yield return StartCoroutine("ReduceInSize"); 141 142 // フェードアウトのコルーチン 143 yield return StartCoroutine("FadeOut"); 144 145 // 少しの間待待たないとすぐに次のカウントにいってしまい違和感がある 146 yield return new WaitForSecondsRealtime(intervalTime); 147 } 148 149 Debug.Log("カウントダウン終了"); 150 151 // ここでレースのスタート処理 152 Debug.Log("Go!"); 153 154 // 終わったら非表示 155 numberText.enabled = false; 156 157 // コルーチンを抜ける 158 yield break; 159 } 160 161 private IEnumerator ReduceInSize() { 162 Debug.Log("大きさ変更開始"); 163 164 // 大小サイズを決めておく 165 // x, y, z がすべて一緒なのでfloat管理でいいと思います 166 // Vector3 initialSize = new Vector3(20, 20, 20); 167 // Vector3 minimumSize = new Vector3(2, 2, 2); 168 float initialSize = 20; 169 float minimumSize = 2; 170 171 // 初期の大きさに設定 172 // Vector3.one に floatをかけて大きさを調整 173 counterText.transform.localScale = Vector3.one * initialSize; 174 175 // テキストのサイズ調整用 176 // このcurrentSizeを変動させて大きさを調整 177 float currentSize = initialSize; 178 179 // reduceTimeを直接いじると変数の値自体が変わってしまうので一時的に変数に格納 180 float tmpReduceTime = reduceTime; 181 // 文字を小さくする 182 while (currentSize > minimumSize) { 183 tmpReduceTime -= Time.deltaTime; // 時間更新(徐々に減らす) 184 currentSize = tmpReduceTime / reduceTime; // 徐々に0に近づける 185 currentSize *= initialSize; // 上の二行の処理では、currentSizeが1→0になってしまうのでinitialSize(最大値)を掛ける 186 currentSize = Mathf.Clamp(currentSize, minimumSize, initialSize); //clamp 187 188 // 大きさ変更 189 counterText.transform.localScale = Vector3.one * currentSize; // 減算したfloatをVector3.oneに掛ける 190 191 yield return null; 192 } 193 194 // 一応最小値をいれておく 195 counterText.transform.localScale = Vector3.one * minimumSize; 196 197 yield break; 198 } 199 200 private IEnumerator FadeOut() { 201 Debug.Log("フェードアウト開始"); 202 203 var alpha = 1f; // α値を設定 204 205 // fadeTimeを直接いじる訳にはいかないので一時的に変数に格納 206 float tmpFadeTime = fadeTime; 207 208 // フェードアウト 209 // α値を減らす 210 while (alpha >= 0) { 211 tmpFadeTime -= Time.deltaTime; 212 alpha = tmpFadeTime / fadeTime; 213 214 // アルファ値変更 215 Color col = counterText.color; 216 col.a = alpha; 217 counterText.color = col; 218 219 yield return null; 220 } 221 222 yield break; 223 } 224}

余談: Time.deltaTimeの使いどころ

パッとコードを見た感じ、Time.deltaTimeを使っていないように見えます。
unityのTime.deltaTimeはハードのスペック差を埋める大切なものです。

例えば、1秒間に120回ゲームを更新できるハイスペックPCと、1秒間に10回しかゲームを更新できないロースペックPCがあるとします。
その2台のPCで以下の処理を行うとします。

C#

1void Update () { 2 transform.position += Vector3.up; 3}

ハイスペックPCだとUpdate()が1秒間に120回呼ばれますが、ロースペックPCだとUpdate()は1秒間に10回しか呼ばれません…。
そうなると、実行結果にスペック差によるズレが生じてしまいます。
これを埋めるために、

C#

1void Update () { 2 transform.position += Vector3.up * Time.deltaTime; 3}

というようにしてスペック差によるズレを抑えています。
なので、簡潔に言うと、スペック差でズレて欲しくないものにはTime.deltaTimeを掛けると良いかもしれません。

まぁ、詳細は調べていただいて…。

投稿2021/01/08 09:38

編集2021/01/09 03:54
PinoMatcha

総合スコア368

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

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

Um_kok

2021/01/08 09:52

回答ありがとうございます。 確かにUIのアニメーションのアニメーションを作ったほうが好ましいし、楽なのかもしれませんね。 ですが、せっかく教えてもらったのに申し訳ないのですが、貴方様がよろしければ、私はコードで書きたいです。何故ならば、私はコードの理解が曖昧です。なので、コードをきっちり理解したいです。最近コルーチンを使い始めたのですが、すごく便利で使っていて面白いので、もっと理解を深めたいと思っております。あと、今その解決方法がわかれば、今後のプログラムにも活かせるし、原因が分からなくて、もやもやしてしまいます。どうか宜しければ、コードで教えてもらえないでしょうか?どうかお願いします。
PinoMatcha

2021/01/08 15:31

回答に追記しました。
Um_kok

2021/01/09 07:12

お返事遅れました。オンライン授業があったため、遅れました、、、 コードありがとうございます。大変見やすかったです。 Spaceアトリビュートは使ったことなかったので、今後は使ってみようと思います。 yield return StartCoroutine なんてのもあるんですね。勉強になりました。 すこし難しかったところを理解を深めるため質問させていただきます。 ReduceInSize() のwhileの中身の currentSize = tmpReduceTime / reduceTime; currentSize *= initialSize; が何をやっているのかが余り良く分かりませんでした。なぜreduceTime で割ったり、initialSize で掛けたりしているのかを教えてもらいたいです。 あと、StartCountThreeTime() の yield return new WaitForSecondsRealtime(intervalTime); は何故、WaitForSecondsRealtime 何でしょうか?  調べさせてもらったのですが、スケール化されてない時間、コルーチンを一時停止する、と書いてありましたが、良くわかりませんでしたWaitForSeconds は使ったことがあるのですが、何が違うのでしょうか?
PinoMatcha

2021/01/09 08:46

【currentSizeの処理について】 float tmpReduceTime = reduceTime; で、時間を所持する一時的な変数を用意しています。 そしてそれを徐々に減らしていくのが tmpReduceTime -= Time.deltaTime; の処理です。 tmpReduceTime / reduceTimeは、最大値から徐々に減るtmpReduceTimeを最大値(reduceTime)で割ることで、1から0で『割合』を求めています。 それをcurrentSizeに格納しています。 しかしcurrentSizeをそのまま使うと、次のClamp処理で0でも1でも引っ掛かり、強制的に最小値の2になってしまいます。 すなわち、大きさ変更の処理が終わってしまうため0~1の割合であるcurrentSizeに文字の最大値を掛けることで0~20に変換しています。 それをテキストの大きさとして使っているのです。 【WaitForSecondsRealtimeについて】 unityでは、Time.timeScaleをいじることでゲーム時間を変更することができます。 Time.timeScale = 0.1f; と記述するとスローモーションを表現できたりするわけです。 そのTime.timeScaleの時間の流れの変更に影響されないのが、 WaitForSecondsRealtimeです。 なのでまぁ正直、Time.timeScaleをいじらないのであればどっちでも大丈夫です。
Um_kok

2021/01/09 09:51 編集

分かりやすい説明ありがとうございます。 私の解釈だと、、 つまり、(最大値 ー 値) / 最大値 = 割合 ということで 割合は 0~1の間、 0~1の間だと、clamp で2が返ってくるため それじゃまずいので、文字のスケール初期値(最大値)をかけてやって  0~20にして、そのままテキストの大きさに代入できる形にしている。 WaitForSecondsRealtime は Time.timeScale をいじることで、ゲーム内の時間の流れを調整できる(Time.timeScale=0)ならば時間が止まる。 ということですね! こんな私に、すごく丁寧なご説明ありがとうございます。 PinoMatchaさんのおかげで理解することができました!ありがとうございます。 Time.deltaTime なども調べてみます。 本当にありがとうございました。また、調べて,そのあと試行錯誤して分からなかったこと、困った事があったときに 頼らせてもらいます。ありがとうございました。
PinoMatcha

2021/01/09 10:43

解決できたようで何よりです。 ただ、『解決済み』へ変更をお願いします……。
Um_kok

2021/01/09 12:25 編集

ベストアンサーにしました。すみません。忘れていました。 何故か、ネット環境が悪かったのか、できておりませんでした。 解決してくださってありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問