メニューを開いてマウスカーソルを表示するときは、FPSキャラクターの移動や回転を制限したいですが、リーンでカメラを横に傾けたままメニューを開いたときにカメラが傾いたまま止まってしまいます。
そこで、マウスカーソルを動かして周囲を見回すように通常の回転は制限しながら、カメラを傾けるような回転はできるようにしてみました。
スタンダードアセットのFPSキャラクターはFirstPersonControllerクラスのついた体と、カメラの付いた頭で構成されています。カメラの回転はMouseLookクラスで行います。
キャラクターを移動させるときは体だけが動いて、回転は横方向が体、縦方向はカメラです。一方、リーンはカメラの位置と回転で行います。
キャラクターの移動をロックしたいとき、カメラの移動をロックする必要はないので、ロック時にカメラが傾くために移動していたものをもとに戻すことは簡単です。しかし、カメラの回転を制限すると、傾いていたのを戻すための回転も制限されるので、カメラの移動だけがもとに戻ってしまいます。
どうにか、通常の回転は制限しながら、リーンの回転は自由にしたいです。リーンはFPSキャラのカメラを横に傾ける #2と同じもので、MouseLookクラスで通常の回転処理をした後に行っています。
通常の回転ではZ方向への回転は行わないので、最後にカメラのZ方向のローカル回転に傾く量を適用するだけでした。その値を上げ下げすることで傾けたり戻したりということをしています。
そこで、まず通常の回転処理の中のリーン処理をパブリックなメソッドに置き換えました。
// MouseLook
public void LookRotation(Transform character, Transform camera)
{
// 通常の回転処理
// ...
// リーン
Lean(camera);
// ...
}
float leanAmount;
// リーン
public void Lean(Transform camera)
{
Vector3 e = camera.localRotation.eulerAngles;
e.z = leanAmount;
camera.localRotation = Quaternion.Euler(e);
}
MouseLookクラスはMonoBehaviourクラスを継承していないので、Update()メソッドもありません。通常の回転はFirstPersonControllerクラスのUpdate()でMouseLookのLookRotation()メソッドが呼ばれることで行われます。
なので、通常の回転をさせるときはそのメソッドを呼び、させないときは今作ったリーンのメソッドだけを呼ぶようにしました。
// FirstPersonController
private void Update()
{
// ...
if (カメラを回転) RotateView();
else m_MouseLook.Lean(m_Camera.transform);
// ...
}
このRotateViewメソッドの中でMouseLookのLookRotation()メソッドが呼ばれています。
これでメニューを開いたときに自然にリーンが戻るようになりました。
FirstPersonControllerクラスでは、リーンをしているときに、リーンのキーボード入力を離したり、頭が壁などに侵入するとリーンが戻るようになっていますが、メニューを開いたりしていないデフォルト状態でないときもリーンが戻るようにしています。