Menu
CoddyTech

入力アクション

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

キーを一つずつテストすると、スクリプトがキーボードに依存してしまいます。代わりに、アクションはプレイヤーが行う操作を表し、プロジェクト側で、それをトリガーするキー、スティック、ボタンを指定します。新しいUnity 6プロジェクトにはアクションのセット(プロジェクト全体のアクションとして設定されたInputSystem_Actionsアセット)が付属しており、そのPlayerマップにはMove(WASD、矢印キー、ゲームパッドの左スティック)、Look(マウスまたは右スティック)、Attack(マウスの左ボタンとEnter)、Interact(E、押し続ける)、Crouch(C)、Jump(Spaceとゲームパッドの南ボタン)、PreviousとNext(1と2)、Sprint(Left Shift)があります。これらは最初から有効になっており、InputSystem.actions.FindAction("Jump")で名前を指定して取得できます。この横視点のクレーンゲームでは、x軸とy軸方向に移動し、Jumpでつかみます。

using UnityEngine;
using UnityEngine.InputSystem;

public class ClawCrane : MonoBehaviour
{
    public float speed = 3f;

    private InputAction moveAction;
    private InputAction jumpAction;

    void Start()
    {
        moveAction = InputSystem.actions.FindAction("Move");
        jumpAction = InputSystem.actions.FindAction("Jump");
    }

    void Update()
    {
        Vector2 input = moveAction.ReadValue<Vector2>();
        transform.position += new Vector3(input.x, input.y, 0f) * speed * Time.deltaTime;

        if (jumpAction.WasPressedThisFrame())
            Debug.Log("Grab!");
    }
}

アクションはStartで一度だけ取得し、InputActionフィールドに保持します。MoveはVector2を返します。xはキーでの左右、yは上下を表し、値は正規化されるため、WとDを同時に押すと(1, 1)ではなく(0.71, 0.71)になります。クレーンは横視点なので、高さにyを使います。上から見たゲームでは、yをzに使います。ボタンアクションはキーと同じように応答します。WasPressedThisFrame()、WasReleasedThisFrame()、IsPressed()を使います。間違いをすると、2つの問題が発生します。名前のスペルを間違えると、FindActionはnullを返します(最初に読み取る際にNullReferenceExceptionが発生します)。また、MoveはVector2を保持するため、キーを押したとたんにMoveでReadValue<Vector3>()を使うとInvalidOperationExceptionが発生します。

challenge icon

チャレンジ

中級

測量士を動かし、プロジェクトのアクションを使って旗を立てましょう。

  1. Start()で、InputSystem.actions.FindAction("Move")、"Jump"、"Attack"を使ってmoveAction、jumpAction、attackActionを設定します。
  2. Update()で、moveAction.ReadValue<Vector2>()にspeedを掛けて移動します。yの値はz方向に使います。
  3. jumpAction.WasPressedThisFrame()のときにPlant()を呼び出し、Attackを押したときにPullUp()を呼び出します。

「プレイ」を押し、旗を3本立ててからクリックして1本引き抜きます。その後、「確認」を押します。

自分で試してみよう

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Surveyor : MonoBehaviour
{
    public float speed = 4f;
    public int flags = 3;
    public GameObject flagPrefab;

    private InputAction moveAction;
    private InputAction jumpAction;
    private InputAction attackAction;
    private List<GameObject> planted = new List<GameObject>();

    void Start()
    {
        // Move、Jump、Attackのアクションを見つける
    }

    void Update()
    {
        // Moveで歩き、Jumpが押されたらPlant()、Attackが押されたらPullUp()を呼び出す
    }

    void Plant()
    {
        if (flags == 0) return;
        Vector3 spot = new Vector3(transform.position.x, 0.75f, transform.position.z);
        planted.Add(Instantiate(flagPrefab, spot, Quaternion.identity));
        flags--;
        Debug.Log("Flags left: " + flags);
    }

    void PullUp()
    {
        if (planted.Count == 0) return;
        GameObject last = planted[planted.Count - 1];
        planted.RemoveAt(planted.Count - 1);
        Destroy(last);
        flags++;
        Debug.Log("Flags left: " + flags);
    }
}

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

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