今回からプログラムを組み始めます。前回追加したプレイヤーに、移動の操作をできるようにしていきましょう。
スクリプトの作り方
初めに、スクリプトの保存先であるフォルダを作成します。AssetsフォルダにScriptsフォルダを作成しました。
ファイル数が増えると後々管理が大変になりますので、しっかりと整理していきましょう。
次に、スクリプトを作成します。UnityではC#という言語を用いて開発します。プロジェクウィンドウで右クリックをして、「Create > C# Script」を選択します。
これで、C#スクリプトが作成されます。スクリプト名は「PlayerController」としました。
作成したスクリプトをダブルクリックすると、コーディングするために設定しているIDEが開きます。IDEは様々な種類がありますが、私の場合はVisual Studioを使用しています。
Unity Asset Storeでは、Unityで完結できるIDEが販売されています。興味のある方はこちらの記事をご覧ください。
移動のプログラミング
早速、プログラミングしていきましょう。しかしながら、初めてで一からプログラムを組むのは不可能に近いです。完成済みのプログラムを見て、どのような処理がされているか一行一行理解することが大切です。
プログラムを作成しましたので、理解しながらプログラミングしてください。
using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(Rigidbody2D))] [RequireComponent(typeof(CapsuleCollider2D))] public class PlayerController : MonoBehaviour { [SerializeField] private Rigidbody2D rb; [SerializeField] private int moveSpeed; void Update() { rb.velocity = new Vector2(Input.GetAxis("Horizontal") * moveSpeed, rb.velocity.y); } }
それでは、解説していきます。
1~3行目のusingは、他のクラスをPlayerControllerでも使用できるようにするコードです。UnityでC#スクリプトを作成すると、初めから記述されています。
5~6行目は、必要なコンポーネントを定義しています。このコードは記述しなくても動作しますが、定義したコンポーネントは自動で追加されます。コンポーネントを追加し忘れると、思わぬバグが発生する可能性がありますので、記述したほうが安心です。
8行目は、PlayerControllerという作成したスクリプトのクラスを定義しています。MonoBehaviourというクラスを継承していますが、始めのうちはあまり気にしなくても大丈夫です。
10~11行目は、グローバル変数を定義しています。Unityでは、一定の条件を満たすとインスペクターから変数の値を設定できるようになります。[SerializeField]はその条件の一つで、private変数でもインスペクターから値を設定できるようになります。public変数でもインスペクターから値を設定できるようになりますが、思わぬバグを引き起こす原因になります。他のクラスで呼び出す予定のない変数は、極力privateにしましょう。
13行目はUpdate関数といい、フレームごとに呼び出されます。パソコンのスペックによって頻度が変動するため注意が必要です。
15行目は、プレイヤーを移動させる処理です。オブジェクトを移動させるには、位置を直接書き換えたり、物理演算で力を加えたりと様々な方法があります。今回は、物理演算の速度を直接書き換えて移動する方法を採用しました。
Input.GetAxis(“Horizontal”)は、左右の矢印キーまたはAとDキーの入力を-1から1の間で取得します。これに、moveSpeedという変数の値を掛けることとで、移動量を調節できるようにしています。
Vector2とはUnity独自の型で、xとyの値をfloat型で保持します。x方向の速度の値のみを書き換えたいので、yは現在の速度を取得して書き換えています。
以上でプレイヤーを移動させるプログラムは完成です。IDEを閉じる際は、必ず保存してからにしましょう。大抵のIDEの保存のショートカットキーは、「Ctrl + S」です。コーディング中にクラッシュしてしまう可能性はゼロではありません。こまめに保存するように心がけましょう。
スクリプトの追加方法
作成したプログラムのスクリプトを、プレイヤーに追加しましょう。ヒエラルキーウィンドウでPlayerのプレファブを選択した後、インスペクターにPlayerControllerのスクリプトをドラッグ&ドロップします。
すると、Rigidbody 2D・Capsule Collider2D・Player Controllerの3のコンポーネントが追加されます。
インスペクターから設定できるようにした変数、RbとMove Speedの値を設定します。
インスペクターのRigidbody 2DをRbのNoneと書かれている場所にドラッグ&ドロップします。また、Move Speedの値は「3」にしました。
一度プレイボタンを押して、ゲームを実行してみてください。左右に移動するものの、落下し続けてしまう状態であれば正常にコンポーネントを追加できています。
Tilemapに当たり判定を追加
今の状態ではプレイヤーが地面を貫通して、無限に落下してしまいます。それは、Tilemapに当たり判定がないことが原因です。Tilemap Collider 2DというコンポーネントをTilemapに追加して、プレイヤーと地面が衝突するようにしていきます。
ヒエラルキーウィンドウで「Tilemap」を選択します。その後、インスペクターで「Add Component > Tilemap > tilemap Collider 2D」をクリックします。
これで、タイルマップにUnityでColliderと呼ばれている当たり判定を追加できました。
では、再度プレイボタンを押して動作確認してみましょう。
地面と衝突するようになっていれば、正常に当たり判定が追加できています。しかし、移動するとプレイヤーが回転してしまいますね。
物理演算を使用しているので、ボールを転がすと回るのと同じ現象が起きています。
Rigidbodyの回転をフリーズ
プレイヤーが回転しないように、Z軸を固定しましょう。実は簡単にできます。
ヒエラルキーウィンドウでPlayerを選択した後「Rigidbody 2D > Constraints > Freeze Rotation」のZの空白をクリックしてチェックを入れます。
回転しないようにする設定は以上で完了です。
それでは、正常に動作するか確認してみましょう。プレイボタンをクリックします。
元の向きを保ちながら移動できるようになりましたね。しかしながら、今度は壁に向かって移動キーを押し続けると、落下しない不具合が発生しました。
Physics Material 2Dの作り方
Physics Material 2Dは、Rigidbody 2DやCollider 2Dに使用することができます。摩擦係数や弾む強さを設定することができる機能です。
摩擦係数をゼロにして、壁と衝突しても落下するようにしていきましょう。
Projectウィンドウで左クリックした後、「Create > Physics Material 2D」をクリックしてマテリアルを作成します。
Materialsフォルダを作成し、「Assets > Materials」に「Player Material」という名前で保存しました。
Frictionの値を設定することで、摩擦係数を変更できます。「0」に設定しましょう。
プレイヤーのオブジェクトを選択し、インスペクターでRigidbody 2DのMaterialに、先程作成した「Player Material」を設定します。
「Overrides > Apply All」をクリックして、元のプレファブにも適応しましょう。
これで、今までプレイヤーのオブジェクトに変更を加えてきた設定が、プレファブ元にも反映されました。
最後に動作確認をします。プレイボタンをクリックしてください。
壁と衝突しても落下するようになりましたね。
使用アセット一覧
「Unityで2Dアクションゲームの作り方を解説」で紹介・使用するアセットは全て無料のものです。
以下は、現在使用中のアセットです。
次回について
次回は、プレイヤーをジャンプさせるプログラムを組んでいきます。