入力アクション
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が発生します。
チャレンジ
中級測量士を動かし、プロジェクトのアクションを使って旗を立てましょう。
Start()で、InputSystem.actions.FindAction("Move")、"Jump"、"Attack"を使ってmoveAction、jumpAction、attackActionを設定します。Update()で、moveAction.ReadValue<Vector2>()にspeedを掛けて移動します。yの値はz方向に使います。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プレイグラウンド