FPSを作ってみよう5-キャラクターの向きの変更や視点を上下に動かす-

前回はキャラクターの移動と走る動作の作成まで完了しました。

FPSゲームのキャラクターが移動する時に歩くアニメーションに変更する機能を作成していきます。またキャラクターが走る機能もスクリプトに追加していきます。

今回はキャラクターの向きの変更と視点であるカメラの向きを上下に動かせるようにしたいと思います。

スポンサーリンク

キャラクターの向きとカメラの視点の上下を変更するやり方を考える

まずはどのように向きを変更するかを考えます。

キャラクターの向きの変更や視点の上下は現状ではゲームパッドに対応していないのでマウスの移動のみで行うようにします。

マウスを左右に移動させた時はキャラクターのY軸の角度を変更してキャラクターが回転するようにします。

マウスを前後に移動させた時は視点(カメラの角度)のX軸の角度を変更してキャラクターが上を見たり下を見たりしているようにします。

キャラクターの回転の角度は制限を与えずずっと回転出来るようにします。

一方、視点の上限に関してはpublic変数を使ってインスペクタで制限値を与え、決められた角度以上に上を向いたり下を向いたりしないようにします。

キャラクターの回転とカメラの視点の上下を変更する方法を見ていく

private var myCamera : Transform; // キャラクター視点のカメラ
public var cameraRotateLimit : float; // キャラクター視点のカメラで回転出来る限度
public var cameraRotForward : boolean; // カメラの上下の移動方法。マウスを上で上を向く場合はtrue、マウスを上で下を向く場合はfalseを設定
private var initCameraRot : Quaternion; // カメラの角度の初期値
public var cameraSpeed : float; // カメラ(視点)の動くスピード

private var xRotate : float; // カメラのX軸の角度変化値
private var yRotate : float; // キャラクターのY軸の角度変化値

private var charaRotation : Quaternion;
private var cameraRotation : Quaternion;

でキャラクターと視点の角度で使用する変数を宣言しています。

cameraRotateLimitは視点が上下する時の最大の角度で、インスペクタで設定出来ます。無限に角度が変更出来ると人間ではない事になるので・・・・((+_+))

cameraRotForwardはマウスの動きに対して視点が同じ方向に移動するか逆方向に移動するかの設定です。

initCameraRotはマウス操作で角度を変更した時に元の角度からどのぐらい変わったか判定する時に初期のカメラ角度を保存しておく変数です。

cameraSpeedは視点の移動するスピードで1秒間に変更する角度を指定し、インスペクタで設定出来るようにします。

charaRotationはキャラクターの角度、cameraRotationはカメラの角度を入れます。

Update関数内でRotateCharaとRotateCamera関数を呼びだし、キャラクターの角度とカメラの角度を変更します。

RotateCharaではマウスの横軸の移動値を計算し、元の角度にかける事で目的の角度を計算します。

目的の角度が計算出来たらQuaternion.Slerpを使って徐々に現在の角度から目的の角度に変更しています。

RotateCameraではマウスの縦軸の移動値を計算し、限界角度を越えていたらカメラの角度を限界角度に変更し直しています。

複雑な計算をしているように見えますが・・・、視点の変更を設定値内に収める計算をしているだけです。

もっと簡単に計算出来ると思いますが・・・わたくし、もうこの処理やりたくない(;一_一)

これでキャラクターの向きと視点の上下の機能が出来たので、MyCharaのインスペクタにパラメータを設定します。

MyCharaのインスペクタに回転の設定をする

限界角度cameraRotateLimitを30にし、cameraRotForwardにチェックを入れてカメラの移動方向がマウスの移動方向と同じになるようにします。

キャラクターの移動機能の作りなおし・・・・(T_T)

回転の設定も出来たので、Unityの実行ボタンを押して動くか確認してみましょう。

キャラクターの回転がうまくいくか試してみる

おおーガッデム!(謎)

キャラクターの回転も出来、視点の上下も制限角度内でちゃんと動いているようですが、キャラクターを回転させた後にキャラクターを移動させると、
違う方向に移動してしまいます。

上の実行結果でもキャラクターを回転させた後に↓のキーを押すとキャラクターの左側に進んでしまっています。

あああああへたこいたああああ((+_+))、ドゥルルンドゥルルンドゥルルンドゥルルン、ウェーイ♪
(小島よしお好きだな・・・・・あ・・ご結婚おめでとうございます(^^)v)

この原因はもちろん移動の仕方です。

velocity.x = Input.GetAxis(“Horizontal”); // 横方向のキーの押し具合をx軸に入れる
velocity.y = 0; // y軸は高さなので0に設定(キー操作で重力を無視して動く事はないから)
velocity.z = Input.GetAxis(“Vertical”); // 手前と奥方向に移動するキーの押し具合をz軸に入れる

現状は移動キーを押した方向をvelocityに設定しているので、キャラクターがどこを向いていようがいまいが、Unityの世界で言う正の方向と負の方向に移動してしまいます。
キャラクターの角度を変更する前はこれでよかったんですが、キャラクターの向きを変更したことによっておかしくなってしまいました。

本来であれば↑や↓のキーを押した時はキャラクターの向いている方向の前後、←や→を押した時はキャラクターの左右に移動。
という風にしなければいけません。

