Unityでキャラクターのなめらかな移動・回転のやり方を検証する

キャラクターを目的地に移動させる時に単純にスタート地点から目的地に移動させるやり方は今までの記事でやってきました。

しかし目的地までずっと同じスピードで移動し、目的地についたらピタッと止めてしまっていました。

操作性重視のゲームではこちらの方がいいですが、リアルな挙動のゲームを作成しようと思ったら歩きだす時や目的地付近に来たら歩くスピードを落としたい所です。

そんな時に使用するのが補間の機能です。

スタート地点と目的地が決まっていたらその間の点を補間して滑らかな動きにする事が出来ます。

この補間はこの記事で初めて扱うわけではなく今までの記事でもちょくちょく出てきていました。

スポンサーリンク

補間に使う関数

補間に使う関数は

Vector3.MoveTowards ある点からある点へ移動させる
Quaternion.RotateTowards ある角度からある角度へ回転させる
Vector3.Lerp ある点からある点の直線線形の割合を求める
Vector3.Slerp ある点からある点の球面線形の割合を求める

これらについては

管理人のかめくめちゃんがUnityのゲームを作成する時によく使う関数を紹介します

を参照してください。

補間関数を使って滑らかに移動させる

これらの補間関数を使って、移動を滑らかにしてみましょう。
またそれぞれの違いについて見てみます。

まずはCharacterControllerのMove機能を使ってキャラクターを動かす時に補間して動かすMoveスクリプトを作成します。

enum(列挙型)で補間モードを切り替えられるようにします。

モードはインスペクタで切り替えられるのでNormal、MoveTowards、Lerp、Slerpの4つの補間モードそれぞれで動くキャラクターを4人配置する事にします。

インスペクタで設定したモードで補間のやり方を変えています。

キーボードの方向キーの移動量を取得し、その移動量を前の値から新しい値へと補間した状態をvelocityに入れ直します。

その後oldVelocityに現在のvelocityを代入します。

後はシンプルなキャラクターを動かす処理が記述されているだけです。

ただ、今回は補間で滑らかな移動をさせる為にアニメーションの切り替えをvelocity.magnitudeが0.1fではなく0.01fより大きい時という条件に変更しておきます。

そうしないとアニメーションが終わった状態で移動してしまいます。

補間移動スクリプトをキャラクターに取り付ける

これでスクリプトが出来たのでStandardAssetのEthanをキャラクターとして配置し、Moveスクリプトを取りつけます。

その後Ethanを選択してCtrl+Dキーで3人コピーし合計4人のEthanを作成します。

補間を使った移動を行うキャラクター達の階層

↑のようにEthanの名前がいっぱい並びました!(`´)

補間モードを選択する

それぞれのキャラクターに設置しているMoveスクリプトのmodeを別々に設定します。

補間モード別に動かすキャラクターを配置

↑のようにEthanだらけです!ヽ(^o^)丿ヽ(^o^)丿ヽ(^o^)丿ヽ(^o^)丿

それぞれのMoveスクリプトのmodeを別々にして、同時に動かし検証してみます。

EthanはNormal
Ethan(1)はMoveTowards
Ethan(2)はLerp
Ethan(3)はSlerp

のモードに設定していて、上から順番になっています。

カメラがキャラクターを追いかけるようにMainCameraにFollowCameraスクリプト(StandardAssetに入っている)を設定し、真ん中のEthanをTargetに設定します。

補間移動の違いを確認する

それでは動かしてみましょう。

補間移動キャラクターのサンプル動画

↑のような感じになります。

1番上のキャラクターは補間を使っていないので動きがキビキビした感じになります。

2番目のキャラクターはMoveTowardsで1番目の何もしていないキャラクターと比較的に同じ動きです。

3番目はLerpなので直線的な補間になります。

4番目はSlerpで球面的な補間になります。

キャラクターを使った移動で補間を使いましたが違いがちょっと解り辛いですね・・・(^_^;)

上のように直接位置を操作した方がサンプルとしてわかりやすかったかもしれません・・・(^_^;)

またはマウスクリックの位置に移動する機能とかだとわかりやすいかも?

Unityのアクションゲームでマウスクリックした位置にキャラクターが移動する機能を作成していきます

のような機能ですね。

キャラクターの回転に補間を使用する

次はキャラクターを回転させるスクリプトRotateを作成しMoveの時と同じようにキャラクターに取りつけて確認してみます。

Rotateは以下のようになります。

enumでRotateModeを宣言します。
MoveTowardsの代わりにRotateTowardsにします。

RotateTowardsはMoveTowardsの角度バージョンという感じです。

横方向のキーが押されていたら現在の角度に入力度合い×回転スピードを足して角度を計算します。

後はMoveスクリプトとほとんど同じで動かすのではなくキャラクターの角度を変更しています。

補間回転スクリプトをキャラクターに取り付ける

スクリプトが出来たので回転させるキャラクターを設置します。

回転させるキャラクターの階層

上のような感じでEthanを量産体制に・・・・。

Rotateスクリプトの設定

rotateSpeedは40にしました。

EthanはNormal
Ethan(1)はRotateTowards
Ethan(2)はLerp
Ethan(3)はSlerp

になります。

回転させるキャラクターを並べた絵

↑はさきほどと同じ絵のように見えますが違います・・・・この画像はいらなかったかも・・・。

実行する前にさきほどMainCameraに取りつけたFollowCameraを無効化しておいてください。

補間回転を確認する

それでは回転も確認してみましょう。

キャラクターの回転の補間

↑のようにNormalはグルグル回ってますね・・・、そりゃUpdate毎に40度ずつ回転しているから当たり前ですが・・・。
なんでTime.deltaTimeをかけてないんだろう・・・謎

んーMoveスクリプトの時より解り辛い結果ですね・・・・。

サンプルを間違えたかも・・・・(^_^;)

補間を検証してみて

今回は補間をわかりやすくしようと思って記事を書いてみましたが、違いがわかり辛いですね。(._.)

キャラクターを使った実践的な補間で、違いがわかりやすいサンプルを思いつかなかったのです。

とりあえず滑らかにキャラクターを動かしたい時は補間を使ってみて、思ってたのと違う時は補間のやり方を変えてみるというのもいいかもしれませんね。

まずはLerpを使った補間を使うだけでいいと思います。

細かいこだわりを求めていくなら他の関数を使っていけばいいと思います。

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます