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

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

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

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

Q&A

解決済

2回答

3046閲覧

Unity2Dで、OntriggerStay2Dの中にあるtrueをfalseに戻したいです。

YuzuTf

総合スコア12

C#

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

0グッド

0クリップ

投稿2016/06/29 06:23

編集2016/06/29 06:26

###前提・実現したいこと
イメージ説明
上の画像の青いブロックとオレンジ色のブロックが接触した際、
青いブロックではHitというフラグがtrueになるプログラムが入っています。
また、青いブロックすべてのフラグがtrueになった際、
下の画像の緑色の枠に接触しているオレンジ色のブロックを消し、
ブロックが消えた場合にはHitの判定をTrueからfalseに戻すというプログラムを組もうとしています。
イメージ説明

###発生している問題・エラーメッセージ
void ontriggerstay2Dで判定を取り、
Trueとfalseを判断しているのですが、ブロックをDestroyで消した際、falseになりません。
void ontriggerExitを入れてみても、そこまでコードが通りませんでした。

###該当のソースコード
こちらが青色のブロックにアタッチしているコードです。
各青色のブロックにはそれぞれ、Hit01~Hit06の数字が入っています。

C#

1using UnityEngine; 2using System.Collections; 3 4public class Destroy01 : MonoBehaviour 5{ 6 7 //public static bool Hit01; //ヒットフラグ 8 public bool Hit01; 9 10 // Use this for initialization 11 void Start() 12 { 13 Hit01 = false; 14 } 15 16 // Update is called once per frame 17 void Update() 18 { 19 } 20 //ブロックと接触時に呼ばれる 21 void OnTriggerStay2D(Collider2D other) 22 { 23 Hit01 = true; 24 } 25 //ブロックが離れる際に呼ばれる 26 void OnTriggerExit2D(Collider2D other) 27 { 28 Hit01 = false; 29 } 30 31 32}

こちらが緑色の枠にアタッチしているコードです。
緑色の枠はCreateEmptyで作成したGameObjectに
Add componentでBoxCollider2Dを作成し、
横長に引き伸ばしたもので作成しました。
is Triggerですり抜けるように設定し、当たり判定をとっています。

C#

1using UnityEngine; 2using System.Collections; 3 4public class Delete : MonoBehaviour 5{ 6 7 public bool ALL_OK; 8 9 // Use this for initialization 10 void Start() 11 { 12 13 } 14 15 // Update is called once per frame 16 void Update() 17 { 18 19 20 GameObject obj1 = GameObject.Find("Cube_00"); 21 GameObject obj2 = GameObject.Find("Cube_01"); 22 GameObject obj3 = GameObject.Find("Cube_02"); 23 GameObject obj4 = GameObject.Find("Cube_03"); 24 GameObject obj5 = GameObject.Find("Cube_04"); 25 GameObject obj6 = GameObject.Find("Cube_05"); 26 27 Destroy01 d1 = obj1.GetComponent<Destroy01>(); 28 Destroy02 d2 = obj2.GetComponent<Destroy02>(); 29 Destroy03 d3 = obj3.GetComponent<Destroy03>(); 30 Destroy04 d4 = obj4.GetComponent<Destroy04>(); 31 Destroy05 d5 = obj5.GetComponent<Destroy05>(); 32 Destroy06 d6 = obj6.GetComponent<Destroy06>(); 33 34 if (d1.Hit01 == true && d2.Hit02 == true && d3.Hit03 == true && 35 d4.Hit04 == true && d5.Hit05 == true && d6.Hit06 == true) 36 { 37 ALL_OK = true; 38 } 39 40 41 } 42 43 44 void OnTriggerStay2D(Collider2D other) 45 { 46 while (ALL_OK == true) 47 { 48 Destroy(other.gameObject); 49 } 50 } 51}

###試したこと
breakをif文の処理に入れてみたり、Destroyの後にALL_OKフラグをfalseに変えてみたり、
ifをwhileに変えてみたりしましたが、効果はありませんでした。
また、void ontriggerEnit2Dで処理を抜けようとしましたが、抜けられませんでした。VSTUで確認したところ、ずっとif文の中をループしてしまいます
###補足情報(言語/FW/ツール等のバージョンなど)
使用言語はC#、使用ツールはUnity5.3、Visual Stdio2013を使用しています。

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

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

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

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

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

guest

回答2

0

ベストアンサー

触れているコリジョンのGameObjectをDestory()で削除した場合、OnTriggerExit2D()などコリジョンが離れた際の関数は呼ばれないことに気をつけてください。
これはGameObjectをSetActive(false);で非表示にしたり、Colliderのコンポーネントをenabled = false;した際も同様です。

もしGameObjectの破棄のタイミングで何か処理をしたいのでしたら、オレンジ色のブロックにコンポーネントを追加して、OnDestroy()関数で処理するか、それともDeleteコンポーネントのOnTriggerStay2D()で処理するかの必要があると思います。

オレンジ色のブロック側で処理する場合

csharp

1using UnityEngine; 2 3public class Orange : MonoBehaviour 4{ 5 public OnDestroy() 6 { 7 // DeleteのUpdate()を参考に。 8 GameObject.Find("Cube_00").GetComponent<Destroy01>().Hit01 = false; 9 GameObject.Find("Cube_01").GetComponent<Destroy02>().Hit02 = false; 10 GameObject.Find("Cube_02").GetComponent<Destroy03>().Hit03 = false; 11 GameObject.Find("Cube_03").GetComponent<Destroy04>().Hit04 = false; 12 GameObject.Find("Cube_04").GetComponent<Destroy05>().Hit05 = false; 13 GameObject.Find("Cube_05").GetComponent<Destroy06>().Hit06 = false; 14 } 15 16} // class Delete

Deleteコンポーネントで処理する場合

csharp

1void OnTriggerStay2D(Collider2D other) 2{ 3 if(ALL_OK == true) 4 { 5 // DeleteのUpdate()を参考に。 6 GameObject.Find("Cube_00").GetComponent<Destroy01>().Hit01 = false; 7 GameObject.Find("Cube_01").GetComponent<Destroy02>().Hit02 = false; 8 GameObject.Find("Cube_02").GetComponent<Destroy03>().Hit03 = false; 9 GameObject.Find("Cube_03").GetComponent<Destroy04>().Hit04 = false; 10 GameObject.Find("Cube_04").GetComponent<Destroy05>().Hit05 = false; 11 GameObject.Find("Cube_05").GetComponent<Destroy06>().Hit06 = false; 12 Destroy(other.gameObject); 13 } 14}

以上をお試しください。

補足で気になる点があるのですが、質問で記載されているソースコードではALL_OKfalseになるタイミングが無い様に思えます。
全てのHitフラグがtrueでない場合にfalseにしてあげる必要があるのではないでしょうか。

csharp

1if (d1.Hit01 == true && d2.Hit02 == true && d3.Hit03 == true && 2 d4.Hit04 == true && d5.Hit05 == true && d6.Hit06 == true) 3{ 4 ALL_OK = true; 5} 6else 7{ 8 ALL_OK = false; 9}

OnTriggerStay2D()にてwhile(ALL_OK == true)で判断されているようですが、if(ALL_OK == true)の方がよいのではないでしょうか。
while()では無限ループに陥ってしまうような気がします。

投稿2016/06/29 09:25

urahimono

総合スコア714

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

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

YuzuTf

2016/07/04 01:25

返信が遅れ、申し訳ありません。 ありがとうございます! しっかり判定を消すことができました!
guest

0

Destroyしたことによって、そのオブジェクトそのものの処理は無効になるからではないでしょうか。
フラグ管理をするスクリプトを変えるか、削除処理を実行前に行いたい処理を追加するなどが必要かと思います。

※当たり前ですが、Destroyした場合、そのオブジェクトにアタッチされているスクリプトは全て停止します。

投稿2016/06/29 06:30

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問