Menu
CoddyTech

足場に乗ろう

CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 51/60。

CharacterController は、その足元にあるものに運ばれません。動くプラットフォームの上ではその場にとどまり、プラットフォームが下を滑って離れていきます。transform.position を動かしても効果はありません。次の Move は、物理演算が最後に認識した位置から始まり、変更が取り消されるからです。

そこで、プレイヤーはプラットフォームの移動量を自身の移動量に加えます。OnControllerColliderHit(ControllerColliderHit hit) は、Move が接触するコライダーごとに実行されます。下からの接触では hit.normal.y は 1 に近い値になります。クレートを同じ方法で運ぶフェリーの例です。

private Ferry ferry;

void OnControllerColliderHit(ControllerColliderHit hit)
{
    if (hit.normal.y > 0.7f && hit.gameObject.TryGetComponent(out Ferry f))
    {
        ferry = f;
    }
}
challenge icon

チャレンジ

中級

プレイヤーが動くプラットフォームに乗れるようにしましょう。

  1. Playerにprivate MovingPlatform platform;とOnControllerColliderHitを追加します。hit.normal.y > 0.5fで、オブジェクトがMovingPlatformを持っている場合、それをplatformに保持します。
  2. Update()で、(move + velocity) * Time.deltaTimeをVector3 motionに入れます。platform != nullの場合は、platform.deltaを加えて、platform = nullを設定します。
  3. controller.Move(motion)を呼び出します。

「プレイ」を押してプラットフォームに飛び乗ると、運ばれます。その後、「確認」を押します。

自分で試してみよう

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 InputAction moveAction;
    private InputAction jumpAction;
    private Vector3 velocity;

    void Start()
    {
        controller = GetComponent<CharacterController>();
        moveAction = InputSystem.actions.FindAction("Move");
        jumpAction = InputSystem.actions.FindAction("Jump");
    }

    void Update()
    {
        if (controller.isGrounded && velocity.y < 0f)
        {
            velocity.y = -2f;
        }

        Vector2 input = moveAction.ReadValue<Vector2>();
        Vector3 move = new Vector3(input.x, 0f, input.y) * speed;

        if (jumpAction.WasPressedThisFrame() && controller.isGrounded)
        {
            velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
        }

        velocity.y += gravity * Time.deltaTime;
        controller.Move((move + velocity) * Time.deltaTime);
    }
}

本格的なゲームを作るのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド