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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Unity3D

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

Unity

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

Q&A

解決済

2回答

1329閲覧

RPGの流れるテキスト表示のエラー

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2021/10/22 10:55

編集2021/10/26 13:07

unityで、流れるテキスト表示をしたいと思っています。
とりあえずこのサイトを参考にしました。
参考にしたサイト

で、呼び出す側に問題があったので、そのスクリプトも書いておきます。
どういうことを実現したいかというと、建造物(タグ house)に触れたかつzキーが押された時に、文字を表示するというものです。文字を表示している最中でzキーが押される場合を想定して、キーが押されたのを検知した瞬間、コライダーがオフになるようにしてあります。
しかし、メッセージ"こおりでできたいえだ。"を3回表示した後、"おや?かゆいところがあるようだ"を表示するまで、文字が一文字ずつ出ず、いっぺんに表示されてしまいます。
メッセージ関数が何回も呼び出されてしまっているからかと思いましたが、
それらしい部分は見当たりませんでした。

どうしたらいいですか?

スクリプト メッセージ

using UnityEngine; using System.Collections; using UnityEngine.UI; using System.Text.RegularExpressions; public class Message : MonoBehaviour { // メッセージUI private Text messageText; // 表示するメッセージ [SerializeField] [TextArea(1, 20)] private string allMessage; // 使用する分割文字列 [SerializeField] private string splitString = "<>"; // 分割したメッセージ private string[] splitMessage; // 分割したメッセージの何番目か private int messageNum; // テキストスピード [SerializeField] private float textSpeed = 0.05f; // 経過時間 private float elapsedTime = 0f; // 今見ている文字番号 private int nowTextNum = 0; // マウスクリックを促すアイコン private Image clickIcon; // クリックアイコンの点滅秒数 [SerializeField] private float clickFlashTime = 0.2f; // 1回分のメッセージを表示したかどうか private bool isOneMessage = false; // メッセージをすべて表示したかどうか private bool isEndMessage = false; void Start() { clickIcon = transform.Find("Panel/Image").GetComponent<Image>(); clickIcon.enabled = false; messageText = GetComponentInChildren<Text>(); messageText.text = ""; } void Update() { // メッセージが終わっているか、メッセージがない場合はこれ以降何もしない if (isEndMessage || allMessage == null) { return; } // 1回に表示するメッセージを表示していない if (!isOneMessage) { // テキスト表示時間を経過したらメッセージを追加 if (elapsedTime >= textSpeed) { messageText.text += splitMessage[messageNum][nowTextNum]; nowTextNum++; elapsedTime = 0f; // メッセージを全部表示、または行数が最大数表示された if (nowTextNum >= splitMessage[messageNum].Length) { isOneMessage = true; } } elapsedTime += Time.deltaTime; // メッセージ表示中にマウスの左ボタンを押したら一括表示 if (Input.GetKeyDown(KeyCode.Z) { // ここまでに表示しているテキストに残りのメッセージを足す messageText.text += splitMessage[messageNum].Substring(nowTextNum); isOneMessage = true; } // 1回に表示するメッセージを表示した } else { elapsedTime += Time.deltaTime; // クリックアイコンを点滅する時間を超えた時、反転させる if (elapsedTime >= clickFlashTime) { clickIcon.enabled = !clickIcon.enabled; elapsedTime = 0f; } // マウスクリックされたら次の文字表示処理 if (Input.GetKeyDown(KeyCode.Z){ nowTextNum = 0; messageNum++; messageText.text = ""; clickIcon.enabled = false; elapsedTime = 0f; isOneMessage = false; // メッセージが全部表示されていたらゲームオブジェクト自体の削除 if (messageNum >= splitMessage.Length) { isEndMessage = true; transform.GetChild(0).gameObject.SetActive(false); } } } } // 新しいメッセージを設定 void SetMessage(string message) { this.allMessage = message; // 分割文字列で一回に表示するメッセージを分割する splitMessage = Regex.Split(allMessage, @"\s*" + splitString + @"\s*", RegexOptions.IgnorePatternWhitespace); nowTextNum = 0; messageNum = 0; messageText.text = ""; isOneMessage = false; isEndMessage = false; } // 他のスクリプトから新しいメッセージを設定しUIをアクティブにする public void SetMessagePanel(string message) { SetMessage(message); transform.GetChild(0).gameObject.SetActive(true); } }

スクリプト 呼び出す側

using System.Collections; using System.Collections.Generic; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { const float value = 0.1f; bool moving = true; public float speed = 6.0F; //歩行速度 public float jumpSpeed = 8.0F; //ジャンプ力 public float gravity = 20.0F; //重力の大きさ public float rotateSpeed = 3.0F; //回転速度 private float mX, mY; private CharacterController controller; private Vector3 moveDirection = Vector3.zero; private float h,v; Animator animator; public AudioClip footsteps; protected AudioSource audioSource; [SerializeField] AudioClip[] clips; [SerializeField] bool randomizePitch = true; [SerializeField] float pitchRange = 0.1f; int coliderchecker = 0; public bool flag = false; bool atatta = false; [SerializeField] private Message messageScript; int housetime; public int icegold = 0; // Use this for initialization void Start () { controller = GetComponent<CharacterController>(); animator = GetComponent<Animator>(); audioSource = GetComponents<AudioSource>()[0]; } // Update is called once per frame void Update () { if(moving == true) { h = Input.GetAxis ("Horizontal"); v = Input.GetAxis ("Vertical"); } moveDirection = new Vector3 (h, 0, v); //moveDirection = transform.TransformDirection(moveDirection); moveDirection *= speed * 3.0f; moveDirection.y -= gravity * Time.deltaTime; controller.Move(moveDirection * Time.deltaTime); if (Input.GetKeyDown(KeyCode.Z)) { if(flag == true) { } if(flag == false) { GetComponent<BoxCollider>().enabled = true; if(coliderchecker == 1) { housetime++; flag = true; if(housetime < 4) { messageScript.SetMessagePanel ("こおりでできたいえだ"); } if(housetime == 4) { messageScript.SetMessagePanel ("おや?かゆいところがあるようだ。"); } if(housetime == 5) { messageScript.SetMessagePanel ("かゆいところをかいてあげた・・・<>いえは よろこんでいるみたいだ。\nいえは おれいに アイスゴールドを 20こ くれた!"); icegold =+ 20; } GetComponent<BoxCollider>().enabled = false; } } } } void OnCollisionStay(Collision collision) { atatta = true; } void OnTriggerEnter(Collider other) { if (other.gameObject.tag == "house") { coliderchecker = 1; } else if (other.gameObject.tag == "store") { coliderchecker = 2; } } void OnTriggerExit(Collider other) { coliderchecker = 0; } void OnCollisionExit(Collision collision) { atatta = false; } }

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/10/22 11:17

何はともあれ、コードは ``` と ``` で囲ってください(``` はバッククォート 3 つ)。
y_waiwai

2021/10/22 11:40

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
退会済みユーザー

退会済みユーザー

2021/10/22 13:14

できました!すみません。。
mimi_no_naka

2021/10/24 14:29 編集

エラーが出ているのがこのコードでは無いのであれば質問文を編集してその部分を記載して下さい 他の人の回答でのやり取りを拝見する限り現状真面目に問題解決しようとしている態度に思えません YOshimさんの回答でのコメントで「呼び出す側にも~」とエラー箇所が複数あるように見受けられますが複数個所あるならばその旨の記載もして下さい
guest

回答2

0

ベストアンサー

YOshimさんとの会話を見るに
ActiveMessagePanelクラスのmessageScriptがNullの為、参照エラーが発生しているのが原因かと思います。

・確認手順
呼び出す側のActiveMessagePanelがアタッチされているオブジェクトを選択してInspectorから画像部分がNoneになっていないか確認して下さい。
イメージ説明

・解決手順
Messageがアタッチされているオブジェクトをドラッグ&ドロップしてNoneを解消して下さい。

・追記

質問の内容が変更されているので追記します。

しかし、メッセージ"こおりでできたいえだ。"を3回表示した後、"おや?かゆいところがあるようだ"を表示するまで、文字が一文字ずつ出ず、いっぺんに表示されてしまいます。

・原因
「メッセージの呼び出し」と「文字送り」をInput.GetKeyDown(KeyCode.Z)の同キーでおこなっている為です。

・解決手順
「別キーを使う」若しくは「フラグ管理で初回の一回目は文字送りを発生させない」ようにして下さい。

・追記2

「フラグ管理で初回の一回目は文字送りを発生させない」に関しての修正点。

・フィールドにprivate bool isDoingMessageを追加。
// メッセージ表示中に~から// 1回に表示する~の間部分を下記の様に書き換える。

抜き出して説明するとミスすると思うので全文コピペして使い、
問題無ければ上記二つの部分の内容理解して下さい。

C#

1using UnityEngine; 2using System.Collections; 3using UnityEngine.UI; 4using System.Text.RegularExpressions; 5 6public class Message : MonoBehaviour 7{ 8 9 // メッセージUI 10 private Text messageText; 11 // 表示するメッセージ 12 [SerializeField] 13 [TextArea(1, 20)] 14 private string allMessage; 15 16 // 使用する分割文字列 17 [SerializeField] 18 private string splitString = "<>"; 19 // 分割したメッセージ 20 private string[] splitMessage; 21 // 分割したメッセージの何番目か 22 private int messageNum; 23 // テキストスピード 24 [SerializeField] 25 private float textSpeed = 0.05f; 26 // 経過時間 27 private float elapsedTime = 0f; 28 // 今見ている文字番号 29 private int nowTextNum = 0; 30 // マウスクリックを促すアイコン 31 private Image clickIcon; 32 // クリックアイコンの点滅秒数 33 [SerializeField] 34 private float clickFlashTime = 0.2f; 35 // 1回分のメッセージを表示したかどうか 36 private bool isOneMessage = false; 37 // メッセージをすべて表示したかどうか 38 private bool isEndMessage = false; 39 // メッセージ表示中かどうか 40 private bool isDoingMessage = false; 41 42 void Start() 43 { 44 clickIcon = transform.Find( "Panel/Image" ).GetComponent<Image>(); 45 clickIcon.enabled = false; 46 messageText = GetComponentInChildren<Text>(); 47 messageText.text = ""; 48 49 } 50 51 void Update() 52 { 53 // メッセージが終わっているか、メッセージがない場合はこれ以降何もしない 54 if( isEndMessage || allMessage == null ) 55 { 56 return; 57 } 58 59 // 1回に表示するメッセージを表示していない 60 if( !isOneMessage && splitMessage != null ) 61 { 62 // テキスト表示時間を経過したらメッセージを追加 63 if( elapsedTime >= textSpeed ) 64 { 65 messageText.text += splitMessage[ messageNum ][ nowTextNum ]; 66 67 nowTextNum++; 68 elapsedTime = 0f; 69 70 // メッセージを全部表示、または行数が最大数表示された 71 if( nowTextNum >= splitMessage[ messageNum ].Length ) 72 { 73 isOneMessage = true; 74 } 75 } 76 elapsedTime += Time.deltaTime; 77 78 // メッセージ表示中にマウスの左ボタンを押したら一括表示 79 if( Input.GetKeyDown( KeyCode.Z ) && isDoingMessage) { 80 // ここまでに表示しているテキストに残りのメッセージを足す 81 messageText.text += splitMessage[ messageNum ].Substring( nowTextNum ); 82 isOneMessage = true; 83 isDoingMessage = false; 84 } 85 isDoingMessage = true; 86 87 // 1回に表示するメッセージを表示した 88 } 89 else 90 { 91 92 elapsedTime += Time.deltaTime; 93 94 // クリックアイコンを点滅する時間を超えた時、反転させる 95 if( elapsedTime >= clickFlashTime ) 96 { 97 clickIcon.enabled = !clickIcon.enabled; 98 elapsedTime = 0f; 99 } 100 101 // マウスクリックされたら次の文字表示処理 102 if( Input.GetKeyDown( KeyCode.Z )){ 103 nowTextNum = 0; 104 messageNum++; 105 messageText.text = ""; 106 clickIcon.enabled = false; 107 elapsedTime = 0f; 108 isOneMessage = false; 109 110 // メッセージが全部表示されていたらゲームオブジェクト自体の削除 111 if( splitMessage != null && messageNum >= splitMessage.Length ) 112 { 113 isEndMessage = true; 114 transform.GetChild( 0 ).gameObject.SetActive( false ); 115 } 116 } 117 } 118 } 119 // 新しいメッセージを設定 120 void SetMessage( string message ) 121 { 122 this.allMessage = message; 123 // 分割文字列で一回に表示するメッセージを分割する 124 splitMessage = Regex.Split( allMessage, @"\s*" + splitString + @"\s*", RegexOptions.IgnorePatternWhitespace ); 125 nowTextNum = 0; 126 messageNum = 0; 127 messageText.text = ""; 128 isOneMessage = false; 129 isEndMessage = false; 130 isDoingMessage = false; 131 } 132 // 他のスクリプトから新しいメッセージを設定しUIをアクティブにする 133 public void SetMessagePanel( string message ) 134 { 135 SetMessage( message ); 136 transform.GetChild( 0 ).gameObject.SetActive( true ); 137 } 138}

投稿2021/10/23 14:26

編集2021/10/30 11:55
Hawn

総合スコア1222

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

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

退会済みユーザー

退会済みユーザー

2021/10/24 10:49

ちゃんと動いていますが、エラーのログが出続けていて、重くなっています。
Hawn

2021/10/24 13:55 編集

文章で表現するのが難しいのかもしれないですが「ちゃんと動いている」とはどういう状態でしょうか? エンジニアの感性だとエラーが出ている時点でちゃんと動いているとは言えません。 画像の部分は参照出来ているのか、エラーの詳細、デバッグはどこまでやってその状態なのかなど詳細にお願いします。 それとエラーは質問文に書いてあるスクリプトで発生しているのでしょうか? 別スクリプトで出ているエラーであるならばそのコードも記載するようお願いします。
Hawn

2021/10/24 18:23 編集

質問内容に含まれていないので答えなかったのですが、 「エラーのログが出続けていて」を予測で答えるとsplitMessageがNullの時にエラーが発生する為、 58行目 if( !isOneMessage ) ↓ if( !isOneMessage && splitMessage != null ) と修正しておくと発生しないのではないでしょうか。 そもそも提示してあるコードは77,97行目のifが閉じられていないのでコンパイルエラーで動かないですけどそこは修正済みなのでしょうか?
退会済みユーザー

退会済みユーザー

2021/10/26 10:24

修正済みです。ログは出なくなりました!ということは、呼び出す側に問題があるようなので、修正します。
退会済みユーザー

退会済みユーザー

2021/10/26 10:24

(質問を)
退会済みユーザー

退会済みユーザー

2021/10/28 07:54

すみません!自分が無能なので、、、 //『フラグ管理で初回の一回目は文字送りを発生させない』 どう記述すればいいですか?
Hawn

2021/10/28 11:55 編集

isOneMessageやisEndMessageとやり方は同じです。 bool変数を一つ追加して記述して下さい。 個人的にはフラグは乱雑になるのでStateパターンで作り直して貰った方が良いですが、 今時点では無理そうなのでフラグでやって下さい。
退会済みユーザー

退会済みユーザー

2021/10/30 04:05

92行目に、(マウスクリックされたら次の文字表示処理)zキーを押すのとフラグ変数がfalseの時にifを実行するようにしました。フラグ変数は呼び出す側のスクリプトで、変数 housetime が1の時にフラグ変数をtrueにし、2以上ならfalseというふうにしましたが、1回目の”こおりでできたいえだ”のところで、次に進めなくなっています。どうしたらいいですか? できれば、どこをどんなふうに書き直せばいいか、教えてください。
Hawn

2021/10/30 10:44 編集

ちょっと見当違いな所をやってしまっている様なのでまずはコードの内容を全て理解するところから始めた方が良いかと思います。 場当たり的にやっているとエンドレスで躓きます。 今回だけ追記2に記載しました。
退会済みユーザー

退会済みユーザー

2021/11/03 10:02

できました! ありがとうございます!
退会済みユーザー

退会済みユーザー

2021/11/04 10:39

すみません!質問です。 playoneshotでテキストの文字が出た時ごとに音を鳴らしたいのですが、どこにplayoneshotをいれたらいいですか?
Hawn

2021/11/04 11:34

messageText.text += splitMessage[messageNum][nowTextNum]; // この辺り nowTextNum++; 上記箇所で良いのではないでしょうか
退会済みユーザー

退会済みユーザー

2021/11/07 07:51

ここここここここここここここここここ・・・・・と出てきました。 あと、Object reference not set to an instance of an object がでています。
guest

0

しかし、55行目でエラーが出ます。内容は

Object reference not set to an instance of an object
です。他のオブジェクトから、スクリプト側の関数を呼び出した時に出ます。

コードを確認したところ、55行目は// テキスト表示時間を経過したらメッセージを追加でしたので、恐らくエラーが出ているのは他のコードかと思います。そちらのコードの該当箇所を修正する必要があります。

投稿2021/10/23 01:11

YOshim

総合スコア1085

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

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

退会済みユーザー

退会済みユーザー

2021/10/23 04:11

messageScript.SetMessagePanel (“はろうわアルド”); というふうに記述しました。 直接文字列を代入しています
YOshim

2021/10/23 04:12

エラーが出ているのは記載のスクリプトで間違いないでしょうか。
退会済みユーザー

退会済みユーザー

2021/10/23 04:50

あ、呼び出す側にもエラーが出てますね。さっきの記述のとこで。(はろうわあるどのやつ)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問