今回の記事はUnityのTPS型キャラ移動の続きです。
カメラはTPS型でキャラの周りを回るようになっていますが、これに視点をリセットする(プレイヤーキャラの真後ろにカメラを回す)機能を作っていきます。
前回の記事はこちらです!↓
もくじ
リセットの作り方
今回の機能はRigidbodyを使わずにTransform.rotationで作ることにしました。
カメラの回転を作った記事でRigidbodyとTransformの回転どちらでも作れると紹介しましたが、Rigidbodyだとリセット機能を作るのは難しくなります。
RigidbodyのHinge JointにもSpringという機能があってリセットに使えなくはないのですが、正確なリセットを作るのには向いていないかな…と思います。
リセットの処理
まずどんな仕様で作りたいのかを考えてみました。
- Quaternion.LerpかSlerpを使ってコルーチンで動かす
- 開始時のプレイヤーキャラとカメラの間の角度によってフレーム数を増減する
- 等速ではなくイージングした動きにする
今回は目的の向きまでの回転をさせたいので、プレイヤーキャラの回転の記事のようにQuaternion.LerpかSlerpを使って回転させます。
コルーチンの中でfor文を使って回転させるので、コルーチンが開始したらまず回すフレーム数を決めます。回す角度が大きかったらフレーム数を多く、小さかったら少なくする必要があります。
まず事前に、リセットする角度が180度だったときのフレーム数(最大値)と0度だったときのフレーム数(最小値)をスクリプトで設定できるようにしておきます。
リセットの処理が開始されたら、Vector3.Angle()を使ってプレイヤーキャラの正面のQuaternion(目的の向き)とカメラの現在の向き(Transform.rotation)の間の角度を算出します。
そして回す角度 / 180.0f をMathf.Lerp()やイージングなどの補間値にして今回のフレーム数を算出します。
floatで算出することになるので、Mathf.RoundToInt()で整数にするのを忘れずに!

回転のスピードもイージングで加減速させたいので、(float)現在のフレーム数 / (float)今回の全フレーム数 をイージングの補間値にして0.0f~1.0fの値を算出し、これを更にQuaternion.Lerp()の補間値とします。
こんな感じです!
[SerializeField] float maxFrames = 35.0f;
[SerializeField] float minFrames = 0.0f;
[SerializeField] AnimationCurve resetSpeed;
WaitForFixedUpdate waitForFixedUpdate;
IEnumerator ResetCamera()
{
var angle = Vector3.Angle(transform.forward, player.transform.forward);
var frames = Mathf.RoundToInt(Mathf.Lerp(minFrames, maxFrames, (angle / 180.0f)));
var startQua = transform.rotation;
var targetQua = player.transform.rotation;
for (int i = 0; i < frames; i++)
{
var currentSpeed = resetSpeed.Evaluate((float)i / (float)frames);
transform.localRotation = Quaternion.Lerp(startQua, targetQua, currentSpeed);
yield return waitForFixedUpdate;
}
}
フレーム数の最大値と最小値がfloatになっているのはMathf.Lerp()を使うためです。
また、スピードのイージングにはAnimationCurveのイージングを使ってみました。この場合、カーブの最初と最後の値が0.0fと1.0fになるように作る必要があります。
ここまでの仕上がり
かなりスムーズで見やすい動きになったかなと思います!イージングを入れたのがとても良い感じです。
全体的にTPSらしい動きができるようになりました。
移動とジャンプの挙動にもう少しもう少し工夫の余地があるなと思っているので、次の記事からはそのあたりを直していこうと思います。
次回の記事はこちら↓