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

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

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

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

Unity3D

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

Unity

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

Q&A

1回答

1779閲覧

プレイヤーの移動方向を前後左右の4方向で取得したい

futuru

総合スコア0

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2021/08/30 00:29

編集2021/08/30 01:36

やりたいこと

Unityで移動している方向によって移動アニメーションを切り替えたいので前後左右どちらに移動しているかを取得したいです。
またカメラは常にプレイヤーの前を向くようになっているので
前後左右はワールド座標からみた方向ではなく、プレイヤーが向いている方向を前として判断したいです。

・イメージ画像
イメージ説明

躓いているところ

最初にプレイヤーにRigidbodyが付いている事もあり
Rigidbody.velocityの値によってどちらの方向に移動しているか探ろうと思ったのですが...
このプレイヤーのカメラが常に前を向くようになっている為、前に歩くだけでも
1.北を向き前に進む(南→北) 2.南を向き前に進む(北→南)
1.東を向き前に進む(西→東) 2.西を向き前に進む(東→西) の4通りの状況が出来てしまいます。
Rigidbody.velocityはワールド座標が基準になっているので以下のような条件分岐で分けようとすると...

// 北を向き前に歩くと "前に歩いています" // 南を向き前に歩くと "後ろに歩いています" ← 本当は前に歩いていますと出て欲しい if (rigidbody.velocity.z > 0) Debug.Log("前に歩いています"); else if (rigidbody.velocity.z < 0) Debug.Log("後ろに歩いています");

そこで次はプレイヤーの向いている角度によって判断基準を変更することにしました

Vector3 moveVec = // プレイヤーが1フレームで動いた移動ベクトル float rotY = // プレイヤーの向いている角度 // 殆ど止まってる if (Mathf.Abs(moveVec.magnitude) < Mathf.Epsilon) moveState = MoveState.Standing; else { // 左右か前後かで言うなら前後移動 if (Mathf.Abs(moveVec.z) >= Mathf.Abs(moveVec.x)) { // 絶対座標から見て前に進んでる if (moveVec.z >= 0) { if (rotY >= 45 && rotY < 135) moveState = MoveState.Left; else if (rotY >= 135 && rotY < 215) moveState = MoveState.Back; else if (rotY >= 215 && rotY < 305) moveState = MoveState.Right; else moveState = MoveState.Forward; } else { if (rotY >= 45 && rotY < 135) moveState = MoveState.Right; else if (rotY >= 135 && rotY < 215) moveState = MoveState.Forward; else if (rotY >= 215 && rotY < 305) moveState = MoveState.Left; else moveState = MoveState.Back; } } else { // 絶対座標から見て右に進んでる if (moveVec.x >= 0) { if (rotY >= 45 && rotY < 135) moveState = MoveState.Forward; else if (rotY >= 135 && rotY < 215) moveState = MoveState.Left; else if (rotY >= 215 && rotY < 305) moveState = MoveState.Back; else moveState = MoveState.Right; } else { if (rotY >= 45 && rotY < 135) moveState = MoveState.Back; else if (rotY >= 135 && rotY < 215) moveState = MoveState.Right; else if (rotY >= 215 && rotY < 305) moveState = MoveState.Forward; else moveState = MoveState.Left; } } }

これである程度移動方向を正しく得られるようになりましたが
まだ100%正しくは取ることは出来ず((45,135,215,305)°辺りで細かく移動すると偶に間違った方向が返ってきたりします)

これ以上はもうお手上げなのでアドバイスを頂ければかと思います。
よろしくお願いします。

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

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

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

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

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

bboydaisuke

2021/08/31 23:47

何をしようとしているのかよくわかりませんが、対象が操作して動かすようなプレイヤーならば、 入力を受け付ける → 移動させる → 移動方向を取得して... ではなく、 入力を受け付ける → 入力を元にアニメーションを再生し、移動方向・量を計算する という順序の方が大抵の場合楽ですよ。
guest

回答1

0

当方,Unityを知らない人なので

Unityで移動している方向によって移動アニメーションを切り替えたいので前後左右どちらに移動しているかを取得したいです。

という話における「前後左右」という方向の基準が何になるのか? が謎ですが,
とにかく何かしらの「今はこっち方向が前」という基準があるのですよね? きっと.

それが「カメラ」基準なのか何なのか不明ですが,仮に,「カメラが向いている方向(カメラの真正面の方向)」というのが「前後左右」の「前」であるとするならば,

「プレイヤーが向いている方向(移動方向?)」と,当該基準方向たる「カメラが向いている方向(カメラの真正面の方向)」との内積なり外積なりを求めてみれば,それで判断が付くのではないでしょうか.
(当然,演算は「前後左右」を考えている平面上でやる)

投稿2021/08/30 01:16

編集2021/08/30 01:17
fana

総合スコア11954

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

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

futuru

2021/08/30 01:39

回答ありがとうございます。 少し分かりにくい文章になっているようなので参考画像を追加しました。 お恥ずかしい事に殆ど数学が分からない状態でして... 少し調べたところベクトルの内積と外積といった計算が出てきたのですがこちらを学んでいけばこの問題も解決するのでしょうか?
fana

2021/08/30 01:50

> イメージ画像 によると,プレイヤーの向きが基準で,プレイヤーというのは向きを変えずにいろんな方向に動く…という話なんですかね? (「左右」に移動する場合には蟹歩き的なモーションにしたい的な話かな)
fana

2021/08/30 01:56

まぁ,基準が何であれ,「前後左右」を考えている平面上で,「前方」を指すベクトルが(fx,fy)であるなら, 「後方」方向のベクトルは,その逆向きの (-fx, -fy) であり, 「左右」方向のベクトルは (-fy, fx) と (fy, -fx) だ(この世界でどっちが右でどっちが左かは私にはわからないが) 最もシンプルな話を挙げるならば,「前後左右」のどっちに向いているかを判断したい方向ベクトル (x,y) と,前記4つの方向ベクトルそれぞれとの内積を計算したときに「内積値が最も大きくなる方向」として判断すればよい. (実際上はもっと簡潔な実装になるだろうが)
fana

2021/08/30 02:03 編集

内積とか外積の式を調べれば,sinθ とか cosθ とかいうのが出てくるっしょ. つまり,2つのベクトルの成す角θがその式に含まれているわけ. そしたら,「内積なり外積の値を,このθに関する情報を得るのに使えるよね」っていう話になるよね. 例えば,ベクトル A=(ax,ay) と B=(bx,by) の内積については ax*bx + ay*by であり, |A| * |B| * cosθ でもある. という2つの式が見つかるよね. AとBの要素値を知っていれば,各ベクトルの長さ |A| と |B| は求められるし,内積の値自体も前者側の式から求められる. そしたら, 前者の式から求めた内積値 = |A|*|B|*cosθ という形から cosθ の値を求めることができる.
fana

2021/08/30 02:11 編集

cosθ とは, θが0度のとき,すなわち2つのベクトルの方向が完全一致するときに最も大きな値(1) になり, θが90(or -90)度のとき,すなわち2つのベクトルが直交するときに値は0になり, θが180度のとき,すなわち丁度反対向きの時に最も小さな値(-1)になる. 前述した > 最もシンプルな話を挙げるならば… は,ここからくる話. 4つの方向ベクトルのうち,最も(x,y)に向きが近い(成す角θが小さい)のはどれか? というのを, 内積値が最も大きいのはどれか? で求めている. (4つの内積計算において,内積計算対象の2つのベクトルの長さは全部同じなのだから,内積値の大小はcosθだけに依存する)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問