
どの高さからでもはしごに乗れるようにします。また、はしごの上まで来たら自動ではしごを降りるようにします。
前の記事では、地面の近くのはしごに乗る位置に空のゲームオブジェクトを置いていましたが、はしごの終点の少し上に置くことにしました。

これは、Z軸方向をまっすぐはしごに向けて、Y軸をハシゴの長い方の向きに合わせます。はしごをまっすぐ上に立ててから、はしごの子オブジェクトして、Y軸がまっすぐ上を向くように空のゲームオブジェクトを置きます。
そして、はしごに乗るときは、プレイヤーの高さを通って真上を向いたPlaneを作り、空のオブジェクトからそのY軸の逆方向に飛ばしたレイとPlaneとの交点へプレイヤーをワープさせます。

それによって、はしごの上にいるときや、ジャンプしているときでも、その位置からはしごに乗れます。

public bool Warp(Transform t)
{
if (t.childCount != 1) return false;
warp = true;
ladderTransform = t;
ladderTop = ladderTransform.GetChild(0);
Vector3 pos = transform.position;
pos.y += 1f;
Plane p = new Plane(transform.up, pos); // プレイヤーの高さにPlaneを作る
Ray ray = new Ray(ladderTop.position, -ladderTop.up); // 子オブジェクトからのレイ
float enter = 0f;
if (p.Raycast(ray, out enter))
{
ladderStartPos = ray.GetPoint(enter);
m_MouseLook.Warp(Quaternion.Euler(new Vector3(m_Camera.transform.eulerAngles.x, ladderTop.eulerAngles.y, ladderTop.eulerAngles.z)));
return true;
}
else {
return false;
}
}
また、MouseLookのワープのための関数へ回転値を渡すようにしました。このX軸をカメラの値にすることで、カメラの縦回転を変えずにはしごに乗れるようになりました。

さらに、プレイヤーが空のオブジェクトの近くで上へ移動しようとすると、はしごを降りてプレイヤーの視線の斜め上方向に少し移動します。
if(Vector3.SqrMagnitude(ladderTop.position - transform.position) < 2.6f && m_Input.y > 0)
{
//m_Input.y = 0f;
// はしごを降りる
Climb(false, false, (transform.forward + Vector3.up) * 0.2f);
}
これではしごの登り降りができるようになりました。