はしごに裏から乗ろうとするとキャラクターがはしごに引っかかってしまう問題を解決してみました。
キャラクターをはしごの前に移動させるときにキャラクターコントローラーのMoveメソッドを使うと、はしごのコライダーに当たって止まってしまうようです。
なので、はしごに乗る時は一旦キャラクターコントローラーを無効にして、トランスフォームに値を代入してキャラクターを移動させます。
public bool Warp(Transform t)
{
if (t.childCount != 1) return false;
// キャラクターコントローラーをオフ
m_CharacterController.enabled = 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;
}
}
// FixedUpdate
if (warp)
{
Vector3 warpDir = ladderStartPos - transform.position;
if (warpDir.magnitude <= 0.1f)
{
transform.position = ladderStartPos;
StartCoroutine("EndWarp");
}
else
{
transform.position += warpDir * Time.fixedDeltaTime * warpSpeed;
}
}
else
{
// 通常はキャラクターコントローラーで移動させる
// ...
}
そして、ワープが終了したらキャラクターコントローラーを有効にします。
IEnumerator EndWarp()
{
if (warp)
{
m_MouseLook.smooth = false; // 先にスムーズを切る
warp = false; // 移動できるようにする
yield return null; // 1フレーム待つ
// キャラクターコントローラーをオン
m_CharacterController.enabled = true;
Climb(true, true, ladderTop.up);
yield return null; // 1フレーム待つ
m_MouseLook.EndWarp();
}
}
これで、はしごに引っかかることがなくなりました。
また、ワープ中にもGetInputが実行されて、ワープ中のキー入力がワープ直後に反映されるようですが、あまり気になりません。他にも、ワープ中にタイミング良くシフトキーを押して走り出すと、FovKickのためのコルーチンがスタートする直前のStopAllCoroutines()のせいで、ワープ終了のコルーチンが止まってしまうことがありますが、簡単に回避できます。