FPSコントローラーの移動方向を変えて棒や垂れ下がる鎖などを登れるようにしてみます。
まず頭のスクリプトで、近くで棒にレイが当たっているときにFキーが押されると、体のスクリプト(FirstPersonController)のbool変数を変えて登っている状態に切り替えます。頭と体で分けてしまったのは失敗だったかもしれません。
else if (hit.collider.tag == "Pole" && hit.distance < 1f)
{
image.SetActive(true); // 手のマークを出す
if (Input.GetKeyDown(KeyCode.F))
{
image.SetActive(false); // 手のマークを消す
sc_fps.m_IsClimbingPole = true; // FirstPersonController
state = 4;
}
}
その後、頭のスクリプトでは、登っているときに再度Fキーが押されると登るのをやめて、何もしていない状態に戻します。
else if (state == 4)
{
// 手を離す
if(Input.GetKeyDown(KeyCode.F))
{
sc_fps.m_IsClimbingPole = false;
state = 0;
}
}
FirstPersonControllerでは、キャラの移動のベクトルを決めて、キャラクターコントローラーのMove()を実行してキャラを移動させるのをFixedUpdate()の中で行うので、ここで、登っている時は縦方向にしか移動できないようにします。
移動キー入力をキャラの前や右方向にかけるところで、登っている時は、前後の移動キーをキャラの上方向にかけます。そのときに移動速度も決めます。Vector3 desiredMove;
if (m_IsClimbingPole)
{
desiredMove = transform.up * m_Input.y;
m_MoveDir.y = desiredMove.y * speed;
}
else
{
desiredMove = /* ... */;
}
speedをかけているので、シフトキーを押している間は速度が上がります。
その下の縦方向の移動を決めるところは、登っている時はスルーしますが、ジャンプはできるようにします。
if (!m_IsClimbingPole)
{
if (m_CharacterController.isGrounded)
{
/* ... */
if (m_Jump)
{
/* ジャンプする */
}
}
else
{
/* ... */
}
}
else {
if (m_Jump)
{
/* ジャンプする */
// 手を離す
sc_item3.ReleaseHold(); // 頭のスクリプト
m_IsClimbingPole = false;
}
}
ジャンプする処理は上にあるのをそのままコピペして、手を離す処理を追加します。頭のスクリプトのメソッドを実行して、何もしていない状態に戻しています。
public void ReleaseHold()
{
if (state == 4)
{
state = 0;
}
}
これで登っている時にジャンプして飛び降りられるようになりました。
また、登っているときに足が床についたら手を離すようにします。FirstPersonControllerのUpdate()の中の着地時の処理に追記します。
if (!m_PreviouslyGrounded && m_CharacterController.isGrounded)
{
if (m_IsClimbingPole)
{
// 手を離す
sc_item3.ReleaseHold();
m_IsClimbingPole = false;
}
/* ... */
}
次は、登っているときに体の回転を制限したり、歩いているときのようにカメラを振ったりしてみます。