また、キャラクターが向きを変えている時は立っている状態で回転してしまっているので、足踏みをしながら回転するようにしてみます。

キャラクターの移動の修正と回転時のアニメーションの追加

private var charaRotFlag : boolean = false; // キャラが回転中かどうか?

でキャラクターが方向を変えているかどうかを判別します。

RotateCharaに処理を加えます。

マウスが左右に移動している場合はcharaRotFlagにtrueを入れ、それ以外はfalseを入れます。

また移動方法は

velocity = (transform.forward * Input.GetAxis(“Vertical”) + transform.right * Input.GetAxis(“Horizontal”)).normalized;

と変更します。

以前だと移動速度を正規化していなかった為、斜め方向の移動が大きくなっていましたので
全体をVector3のnormalizedプロパティで正規化した値をvelocityに入れるようにしました。

同じようなものでVector3のnormalize関数がありますが、こちらの場合元の値を書き換えてしまいます。
今回の場合は一時的な値として使うのでどちらでも問題はなさそうです。

transform.forwardはキャラクターの前方でそれにInput.GetAxis(“Vertical”)の値をかけ、
transform.rightはキャラクターの右方向でそれにInput.GetAxis(“Horizontal”)の値をかけて

キャラクターの向きに応じた移動方向と移動値を計算します。

キャラクターが向きを変えている時は歩くアニメーションをさせたいので、移動している時以外にcharaRotFlagがOnの時も条件に入れます。

そのままだと走るボタンを押している時にキャラクターの向きを変えると走るアニメーションになってしまう(走るアニメーションでいいならいいですが)ので、
条件を加えてキャラクターが向きを変える時は歩くアニメーションにします。

これでキャラクターの回転とそのアニメーション、またキャラクターの向きによって移動方向を変える事が出来るようになりました。

キャラクターの回転と視点の角度変更の機能を作り終えて

キャラクターの回転と視点(カメラ)の上下の機能は簡単に実装出来そうで細かい部分で実は難しかったです。

キャラクターの回転自体はただキャラクターのY軸の角度を変更すればいいんですが、
カメラの角度の上下はただX軸の角度を変更出来るようにするだけだと、無制限に角度が変わってしまって人間ではない角度まで変わってしまいます・・・(^_^;)

そこで制限角度を設けて一定の角度以上にはカメラが向かないようにしました。

この機能がないとキャラクターの内部まで映し出してしまうほど回転して問題が出てきてしまいます。

現状角度を変更した時に限界角度の設定値によってはキャラクターの中身が見えてしまいますが、これは次回以降修正していきますので、ほうっておいてください。

実は視点の変更に関してはまだ問題を残しています。

Unityのガンシューティングの機能に上半身だけを動かして狙いを敵に定められるようにする機能を追加します

のようにカメラをキャラクターのボーン内(頭のあたり)に設定し、ボーンの角度を変えてキャラクター自身の上半身の角度を変えるという方法がありますが、
今回はカメラの角度だけを変えキャラクターの上半身の角度を変えていません。

このままだと例えばオンライン対戦を実現しようと思った時に相手方のキャラが実際に攻撃をする方向とキャラクターが向いている方向が違うという不具合が発生します。

また、もし上半身の角度を変更出来たとして、
キャラクターの上半身の角度を変更する時にカメラをボーンの子要素に配置しておくとカメラが相対的に動くので簡単に視点の移動を実装出来そうですが、
親要素の位置や角度の相対値で動く為、キャラクターを歩かせるとカメラのブレが大きく視点が定まらなくなります。

今後、上半身の角度を変更する事や上半身の角度を変更することでカメラが歩く時に大きくブレてしまう時の対策やキャラクターの中身を表示してしまう問題の対処をしていきます。

これらはキャラクターのアニメーションを作成する記事以降に対処します。

次回はFPSゲーム用のジャンプ機能を作成していきます。

スポンサーリンク

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

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

コメント

  1. Yu より:

    コメントで失礼します
    角度計算変更でLateUpdate()の中を変更したのですが
    NullReferenceException: Object reference not set to an instance of an object MyChara.LateUpdate()(at Assets/Script/MyChara.js:81)
    というエラーが出て先に進めません…
    オブジェクトが存在していないところまではわかったのですがどのオブジェクトなのかわからなかったのでわかりましたら教えてください!

    • コンソールのエラーが出た部分をダブルクリックするとMonoDevelopが起動しエラー箇所部分がハイライトされるので、スクリプトのその行で使っているオブジェクトのエラーである事が確認出来ます。

      LateUpdate内でオブジェクトの参照がNullと言う事はmyCameraですかね?

      Startメソッドで

      myCamera = GetComponentInChildren.<Camera>().transform;

      C#なら

      myCamera = GetComponentInChildren<Camera>().transform;

      と、このスクリプトを設定しているMusasi君(記事中のキャラクター名)の子要素にあるカメラのTransformを取得しています。

      つまりここでmyCameraが取得出来ていないという事はMusasi君の子要素にカメラを設置していないのかもしれません。

      キャラクターの子要素にカメラを設置していないのであればpublicでCamera型の変数myCameraを宣言しStartメソッドで取得しないでインスペクタで設定してしまうという手もあります。

      詳しいスクリプトがわからないので、あくまでmyCameraがNullというエラーが発生しているという状況でのお話になります。(._.)