
FPSコントローラーではしごを登ってみます。
はしごを登る時は、はしごからの距離やキャラが回転できる範囲を常に同じにしたいと思ったので、今回はキャラクターコントローラーをはしごの前の指定の位置へワープさせ、指定の方向へ回転させてみます。
まずはしごの前に空のゲームオブジェクトを置いて、プレイヤーが目指す位置、回転にしておきます。


移動させる
キャラクターコントローラーではMove()の引数に方向を入れることで移動させます。プレイヤーからこの空のオブジェクトへのVector3を入れれば、空のオブジェクトの場所まで瞬時に移動します。
- // FirstPersonController
- [SerializeField] Transform mark;
- bool warp = false;
- Vector3 warpPos;
-
- public void Warp(Transform t)
- {
- warp = true;
- warpPos = t.position;
- m_MouseLook.Warp(t);
- }
-
- public void EndWarp()
- {
- if (warp)
- {
- m_IsClimbingPole = true;
- warp = false;
- m_MouseLook.EndWarp();
- }
- }
-
- // ---
- // Update()
-
- if(Input.GetKeyDown(KeyCode.N))
- {
- Warp(mark);
- }
-
- // ---
- // FixedUpdate()
-
- if (warp)
- {
- Vector3 warpDir = warpPos - transform.position;
- if (warpDir.magnitude <= 0.1f)
- {
- m_CollisionFlags = m_CharacterController.Move(warpDir);
- EndWarp();
- }
- else
- {
- m_CollisionFlags = m_CharacterController.Move(warpDir * Time.fixedDeltaTime * 15);
- }
- }
- else
- {
- m_CollisionFlags = m_CharacterController.Move( /* ... */ );
- }
まずFirstPersonControllerクラスにワープのスタートと終了のメソッドを作りました。ワープ開始のメソッドの引数には目的地のトランスフォームを入れます。回転を制御するためにMouseLookクラスに作るワープ用のメソッドを呼び出します。
今回はキー入力で目的地までワープさせてみます。ワープが始まると、目的地までの方向へ何回かにわけて移動します。Time.fixedDeltaTimeの後にかける値でワープにかかる時間が変わります。

ワープしていないときは、デフォルトの引数でキャラクターコントローラーのMoveが呼ばれます。この前に通常のキャラの移動のために移動キーを受けたり速さを変えたりするような処理がありますが、ワープしているときは無駄になるので、回避できた方がいいかもしれません。
プレイヤーが目的地に十分近づいたら、目的地まで瞬時に移動させてワープを終了します。ワープが終了したら、前の記事の方法で棒を登っている状態へ切り替えています。
回転させる
- // MouseLook
- bool warp = false;
- Transform warpTransform;
- bool defSmooth;
-
- public void Warp(Transform t)
- {
- warp = true;
- warpTransform = t;
- defSmooth = smooth;
- smooth = true;
-
- m_CharacterTargetRot = Quaternion.Euler(new Vector3(0f, warpTransform.eulerAngles.y, 0f));
- m_CameraTargetRot = Quaternion.Euler(new Vector3(warpTransform.eulerAngles.x, 0f, 0f));
- }
-
- public void EndWarp()
- {
- if (warp)
- {
- warp = false;
- smooth = defSmooth;
- }
- }
-
- // ---
- // LookRotation()
-
- if (!warp)
- {
- m_CharacterTargetRot /* ... */;
- m_CameraTargetRot /* ... */;
- }
MouseLookクラスにもワープ用のメソッドを作りました。ワープ中はいつもスムーズに回転させたいので、ワープ開始時のsmoothの値を保存してtrueにし、終わったら元に戻します。
スタート時に目的の回転値を決めて、ワープ中は、回転値を決める元々の処理をしないようにします。体はY軸に沿って横に、頭はX軸に沿って縦にだけ回転させています。

これではしごの前にワープしてそのままはしごを登れるようになりました。次は、上まで来たらはしごを降りたり、ななめのはしごに沿って登ったりできるようにします。
