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

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

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

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

UI

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

Unity

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

Q&A

解決済

1回答

631閲覧

マップ移動時のマップ名の切り替えについて

BRAK

総合スコア98

C#

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

UI

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

Unity

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

0グッド

0クリップ

投稿2020/02/12 14:29

編集2020/02/13 01:39

マップを移動したときにマップ名を出すようにスクリプトを書きました。
違うマップに移動したときにUIを表示し、また、別のマップに移動したら同じく起動させます。4秒で消えるようにしているのですが、UIが表示され3秒後に別のマップに移動したらマップ名が残り1秒しか表示されないのですが何かいい方法はありませんか

c#

1 2``C# 3 4 public GameObject text; 5 public Text placeText; 6 public bool Enter; 7 public string placeName; 8private void OnTriggerEnter2D(Collider2D col) 9 { 10 if(col.tag == "Player") 11 { 12 if (Enter == true) 13 { 14 StartCoroutine(PlaceNameCo()); 15 } 16 } 17 } 18 private IEnumerator PlaceNameCo() 19 { 20 text.SetActive(true); 21 placeText.text = placeName; 22 yield return new WaitForSeconds(4f); 23 text.SetActive(false); 24 } 25

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

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

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

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

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

nskydiving

2020/02/12 19:36

<code>タグが適用されておらず、コードのレイアウトが崩れてしまっています。(改行が必要です) このままでは回答が付きづらいですので、修正してください。 ```C# // ここにコードを書いてください。 ```
guest

回答1

0

ベストアンサー

コルーチンが起動中ならStopCoroutineで止めてからStartCoroutineしてはどうでしょう?

追記

動作させたわけではないので、下記スクリプトが正常に動作しないかもしれませんが、こんな感じでしょうか。

スクリプトがどのようなオブジェクトにアタッチされているのか分からないので、適切なのか判断できませんが、とりあえず「マップから出た」というのを「OnTriggerExit2D」で判断できるものとしています。

C#

