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

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

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

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

Unity3D

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

Q&A

解決済

3回答

3822閲覧

衝突判定でflagをtrueにしたのに、メソッドではfalseのままになる。

Kuronekoya

総合スコア26

C#

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

Unity3D

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

0グッド

0クリップ

投稿2016/04/26 13:00

いつもお世話になっています。
今回はUnity3Dについて伺います。

現在落ちゲームを作っているのですが、衝突判定とメソッドが上手くかみ合いません。
というのも、ブロックが下に落ちるメソッドを作り、壁にブロックが衝突した時点でそのメソッドを終わらせたいと思い、
flagがfalseの時、メソッド内で処理を繰り返し行い、ブロックが壁に衝突した時点でflagをtrueにして処理を終わらせる、という手を取ろうと思ったのですが、OnCollisionEnter内ではflagはtrueになるものの、メソッド内ではfalseのままなのです。

説明ではわかり難いと思いますが、原因のわかる方、どうぞご教授いただけませんでしょうか。よろしくお願いいたします。

C#

1Class A 2mBlock [0].FallBlock (block); 3 4 5Class B 6bool flag = false; 7 8public void FallBlock(Block block){ 9 //flagがfalseの間はブロックが落ちる 10 while(flag == false){ 11 //ブロックが落ちる処理 12 Vector3 blockPos = block.transform.position; 13 blockPos -= -1; 14 block.transform.position = blockPos; 15 } 16} 17 18private void OnCollisionEnter(Collision collision){ 19 //壁に衝突したらflagをtrueにする 20 if(collision.gameObject.tag == "Wall"){ 21 flag = true; 22 } 23} 24 25

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

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

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

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

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

guest

回答3

0

whileの用法は別として、クラス内の変数の値が変わるのはおかしいです。
(「flagがtrue/falseになる」のはDebug.Log等で確認済みという想定で回答します)

1.記載の部分の他に、flagをfalseにしている部分はありませんか?(そこが暴発していませんか?)

2.衝突しているのは正しいオブジェクトですか?
mBlock [0].FallBlock (block);
という部分を見るに、ブロックは複数あるようですが、flagがtrueにならない(=動き続ける)のはmBlock[0]で間違いありませんか?
「ブロックAは衝突していて、ブロックBは衝突していない」という状況だった場合、ブロックAではflag=true、ブロックBではfalg=falseとなりますが、この点は確認していますか?

投稿2016/04/27 02:36

sakura_hana

総合スコア11425

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

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

Kuronekoya

2016/04/27 06:15

sakura_hana様、ご回答ありがとうございます。 おっしゃる通り、Debug.Logとブレークポイントで確認済みです。 1の回答ですが、記載の部分以外にflagを変えている部分がなく、暴発してるような気配がありません…。 そして2の回答なのですが、ブロックはこれから増やしていくために配列に入れていますが、現在の時点ではまだ1つしか作っていないので、1つだけが反応している、というのも考えにくいようです。 そもそもの設計が悪いのかもしれません…ご回答いただいたのに解決に至らず申し訳ありません…。 もう一度、設計からやり直してみようと思います。 前回に引き続き、ご回答いただき本当にありがとうございました!
guest

0

ベストアンサー

FallBlock() 内の while がCPU占有ループ(CPU時間をOSや他のスレッドに渡さずにずっとCPUを使い続ける状態)になっているように思われます。
gameobject の移動は Update() イベントハンドラを使うのが一般的ではないかと。

C#

1// BlockCtl.cs 2using UnityEngine; 3using System.Collections; 4 5public class BlockCtrl : MonoBehaviour { 6 bool flag = false; 7 void Start () { 8 } 9 void Update() { 10 if (!flag) { 11 Vector3 blockPos = transform.position; 12 blockPos -= -1; 13 transform.position = blockPos; 14 } 15 } 16 void OnCollisionEnter(Collision collision) { 17 //壁に衝突したらflagをtrueにする 18 if(collision.gameObject.tag == "Wall"){ 19 flag = true; 20 } 21 } 22}

ゲームコントローラー他の設計が解らないので必ずしもこのような記述にはならないこともあると思いますが、ご参考になれば。

投稿2016/04/26 13:44

tkanda

総合スコア2425

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

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

Kuronekoya

2016/04/27 06:09

tkanda様、ご回答ありがとうございます。 Update()を使えば確かに早いですね!この方法で上手くいきそうです。 コードまで書いていただき、本当にありがとうございます。 この方法を使って再度書き直してみようと思います。 ご回答ありがとうございました!
guest

0

Unity3Dを触ったことがないので、的外れなことを書いているかもしれませんが、

C#

1 while(flag == false){ 2 //ブロックが落ちる処理 3 () 4 } 5}

このループはループ内でフラグを変更する箇所がないので、他に非同期でフラグを変えてくれる処理がないと永遠にループし続けることになりませんか?

OnCollisionEnter()というイベントハンドラがありますが、提示いただいているコードを見る限り、FallBlock()関数から一旦抜けないとOnCollisionEnter()へ処理が移らないのではないでしょうか?

もし、別の場所でTask.Run()している処理があるのであればその処理で発生する他のイベントでフラグを戻している処理がないか確認してみてください(あまり論理的な方法ではないですが、フラグを変化させている箇所にブレークポイントを貼りまくってどこでフラグを戻しているかデバッガで追うのも一つの手です)。

あとはflagの宣言にvolatileをつけて、コンパイラから最適化されないようにすることで、回避できるかもしれません。
while内部でflagが変化する処理がないため、flagのチェック処理がスキップされる場合があります。volatileをつけて宣言すると最適化の際にも常に新しいflagの値をチェックしてくれるようになります。

投稿2016/04/26 13:37

編集2016/04/26 13:43
KoichiSugiyama

総合スコア3041

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

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

Kuronekoya

2016/04/27 06:07

KoichiSugiyama様、ご回答どうもありがとうございます。 なるほど。FallBlock()関数の途中でOnCollisionEnter()へ移すことはできないのですね。 一応ブレークポイントを置いたりDebug.Logを置いて色々調べてはみたのですが、結果はわかりませんでした… 初心者すぎて、volatileというものを初めて聞きました。そんな方法があるのですね! 一度調べてみます。 ご回答、どうもありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問