棒を登っているときにカメラの水平な回転を制限します。
スタンダードアセットのMouseLookクラスにはカメラの縦回転を制限するClampRotationAroundXAxisメソッドが用意されているので、これを使ってみます。
まず他のスクリプトで、棒の登り始めたときや手を離したときに、回転の制限をオンオフするメソッドを作りました。制限をかけるときに、棒を登り始めたときのキャラの角度を保存しますが、Quaternion.eulerAnglesは0~360の範囲の角度なので、ClampRotationAroundXAxisで管理する-180~180の範囲の角度に直しました。
public void LockRotYAxis(Quaternion q)
{
float y = q.eulerAngles.y;
if (y > 180)
{
y = y - 360;
}
initAngleY = y;
Debug.Log(y);
clampHorizontalRotation = true;
}
public void UnlockRotYAxis()
{
clampHorizontalRotation = false;
}
ClampRotationAroundXAxisメソッドをコピペして、ClampRotationAroundYAxisメソッドを作り、角度を制限する部分を新しいコードに置き換えます。
Quaternion ClampRotationAroundYAxis(Quaternion q)
{
// ...
float angleY = // ...
if (MinimumY + initAngleY <= -180)
{
if (angleY >= initAngleY + 180)
{
angleY = Mathf.Clamp(angleY, (MinimumY + initAngleY) + 360, (MaximumY + initAngleY) + 360);
}
else {
angleY = Mathf.Clamp(angleY, MinimumY + initAngleY, MaximumY + initAngleY);
}
}
else if (MaximumY + initAngleY > 180)
{
if (angleY >= initAngleY - 180)
{
angleY = Mathf.Clamp(angleY, MinimumY + initAngleY, MaximumY + initAngleY);
}
else
{
angleY = Mathf.Clamp(angleY, (MinimumY + initAngleY) - 360, (MaximumY + initAngleY) -360);
}
}
else
{
if (initAngleY > 0)
{
if (angleY < MinimumY + initAngleY && angleY > initAngleY - 180)
{
angleY = MinimumY + initAngleY;
}
else if (angleY > MaximumY + initAngleY || angleY <= initAngleY - 180)
{
angleY = MaximumY + initAngleY;
}
}
else if (initAngleY <= 0)
{
if (angleY > MaximumY + initAngleY && angleY < initAngleY + 180)
{
angleY = MaximumY + initAngleY;
}
else if (angleY < MinimumY + initAngleY || angleY >= initAngleY + 180)
{
angleY = MinimumY + initAngleY;
}
}
}
// ...
}
元のメソッドのようにMathf.Clamp()を使うと、マウスを素早く動かしたときに、反対側の制限まで急に回転してしまうので、棒を登り始めたときの角度から真後ろの角度まで、360度を2等分して、今の角度がどちら側にあるかによって固定する角度を決めています。
180度のところに段差があるので分岐が多くなってしまいました。まだたまに反対側の制限へ飛ぶことがありますが、デフォルトのClampRotationAroundXAxisによるカメラの縦回転でも同じことが起こるので、許容範囲かもしれません。
X/YSensitivityでマウス感度を下げると抑えられます。