CharacterController.Move
CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 37/56。
CharacterControllerは、歩行キャラクターのためのUnityのコンポーネントです。スクリプトからcontroller.Move(motion)を呼び出したときだけ動くカプセルです。motionはこのフレームで移動する距離なので、速度にTime.deltaTimeを掛けた値です。Moveはカプセルを壁の中ではなく壁に沿って滑らせ、Slope Limit(45 degrees)までの斜面を上り、Step Offset(0.3 units)までの段差に乗り上げます。これはRigidbodyではありません。力も重力も跳ね返りもなく、何かに押されることもありません。Moveが指示した場所に正確に移動するため、精密なゲーム操作に適しています。
重力を加えるのも、床を見つけるのも自分で行います。isGroundedは、最後のMoveで下側にある何かに触れたときにtrueになるため、下向きの成分がない移動では床を見つけられません。コントローラーのMin Move Distance(0.001)より短いMoveは何もしないため、横方向にしか動かないコントローラーは、停止するとすぐに接地していないと報告します。この配達員は矢印キーで歩き、移動のたびに少し下向きに押します。
public class Courier : MonoBehaviour
{
public float speed = 6f;
CharacterController controller;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
move.y = -2f; // 床を検出できるように、常に下向きの力を加える
controller.Move(move * Time.deltaTime);
if (!controller.isGrounded)
{
Debug.Log("Off the ground");
}
}
}カプセルは、触れているものからSkin Width(0.08)だけ離れています。そのため、高さ2 unitsのコントローラーは、y = 0の床の上でy = 1ではなくy = 1.08の位置に静止します。また、Moveは物理演算が最後にコントローラーを認識した位置から移動を開始するため、コントローラーのtransform.positionを設定しても、次のMoveで元に戻ることがあります。テレポートさせるには、controller.enabled = falseにしてから移動させ、再び有効にしてください。
チャレンジ
中級探検者は、後ろに壁があり左側が崖になっている石の足場に立っています。CharacterControllerを持つPlayerに、Explorer.csを記述してください。Inspectorではspeed(4)とfallSpeed(3)が設定されており、Start()ではすでにcontrollerと探検者のRendererを取得しています。
- raw axesで読み取った矢印キー(またはWASD)で、
controller.Moveを使って1秒あたりspeed単位の速さで移動します。左右はx軸に沿って、上下はz軸に沿って移動します。壁に当たると止まる必要があります。 - 移動するたびに、1秒あたり
fallSpeed単位の速さで下方向にも移動するため、探検者は足場の上にとどまり、その端から落ちます。 - コントローラーが接地している間、探検者は
Color.greenになり、接地していない間はColor.redになります。
Playを押し、壁に向かって歩いてから端から落ち、その後Checkを押してください。
自分で試してみよう
using UnityEngine;
public class Explorer : MonoBehaviour
{
public float speed = 4f;
public float fallSpeed = 3f;
CharacterController controller;
Renderer rend;
void Start()
{
controller = GetComponent<CharacterController>();
rend = GetComponent<Renderer>();
}
void Update()
{
// controller.Moveで移動し、次にisGroundedに応じてExplorerの色を変える
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。