1 2 public GameObject text; 3 public Text placeText; 4 public bool Enter; 5 public string placeName; 6 7 Coroutine co; 8 9 private void OnTriggerEnter2D(Collider2D col) 10 { 11 if(col.tag == "Player") 12 { 13 if (Enter == true) 14 { 15 co = StartCoroutine(PlaceNameCo()); 16 } 17 } 18 } 19 private void OnTriggerExit2D(Collider2D col) 20 { 21 if(col.tag == "Player") 22 { 23 if (Enter == true) //Enterが何を示すのもなのか分からなかったのでそのままにしてあります。 24 { 25 if (co != null) 26 { 27 StopCoroutine(co); 28 co = null; 29 } 30 } 31 } 32 } 33 34 private IEnumerator PlaceNameCo() 35 { 36 text.SetActive(true); 37 placeText.text = placeName; 38 yield return new WaitForSeconds(4f); 39 text.SetActive(false); 40 co = null; 41 }

また別の案ですが、コルーチンの起動に関しては今まで通りとしてコルーチンにて

C#

1 private IEnumerator PlaceNameCo() 2 { 3 text.SetActive(true); 4 placeText.text = placeName; 5 if(int i = 0;i < 40 ; i++) 6 { 7 yield return new WaitForSeconds(0.1f); 8 if (placeText.text != placeName) 9 { 10 yield break; 11 } 12 } 13 text.SetActive(false); 14 co = null; 15 }

といった感じでWaitするのを短時間でループするようにして、テキストが自分のマップ名ではなくなったらコルーチンを終了するようにすればどうでしょう?

ただ、私もUnityはほぼ知らないと言っていいので、もっと適切な書き方があるのではないかと思います。

投稿2020/02/13 03:36

編集2020/02/25 08:28
YAmaGNZ

総合スコア10258

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

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

BRAK

2020/02/13 04:14

private void OnTriggerEnter2D(Collider2D col) { if(col.tag == "Player") { if (Enter == true) { StopCoroutine(PlaceNameCo()); ★ StartCoroutine(PlaceNameCo()); } } } これでStartCoroutineの中身を数秒遅らせて試してみましたが同じ結果でした。
YAmaGNZ

2020/02/13 04:18

StopCoroutineについて調べると分かると思いますが、その書き方ですとコルーチンは停止しません。 StartCoroutineの戻り値がCoroutineなので、それを渡すようにしてください。
BRAK

2020/02/13 07:21

if (Enter== true) { Coroutine coroutine = StartCoroutine(PlaceNameCo()); StartCoroutine(StopWait(coroutine)); StartCoroutine(PlaceNameCo()); } private IEnumerator StopWait(Coroutine coroutine) { yield return new WaitForSeconds(0.1f); StopCoroutine(coroutine); } で書き直してみたのですがだめみたいです。
YAmaGNZ

2020/02/13 07:38

何か勘違いされているようです。 StopCoroutineで検索されることをお勧めします。
BRAK

2020/02/13 16:51

上ので動かなかったのであの後、別のサイト見ながらスクリプトを作ったんですが、うまくいかなかったんです。 それがこれです。 IEnumerator routine; void Start(){ routine = PlaceNameCo(); } private void OnTriggerEnter2D(Collider2D col) { if(col.tag == "Player") { if (Enter== true) { StopCoroutine(PlaceNameCo()); routine = null; routine = PlaceNameCo(); StartCoroutine(PlaceNameCo()); } }
YAmaGNZ

2020/02/13 22:41 編集

Coroutine co; を適切な場所で定義しておいて コルーチン開始時は if(co!=null) { StopCoroutine(co); } co = StartCoroutine(PlaceNameCo()); それで、コルーチン側で処理終了時にcoをnullにすればいいかと
BRAK

2020/02/14 03:58

ありがとうございます。 昨日サイトを見て作ったやつも、今教えていただいたやつも恐らく起動しているのですが新たな欠陥があってうまくいかないようでした。 マップが切り替わる際に、スクリプトを同じものを使っているせいでスクリプト内で最初に4秒経過してtext.SetActive(false);があとのものに影響して4秒より先に消えてしまうように感じます。デバックでも見たのですが恐らくそうです。 また、StopCoroutineのタイミングも別のマップに入ったタイミングで行われず同じマップに入ったタイミングで処理が実行されます。
YAmaGNZ

2020/02/14 04:41

すみません、提示部分はどのマップに入った時でも動作するものだと思っていました。 マップ1に入った時に動くスクリプトとマップ2に入った時に動くスクリプトが同一(インスタンス含めて)ではないということですか? そうなのであれば、先ほど提示したようなStartCoroutineを実行するときにコルーチンが動いたいたらStopCoroutineするのではなく、マップから出たらStopCoroutineだけを行うとかできませんかね?
BRAK

2020/02/14 16:16

すみません。スクリプトは同一で、表示するテキストも同じにしているため処理が同一になって初めの処理があとの同じテキストにかかって4秒以下で消えるっていうことなのかもしれないです。。 マップから出てStopCoroutineにしたら、スクリプトが同一なので新しいマップ名でずっと止まります。 また実験で異なるText(マップ1をText1とマップ2をText2)にしてマップに入って if(co!=null) { StopCoroutine(co); SetActive(false) } にするというのをやってみたのですが、下に重なる形で失敗しました。 改めてスクリプトは同一のものを使っています。
YAmaGNZ

2020/02/14 23:10

1.マップ1に入った時にコルーチンを開始coに格納(これをco1とします) 2.マップ2に入った時に参照するco(これをco2とします) 現象を聞いているとco1とco2が別物となっているのではないかと思われます。 別物だから、co1にコルーチンが格納されていてもco2はnullのままになっているのではないでしょうか? マップ1に再度入った時にco1にコルーチンが入っているからtopCoroutineが動くとなっている気がします。 スクリプトが同一というのは、スクリプトのソースが同じだけで、別のオブジェクトにそれぞれアタッチされていたりしませんか? その場合、ソースが同じでも別インスタンスとなりますので、メンバ変数等もstatic宣言していないかぎりは別物となります。 また、マップから出たタイミングでStopCoroutineする場合は マップ1→マップ2→マップ1と移動した場合は 1.マップ1に入る(コルーチン開始) 2.マップ1から出る(コルーチンが動いていれば停止) 3.マップ2に入る(コルーチン開始) 4.マップ2から出る(コルーチンが動いていれば停止) 5.マップ1に入る(コルーチン開始) と動作すると思うのですが、このような動きはしませんか?
BRAK

2020/02/15 02:15

スクリプトは別オブジェクトに付けています。 はい、この動きをしています。 メンバを含めてstatic宣言で実行すれば理想通りの動きが出来るということですか?
YAmaGNZ

2020/02/15 23:36 編集

いまいちスクリプトやTextのオブジェクトが完全に同一の物なのか分からないのでstatic宣言してうまくいくかは分かりません。 一度、object.GetInstanceID(https://docs.unity3d.com/ja/current/ScriptReference/Object.GetInstanceID.html)で本当に同じものなのか確認してみてはどうでしょうか?同じものなのであればGetInstanceIDは同じ値を返すはずです。 Debug.Log(GetInstanceID()); とすればスクリプトのIDがログとして出力されます。 Debug.Log(text.GetInstanceID()); とすればTextのIDが出力されますので、確認してみてください。 これが、例えばマップ1での操作を行っている時は同じ値だが、マップ2での操作を行っている時は違う値が返ってくるとなれば、マップ1で扱っているものとマップ2で扱っているものは別物になります。 こうなると、マップ1に入った時にStartCoroutineして出るときにStopCoroutineするという形がいいのではないかと思います。 動いているスクリプトが同一のものなのか、別の物なのか判断してみてください。 (ここで言う”同一のもの”とはインスタンスIDが同一の物です)
BRAK

2020/02/16 02:57

ありがとうございます。 1度確認してみます。
BRAK

2020/02/25 06:50

すみません。先週はバイトとこれから通う学校のチーム制作の発表がありこっちに手が回らなく回答できませんでした。 今、試してみたところテキストは同じIDだったのですが、スクリプトのインスタンスIDが全く別物だとわかりました。 また、コルーチンをstaticで宣言するとマップ2から1へ移行するときにコルーチンの存続に失敗(エラー名Coroutine continue failure)して理想通りの結果にすることはできました。 これはマップ1のコルーチン内のtext.SetActive(false);がなくなったため マップ2でのコルーチンを重複させることができました。 本来だとマップ1のコルーチン内のtext.SetActive(false);がマップ2のテキストに影響を与える形になっています。
BRAK

2020/02/25 07:15

それと、>>マップ1に入った時にStartCoroutineして出るときにStopCoroutineするという形がいいのではないかと思います。 に関してなのですが、Enterをfalseにするなどしてみたのですが、できなくていまいちよくわからなかったので教えていただけると助かります。
BRAK

2020/02/25 08:44

ありがとうございます。 後で試してみたいと思います。 ちなみにEnterはplayerのtagに触れていたら、もし、trueなら今ではコルーチンをスタートさせるというのを意味しています。
BRAK

2020/02/26 04:11

今、試してみたところ少し変えて無事成功しました。 テキストが自分の名前ではなかったらというスクリプトがかなりよく働いてくれてうまくいきました。 最後までいろいろありがとうございます。
BRAK

2020/02/26 04:15 編集

```C# private void OnTriggerEnter2D(Collider2D col) { if (col.tag == "Player") { if (co != null) { StopCoroutine(co); co = null; } } } private void OnTriggerExit2D(Collider2D col) { if(col.tag == "Player") { if(Enter == true) { co = StartCoroutine(PlaceNameCo()); } } } private IEnumerator PlaceNameCo() { text.SetActive(true); placeText.text = placeName; for (int i = 0; i < 40; i++) { yield return new WaitForSeconds(0.1f); if (placeText.text != placeName) { yield break; } } text.SetActive(false); co = null; } ``` 入る時と出る時はほぼ同時なので、出る時にStopしてしまうと動かなくなってしまうので出るときにStartさせました。
YAmaGNZ

2020/02/26 04:28

マップ名が異なる時にコルーチンを停止させるというのは、StopCoroutineの変わりにコルーチンを停止させるということなので、StopCoroutineの部分は必要ありません。 多分、質問に載せているコードでうまく動くと思います。
BRAK

2020/02/27 11:00

あ、本当ですね。見やすく書き換え直します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問