コース
CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 48/56。
この章では3Dプラットフォーマーを作ります。浮遊する足場を走って跳び渡り、滑る足場に乗り、チェックポイントに触れて落下してもスタート地点に戻されないようにし、画面にカウントされる宝石を集め、ゴールを越えて次のレベルに進み、自己ベストタイムの更新を目指します。ゲームは5つのスクリプトで構成されており、これらはプロジェクトに最初から入っています。Player、MovingPlatform、Checkpoint、Gem、FinishLineです。最後の4つは今のところ空で、それぞれのレッスンで1つずつ作成します。プレイヤーはInput Systemのアクションで操作するCharacterControllerで、カメラはその子オブジェクトなので、スクリプトなしで追従します。
CharacterControllerの移動方法は2つあります。Move(motion)は距離を指定して移動し、何も加えないため、重力、ジャンプ、Time.deltaTimeはCharacter Controllerの章と同様にスクリプト側で処理します。SimpleMove(speed)は毎秒の速度を受け取り、フレームの時間を使って自動的に移動量を計算し、重力も加えます。渡したyの値は無視されるため、これで移動するキャラクターは足場の端から落ちますが、ジャンプはできません。上から見下ろす牧羊ゲームのこの牧羊犬にはジャンプが不要なので、SimpleMoveとMoveアクションだけでスクリプト全体を構成できます。
using UnityEngine;
using UnityEngine.InputSystem;
public class Sheepdog : MonoBehaviour
{
[SerializeField] private float speed = 6f;
private CharacterController controller;
private InputAction moveAction;
void Start()
{
controller = GetComponent<CharacterController>();
moveAction = InputSystem.actions.FindAction("Move");
}
void Update()
{
Vector2 input = moveAction.ReadValue<Vector2>();
controller.SimpleMove(new Vector3(input.x, 0f, input.y) * speed);
}
}プラットフォーマーのプレイヤーはジャンプする必要があるため、独自の垂直速度を保持してMoveで移動し、InputクラスではなくMoveアクションとJumpアクションを読み取ります。Unityでは、1フレームにつきMoveまたはSimpleMoveを1回呼び出すことが推奨されています。歩行と落下を同じ呼び出しに含めることで、isGroundedはその移動全体の状態を示します。
チャレンジ
中級プレイヤーからプラットフォーマーを始めましょう。Player スクリプトには、speed(5)、jumpHeight(1.5)、gravity(-9.81)、controller、そして落下用のvelocityがあります。MoveアクションとJumpアクションをStartで一度だけ取得し、Updateでは次の処理を行います。
- Moveは、プレイヤーを毎秒
speedユニットの速度で移動させます。x軸に沿って右と左、z軸に沿って前と後ろへ移動します。 - 重力は毎フレーム、
gravity * Time.deltaTimeをvelocity.yに加算します。コントローラーが接地していて、velocity.yが0未満の場合は、まずvelocity.yを-2に設定し、地面に押し付けられた状態を保ちます。 - 接地中にJumpを押すたび、
velocity.yをMathf.Sqrt(jumpHeight * -2f * gravity)に設定します。これにより、jumpHeightユニットの高さまでジャンプします。Jumpを押し続けてもジャンプは1回だけで、空中ではジャンプできません。 - 歩行の移動と
velocityを合わせたものにTime.deltaTimeを掛けて、controller.Moveを1回呼び出します。
Playを押して最初のプラットフォームへジャンプし、続いてCheckを押します。
自分で試してみよう
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
[SerializeField] private float speed = 5f;
[SerializeField] private float jumpHeight = 1.5f;
[SerializeField] private float gravity = -9.81f;
private CharacterController controller;
private Vector3 velocity;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
// Moveアクションで歩き、Jumpアクションでジャンプし、重力で落下する
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。