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

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

新規登録して質問してみよう
ただいま回答率
85.31%
Unity

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

Q&A

解決済

1回答

246閲覧

【Unity2D】タップで上下左右移動しているオブジェクトの斜め移動をなくしたい

Beggi

総合スコア7

Unity

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

0グッド

0クリップ

投稿2023/08/21 01:43

編集2023/08/22 05:58

実現したいこと

・Unity2Dでオブジェクトをタップ→上下左右いずれか一か所に何もなければその箇所に移動

という処理をしたいです。

以下の左側のように、下一か所だけ空いている場合はオブジェクトが下に移動してくれるのですが、
画像右側のように斜め方向(2)に空いた箇所があると、そこに斜め移動してしまいます。これを斜め移動せず、真っすぐの方向(1)に移動するようにしたいです。
イメージ説明

該当のソースコード

private void PieceMoving() { //上にRayを飛ばす RaycastHit2D hitUp = Physics2D.Raycast(transform.position + Vector3.up, Vector2.up, 0.1f);     //下にRayを飛ばす RaycastHit2D hitDown = Physics2D.Raycast(transform.position + Vector3.down, Vector2.down, 0.1f); //右にRayを飛ばす RaycastHit2D hitRight = Physics2D.Raycast(transform.position + Vector3.right, Vector2.right, 0.1f); //左にRayを飛ばす RaycastHit2D hitLeft = Physics2D.Raycast(transform.position + Vector3.left, Vector2.left, 0.1f); //上に何もなければ上に移動する if (!hitUp) { transform.position += new Vector3(0, 1.5f, 0); Debug.Log("上に移動した"); } //下に何もなければ下に移動する else if (!hitDown) { transform.position -= new Vector3(0, 1.5f, 0); Debug.Log("下に移動した"); } //右に何もなければ右に移動する else if (!hitRight) { transform.position += new Vector3(1.5f, 0, 0); Debug.Log("右に移動した"); } //左に何もなければ左に移動する else if (!hitLeft) { transform.position -= new Vector3(1.5f, 0, 0); Debug.Log("左に移動した"); } } private void OnMouseDown() { PieceMoving(); }

試したこと

以下のように各条件にフラグを立てて、フラグがfalseなら移動し、trueにする。のちにfalseに戻し…という風にしてみましたが、上手くいきませんでした。

else if (!hitLeft&&move==false) { transform.position -= new Vector3(1.5f, 0, 0); Debug.Log("左に移動した"); move = true; }

上記コードに至った経緯

else if文は上から順に条件を確認していき、途中で当てはまったらif条件を抜けるという解釈をしています。
そのため、自分のイメージでは、『上に何かあった→下に何かあった→右に何もなかった→移動→if文を抜ける』という形になるのではないかなと思っています。
なので、仮に下と斜め右下に二つ空いている箇所があっても、『上に何かあった→下に何もなかった→移動→if文抜ける』になるのでは?と疑問です。

それとも今の状況は、『上に何かあった→下に何もなかった→移動→if文抜ける』『上に何かあった→下に何かあった→右に何もなかった→移動→if文を抜ける』を同時に行ってしまっている感じなのでしょうか?
下に移動している最中に、右に何かあるかの判定をしちゃってるみたいな…。

ソースコードをどうすればよいのか、ご教授いただければ幸いです。
また、もしよろしければ、自分の解釈に関しても、誤っている点等ありましたら、そちらもご教授いただきたいです。よろしくお願いします!

※追記

頂いたコメントから検証したところ、PieceMoving()自体が二回呼ばれていることがわかりました。

そこで、本来はタッチするたびに移動させたいのですが、試しにPieceMoving()を一回だけ呼ぶ風にしてみました。

bool move=true; private void PieceMoving() { if(move==true) { //上にRayを飛ばす RaycastHit2D hitUp = Physics2D.Raycast(transform.position + Vector3.up, Vector2.up, 0.1f);     //下にRayを飛ばす RaycastHit2D hitDown = Physics2D.Raycast(transform.position + Vector3.down, Vector2.down, 0.1f); //右にRayを飛ばす RaycastHit2D hitRight = Physics2D.Raycast(transform.position + Vector3.right, Vector2.right, 0.1f); //左にRayを飛ばす RaycastHit2D hitLeft = Physics2D.Raycast(transform.position + Vector3.left, Vector2.left, 0.1f); //上に何もなければ上に移動する if (!hitUp) { transform.position += new Vector3(0, 1.5f, 0); Debug.Log("上に移動した"); } //下に何もなければ下に移動する else if (!hitDown) { transform.position -= new Vector3(0, 1.5f, 0); Debug.Log("下に移動した"); } //右に何もなければ右に移動する else if (!hitRight) { transform.position += new Vector3(1.5f, 0, 0); Debug.Log("右に移動した"); } //左に何もなければ左に移動する else if (!hitLeft) { transform.position -= new Vector3(1.5f, 0, 0); Debug.Log("左に移動した"); } } move=false; } private void OnMouseDown() { PieceMoving(); }

これで一回オブジェクトに触った後、二回目触れてもPieceMoving()は呼ばれなくなりました。
しかし、一回触ったときに、PieceMoving()が二回呼ばれている感じになってしまいます。

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

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

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

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

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

fana

2023/08/22 03:48 編集

まず,何が起こっているのかを明らかにしてください(=調査してください). 1回の PieceMoving() の実施によって斜めに移動しているという話なのか, それとも,2回連続で PieceMoving() が実施された結果として「下→右」と移動しているという話なのか? その他の何かが起こっているのか? といったことを調べてみると良いのでは. 例えば PieceMoving() が呼ばれるたびにカウントアップするカウンタを用意して,PieceMoving()内のデバッグ出力時にそのカウンタ値も表示するようにすれば,連続して何回も呼ばれているのか否かといったことはわかるのではないでしょうか. (あるいはもっと単純に PieceMoving() の先頭で「呼ばれたぞ」とか出力するくらいでも良いかも)
fana

2023/08/22 03:48

> 仮に下と斜め右下に二つ空いている箇所があっても、『上に何かあった→下に何もなかった→移動→if文抜ける』になるのでは? …という話であるハズなのに,変な方向に移動していまうのは何故なのだろうか? と考えて あり得そうな仮説を立てて,検証してみる,的な話です. ↑で書いた仮説は,「本来は1回だけ実施したい PieceMoving() が何らかの理由により複数回連続で呼ばれてしまっているのでは?」みたいな.
Beggi

2023/08/22 04:39 編集

丁寧にありがとうございます! if部分ばかり注視していて、PieceMoving全体に問題がある可能性を全然考えていませんでした…。 検証した結果、おっしゃる通り、タッチするとPieceMovingが連続で呼ばれているようでした。 斜めに直接移動しているのではなく、下→右で移動しているために斜めに見えるという形ですね。 ※追記 正確にはRayを飛ばすところまでだけ二回呼ばれているようです。
guest

回答1

0

自己解決

何度も検証したし、『二回だけ呼ばれている』ということがわかり、その原因を探りました。
その結果、本質問であげたコードをオブジェクトに直接アタッチしているのにも関わらず、別のスクリプトから再度アタッチして、オブジェクトに対して、同じコードが二つアタッチされている状態になってしまっていました…。

コメントにもいただいたように、検証を繰り返すこと。また、一つの問題ばかり注視せず、視野を広げて様々な方向から問題を見つめ直していこうと思います。
アドバイス、ありがとうございました!

投稿2023/08/23 01:01

Beggi

総合スコア7

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問