キー入力で球が移動するようスクリプトを書こう
さて、いよいよスクリプトを書いていきます。
…と、その前にRoll-a-Ballについて説明しておきます。
「Roll-a-Ball」はUnityの最も基礎的なチュートリアルで、「球体を転がして立方体を集めて、全て集めたら「You Win!」というTextが表示される」というシンプルなものです。
まずはHierarchyウインドウのPlayerオブジェクトにアタッチされているPlayerControllerスクリプトを開き、中身を全部消して、↓を貼り付けてください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
public Text countText;
public Text winText;
int count;
Rigidbody rb;
float movementX;
float movementY;
float speed = 10;
void Start ()
{
rb = GetComponent<Rigidbody>();
count = 0;
SetCountText ();
winText.text = "";
}
void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movementX = movementVector.x;
movementY = movementVector.y;
}
void FixedUpdate()
{
Vector3 movement = new Vector3(movementX, 0.0f, movementY);
rb.AddForce(movement * speed);
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag ("Pick Up"))
{
other.gameObject.SetActive (false);
count = count + 1;
SetCountText ();
}
}
void SetCountText()
{
countText.text = "Count: " + count.ToString ();
if (count >= 12)
{
winText.text = "You Win!";
}
}
}
まとめて書くと訳がわかりませんが、「OnMove」に注目してください。
void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movementX = movementVector.x;
movementY = movementVector.y;
}
引数として設定している InputValue はInputSystemで使われる型です。
つまり、Playerを動かすためのキーを押した際に、この「OnMove」メソッドを呼ぶように設定すれば動きそうですね。
さて、スクリプトを保存して、一度実行してみると…
なんと! 「移動キーを押したらOnMoveを呼ぶ」という設定をしていないのに、スクリプトを書いただけでもう動きます。
いったいどうなってるのでしょうか?
PlayerオブジェクトのPlayerInputコンポーネントを見てみると、
Default Map: Player となっています。つまり、「ゲームを実行した時点で Player という名前のアクションマップの操作方法を使う」という意味です。
また、少し下を見ると「Behavior: Send Messages」となっています。
では、そのアクションマップの中身はどうなってるのでしょうか?
ProjectウインドウのInputActionAsset→Inspectorウインドウの「Edit asset」ボタンからアクションマップの内容を確認してみると、
Playerというアクションマップの中に、「Move」という名前のアクションが登録されています。
つまり、Input Systemはキーが入力されたら(Send Messagesで)「On+(アクション名)」のメソッドを呼び出すという動きをするわけですね。
なので、アクション名を適当に「Mooooove」とかに変えても、スクリプト側のメソッド名を「OnMooooove」とすれば普通に動きます。
で、そのアクションを選択すると、右側に「ActionType:Value」「ControlType:Vector2」と設定されていることがわかります。
これがOnMoveの引数になっていたわけですね。
さらに、「Move」というアクション名の先頭にある▶ボタンを押すと、そのなかに「▶WASD」という名前のバインドが登録されていて、さらにその▶ボタンを押すと、WASDキーや方向キーが登録されていることがわかります。
これによって方向キーを押すと球体が移動するシステムが構築できていた訳ですね。
…このように、Input Systemは初期設定としてアクションマップが登録されているので、これを編集したり追加したり削除したりして入力回りを整理していく形となります。
ちなみに、そのウインドウの上部にある「Auto Save」にチェックを入れると、編集内容が自動で適用されます。
InputActionAssetを自作してみよう
今度はいまと全く同じ動きをするInputActionAssetを自作してみましょう。
Projectウインドウ右クリック→Create→InputActionsで新たにInputActionAssetを作成し、「PlayerControls」と名付けたら、Edit assetボタンでInputActionsウインドウを開きます。
続いて、左上の+ボタンでアクションマップを作成し、Playerと名付けます。
アクションを選んで右クリック→Renameを選んで名前を「Buttons」と変更します。
▶ボタンでアクションを展開し、そのなかのバインドをクリック、右側のBinding→PathをGamepad→Button Eastを選択します。
ちなみにButton Eastとは…
ゲームパッドのボタンってたいてい右側に4つボタンが並んでますが、パッドによってボタン名が違いますよね。そこでInput Systemでは、ボタンの並びを東西南北で判断する、という形式で判断しているわけです。
しかし、パッドによってはボタンがいくつも並んでいて、「Input Systemでいうどのボタンなのか」がわからない場合もあります。
そんなときは Listen ボタンを選択してから、接続されているデバイスのボタンを実際に押してみましょう。すると、対応するボタンが自動的に割り当てられます。
同じアクションに複数のキーを割り当てたい時は、アクション名の右側にある+ボタン→ Add Binding から追加します。
次に、移動のアクションを作ります。
Moveという名前のアクションを新たに作成し、右側の画面でActionTypeをValue、ControlTypeをVector2に設定しましょう。
▶ボタンでアクションを展開し、<No Binding>と書かれたバインドの項目をクリック、Pathの項目をGamepad→Left Stickと選択しましょう。
これで、移動アクションがゲームコントローラーの左スティックにバインドされました。
保存するかAutoSaveを押して(忘れがち)、ウインドウを閉じましょう。
InputActionAssetが完成しましたので、Playerオブジェクト内のPlayerInputコンポーネントの「Actions」に作成したInputActionAssetをアタッチしてください。
以上で実行すると、先ほどと同様にゲームパッドで球体を操作することができるようになりました。
続いて、キーボードのバインドを追加しましょう。
Moveアクションの右側の+ボタンから Add Up\Down\Left\Right Composite を選択します。
一気にズラっと上下左右のキーが追加されるので、そのバインドを「WASD」と名付けます。
あとは、それぞれのバインドに先ほどの要領でWASDキーを割り当てていきましょう。
さて、キーが多くなり画面がゴチャゴチャしてきました。さまざまなデバイスのバインドを整理するために、「コントロールスキーム」を追加します。
左上の No Control Schemes → Add Control Scheme...を選択し、Keyboardと名付け、+ボタンからKeyboardデバイスを選択します。
Requirements(必須かどうか)を「Required(必須)」にして、Saveします。
※実際は全て「Optional」でいいと思いますが…
同じ要領で、「Gamepad」というコントロールスキームも作成し、Requirementsは「Optional」にしておきましょう。
続いて、各バインドにスキームを割り当てます。バインドを選択して、該当するUse in control schemeにチェックを入れましょう。
これで、左上のコントロールスキームからデバイスを選ぶと、そのデバイスのバインドだけが表示されるようになりました。
…チュートリアルの導入部分は以上です。続きをもっと詳しく知りたいかたはこちらから公式チュートリアルをご確認ください。
お疲れ様でした!