テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】キャラクターから見て対象への角度を「-180~180度」の範囲で求める

f:id:tsubaki_t1:20180205232957g:plain

対象への角度を「-180~180度」の範囲で求めてみます。

アニメーションで右向き・左向きに曲がるといった際、どちら方向に曲がれば良いのかを求めたいときに使えます。

 

目次

 角度を求める

角度を求めてみます。

求めるコードはこんな感じです。

selfに自分(Ethan)のTransform、Targetに矢印のTransformがセットされます。

        var diff = target.position - self.position;
        var axis = Vector3.Cross( self.forward, diff );
        var angle = Vector3.Angle( self.forward, diff )
                        * (axis.y < 0 ? -1 : 1) ;

キャラクターが前方を見ている状態で、矢印の向きを見ています。

下の図はゲームで使いやすいように、180で割っています。正面にあるなら0、右側にあるなら0.5、左側なら-0.5が出ます。

f:id:tsubaki_t1:20180205233931g:plain

なお、矢印とキャラクターの高さが同じ事が前提です。

 

それは何をやっているの?

Vector3.Angleで向きを求めています。ただし、これだけだと0~180の範囲が求められますが、-180~180の範囲を求められません。

下の図は、キャラクターの向き(白)と、対象へ到達するベクトル(赤)です。

f:id:tsubaki_t1:20180206110118g:plain

左右の判定をするためにVector3.Crossを使います。

この値で、対象が右にあるのか左にあるのか判断します。

 

下のgifアニメには適応していませんが、実際に使う場合は、下のような感じにします。

Vector3.Cross(direction1, direction2).y < 0 ? -1 : 1

f:id:tsubaki_t1:20180206110516g:plain

後はAngleで求めた角度とCrossで求めた向きをかければ、-180~180が求められます。

Cross(ベクトルの外積)は、コチラの記事が個人的にシックリ来ています。

http://www.sousakuba.com/Programming/gs_gaiseki.html

f:id:tsubaki_t1:20180206112005g:plain

 

せっかくなので(Root Motionで)向きを変える

折角作ったので、元々やりたかったこと、RootMotoinで向きを変えてみます。

何故今回これが必要だったかと言えば、RootMotoinの場合はアニメーションが左向きか右向きか判定する必要があったからです。面倒

 

アプローチは普通にBlendTreeを使って左回り、右回りのアニメーションを登録しておき、ブレンドを-1か1付近なら急速回転、-0.2~0.2辺りならユックリ回転させているだけです。

急速回転の範囲が広いのは、回転をチンタラ待ってるのがたるかったからです。RootMotoinでは、移動と回転がブレンドしないので、こういったチンタラ待つ必要がある要素は速やかに完了させたい所です。

f:id:tsubaki_t1:20180205234528j:plain

f:id:tsubaki_t1:20180205234605j:plain

これで今回の記事のトップGifアニメのように、キャラクターが矢印の方向を向きます。
勿論、モーションに回転が含まれていることが前提です。

 

あとは向く方向を先に頭を向けてたりすると、少し自然に見えるかもしれません。主にIKで。

 

RootMotoinの回転は使いやすい?

どちらかと言えば、YES寄りの絶対にノゥ。

ただ、回る方向に足が出るのは自然で楽しいです。

 

……まぁ足が滑らかに出るというか、普通に足が若干浮いてる訳ですが…

 

関連

キャラクターの顔を向ける方法をど忘れしてました。

qiita.comApply Root Motoinのオプションはこんな感じの機能も使えて結構面白いんですが、色々と癖が…

tsubakit1.hateblo.jp