Unity2Dアクション「移動」ゲーム制作講座
はじめに
2Dアクションゲームで、重要な要素の1つである「移動」
今回は、2Dアクションゲームを1つ完成させる連載の「移動」のUnity2D制作講座です。
今回利用する「PlayerController.cs」全体コードサンプル
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField] float addMoveSpeed = 5f;
[SerializeField][Range(0, 20)] float fHorizontalDampingMovingSpeed = 10f;
[SerializeField][Range(0, 1)] float fHorizontalDampingBasic = 0.5f;
[SerializeField][Range(0, 1)] float fHorizontalDampingWhenStopping = 0.5f;
[SerializeField][Range(0, 1)] float fHorizontalDampingWhenTurning = 0.5f;
private Rigidbody2D rb2d;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
MovePlayer();
}
void MovePlayer()
{
float moveSpeed = Input.GetAxisRaw("Horizontal") * addMoveSpeed;
if (Mathf.Abs(moveSpeed) < 0.01f)
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingWhenStopping, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
else if (Mathf.Sign(moveSpeed) != Mathf.Sign(rb2d.velocity.x))
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingWhenTurning, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
else
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingBasic, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
rb2d.velocity = new Vector2(moveSpeed, rb2d.velocity.y);
}
}
[addMoveSpeed]
- 型: float
- 説明: プレイヤーの水平移動速度のスカラー倍率。Input.GetAxisRaw(“Horizontal”)から得られる入力値にこの値を掛けることで、最終的な移動速度が決定されます。
[fHorizontalDampingWhenStopping]
- 型: float (0 から 1 の範囲)
- 説明: プレイヤーが停止しているときに適用される速度減衰率。値が大きいほど、キャラクターはより速く停止します。この減衰率は、速度が非常に小さいときに使用され、キャラクターが滑らかに停止するのを助けます。
[fHorizontalDampingMovingSpeed]
- 型: float (0 から 20 の範囲)
- 説明: 水平移動時の基本的な速度減衰を調整するスカラー。この値はTime.deltaTimeとともに計算に使用され、速度減衰の適用速度を調整します。
[fHorizontalDampingBasic]
- 型: float (0 から 1 の範囲)
- 説明: プレイヤーが移動しているときに適用される基本的な速度減衰率。この減衰率は通常の移動中に使用され、キャラクターの動きが自然に感じられるようにします。
[fHorizontalDampingWhenTurning]
- 型: float (0 から 1 の範囲)
- 説明: プレイヤーが方向転換する際に適用される速度減衰率。この減衰率は、方向転換時に適用され、キャラクターが急激に方向を変えるときにも滑らかな動きを維持するのを助けます。
[rb2d]
- 型: Rigidbody2D
- 説明: キャラクターのRigidbody2Dコンポーネントへの参照。Unityの物理エンジンを通じてキャラクターの移動や他の物理的相互作用を制御するために使用されます。
手順1:Playerゲームオブジェクトの作成
移動スクリプト「PlayerController.cs」をアタッチするためのゲームオブジェクトを作成します。
ヒエラルキーウインドウの何もない空間を右クリック、出現したクリックメニューの「2D Object」を選択し、
その中にある「Sprites」から、
「Square」をクリックしてゲームオブジェクトを作ります。
インスペクターから「Square」という名前を「Player」に変更してください。
手順2:PlayerController.csの作成と変数宣言
Playerゲームオブジェクトの作成が完了した後、このゲームオブジェクトを動かせるよう、スクリプトを作ります。
Projectビューで右クリックし、クリックメニューを表示させます。
「Create」を選択し、
「C# Script」を選択して、C#スクリプトを新規作成します。
名前を「PlayerController.cs」にしてください。
ダブルクリックでスクリプトを開きます。すると以下のようなコードが記載されています。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerContoller : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
「// Start is called before the first frame update」と「// Update is called once per frame」は不要なコメントなので削除して、以下のようにします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerContoller : MonoBehaviour
{
void Start()
{
}
void Update()
{
}
}
それでは、早速スクリプトを作成します。まず、スクリプト上で利用する変数を宣言します。
[addMoveSpeed]
[SerializeField] float addMoveSpeed = 5f;
- 型: float
- 説明: プレイヤーの水平移動速度のスカラー倍率。Input.GetAxisRaw(“Horizontal”)から得られる入力値にこの値を掛けることで、最終的な移動速度が決定されます。
[fHorizontalDampingWhenStopping]
[SerializeField][Range(0, 20)] float fHorizontalDampingMovingSpeed = 10f;
- 型: float (0 から 1 の範囲)
- 説明: プレイヤーが停止しているときに適用される速度減衰率。値が大きいほど、キャラクターはより速く停止します。この減衰率は、速度が非常に小さいときに使用され、キャラクターが滑らかに停止するのを助けます。
[fHorizontalDampingMovingSpeed]
[SerializeField][Range(0, 1)] float fHorizontalDampingBasic = 0.5f;
- 型: float (0 から 20 の範囲)
- 説明: 水平移動時の基本的な速度減衰を調整するスカラー。この値はTime.deltaTimeとともに計算に使用され、速度減衰の適用速度を調整します。
[fHorizontalDampingBasic]
[SerializeField][Range(0, 1)] float fHorizontalDampingWhenStopping = 0.5f;
- 型: float (0 から 1 の範囲)
- 説明: プレイヤーが移動しているときに適用される基本的な速度減衰率。この減衰率は通常の移動中に使用され、キャラクターの動きが自然に感じられるようにします。
[fHorizontalDampingWhenTurning]
[SerializeField][Range(0, 1)] float fHorizontalDampingWhenTurning = 0.5f;
- 型: float (0 から 1 の範囲)
- 説明: プレイヤーが方向転換する際に適用される速度減衰率。この減衰率は、方向転換時に適用され、キャラクターが急激に方向を変えるときにも滑らかな動きを維持するのを助けます。
[rb2d]
private Rigidbody2D rb2d;
- 型: Rigidbody2D
- 説明: キャラクターのRigidbody2Dコンポーネントへの参照。Unityの物理エンジンを通じてキャラクターの移動や他の物理的相互作用を制御するために使用されます。
以上で「移動」に関する変数の宣言は完了です。以下のスクリプトの通りにしてください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerContoller : MonoBehaviour
{
[SerializeField] float moveSpeed;
[SerializeField] float addMoveSpeed = 5f;
[SerializeField][Range(0, 20)] float fHorizontalDampingMovingSpeed = 10f;
[SerializeField][Range(0, 1)] float fHorizontalDampingBasic = 0.5f;
[SerializeField][Range(0, 1)] float fHorizontalDampingWhenStopping = 0.5f;
[SerializeField][Range(0, 1)] float fHorizontalDampingWhenTurning = 0.5f;
private Rigidbody2D rb2d;
void Start()
{
}
void Update()
{
}
}
手順3:Rigidbody2Dの参照
Playerのゲームオブジェクトに物理現象を適応させるコンポーネント「Rigidbody2D」をアタッチします。
インスペクターの下にある「Add Component」をクリックし、
「Rigidbody2D」を検索してクリックします。
以下のスクリーンショットのようにアタッチされていれば完了です。
次に、アタッチしたRigidbody2Dをスクリプト上で参照・操作する為に、変数「rb2d」にRigidbody2Dを入れます。この際、スクリプトが呼ばれた時=「Start」に入れてください。
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
これで変数「rb2d」の中に、先ほどアタッチしたRigidbody2Dを入れる事ができました。
手順4:移動メソッド「MovePlayer」の作成
今までに宣言した変数を利用して、実際にPlayerのゲームオブジェクトが動くよう、以下の通りにメソッドを作成します。
void MovePlayer()
{
moveSpeed = Input.GetAxisRaw("Horizontal") * addMoveSpeed;
if (Mathf.Abs(moveSpeed) < 0.01f)
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingWhenStopping, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
else if (Mathf.Sign(moveSpeed) != Mathf.Sign(rb2d.velocity.x))
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingWhenTurning, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
else
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingBasic, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
rb2d.velocity = new Vector2(moveSpeed, rb2d.velocity.y);
}
この「MovePlayer」メソッドは、Unityゲームエンジンを使ったプレイヤーキャラクターの水平方向の動きを制御するためのものです。このメソッドでは、キーボードの入力を受け取り、それに基づいてプレイヤーの速度を計算し、Rigidbody2D コンポーネントを使用して物理的な移動を行います。
float moveSpeed = Input.GetAxisRaw("Horizontal") * addMoveSpeed;
Input.GetAxisRaw(“Horizontal”) は、水平方向(左右)のキーボード入力を検出し、-1、0、または1の値を返します。つまり左キーが押されている場合は-1、右キーが押されている場合は1、何も押されていない場合は0となります。
この入力値に addMoveSpeed(プレイヤーの基本移動速度を制御する変数)を掛け合わせることで、実際の移動速度 moveSpeed を計算します。これにより、プレイヤーが左右に移動する際の速度が決定されます。
if (Mathf.Abs(moveSpeed) < 0.01f)
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingWhenStopping, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
Mathf.Abs(moveSpeed) は moveSpeed の絶対値を取得します。この行は、moveSpeed が非常に小さい値(0.01未満)であるかどうかを確認しています。これは、プレイヤーがほとんど動いていないか静止している状態を検出するためです。
fHorizontalDampingWhenStopping は、プレイヤーが停止している際の減速率を表します。
「Mathf.Pow(1f – fHorizontalDampingWhenStopping, Time.deltaTime * fHorizontalDampingMovingSpeed)」の計算で moveSpeed を減速させます。ここで、Time.deltaTime は前のフレームとこのフレームの間の時間(秒)を表し、フレームレートに依存せずに一定の減速を実現することができます。
else if (Mathf.Sign(moveSpeed) != Mathf.Sign(rb2d.velocity.x))
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingWhenTurning, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
この条件は moveSpeed と rb2d.velocity.x(現在の水平速度)の符号が異なる場合にTrueとなります。つまり、プレイヤーが移動方向を反転した場合です。
fHorizontalDampingWhenTurning は方向転換時の減速率を表します。
Mathf.Pow 関数による計算で moveSpeed を指数的に減少させ、方向転換時の自然な減速を実現します。
else
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingBasic, Time.deltaTime * fHorizontalDampingMovingSpeed)
}
fHorizontalDampingBasic は基本的な減速率を表します。
こちらも Mathf.Pow 関数を用いて moveSpeed を時間の経過とともに減少させます。
rb2d.velocity = new Vector2(moveSpeed, rb2d.velocity.y);
最終的に計算された moveSpeed を Rigidbody の x 軸の速度として設定します。y 軸の速度(rb2d.velocity.y)は変更されません。これにより、プレイヤーの垂直方向の動き(ジャンプや落下など)には影響せず、水平方向のみ制御します。
手順5:「PlayerController.cs」の完成
お疲れ様です。以上でプレイヤーの「移動」スクリプトは完成です。以下の通りになります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField] float addMoveSpeed = 5f;
[SerializeField][Range(0, 20)] float fHorizontalDampingMovingSpeed = 10f;
[SerializeField][Range(0, 1)] float fHorizontalDampingBasic = 0.5f;
[SerializeField][Range(0, 1)] float fHorizontalDampingWhenStopping = 0.5f;
[SerializeField][Range(0, 1)] float fHorizontalDampingWhenTurning = 0.5f;
private Rigidbody2D rb2d;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
MovePlayer();
}
void MovePlayer()
{
float moveSpeed = Input.GetAxisRaw("Horizontal") * addMoveSpeed;
if (Mathf.Abs(moveSpeed) < 0.01f)
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingWhenStopping, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
else if (Mathf.Sign(moveSpeed) != Mathf.Sign(rb2d.velocity.x))
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingWhenTurning, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
else
{
moveSpeed *= Mathf.Pow(1f - fHorizontalDampingBasic, Time.deltaTime * fHorizontalDampingMovingSpeed);
}
rb2d.velocity = new Vector2(moveSpeed, rb2d.velocity.y);
}
}
手順5:インスペクターでの設定について
記述エラーが無ければ、Unityのアプリケーションに戻ると、以下のスクリーンショットのような画面がインスペクターに追加・表示されます。
ここでテストプレイをしながら数値を調整し、好みのパラメータにしてください。
手順6:テストプレイ
それでは実際にテストプレイをしたいのですが、着地する地面と当たり判定が無いので準備します。
プレイヤーのゲームオブジェクトを作った時と同じように、「Floor」のゲームオブジェクトを新規作成します。
次に、地面として配置するために、位置と大きさを調整します。「Floor」のインスペクターの「Transform」で以下のように設定します。
Position | X 0 , Y -3 , Z 0 |
Scale | X 18 , Y 1 , Z 1 |
配置が完了したら、「Player」「Floor」それぞれのオブジェクトに当たり判定を設けます。
まず、「Player」のインスペクターの下部にある「Add Component」を選択し、
「Box Collider 2D」を検索し、クリックしてアタッチします。
「Floor」のゲームオブジェクトにも同様に「Box Collider 2D」をアタッチしてください。
当たり判定が適応されたら、Unityアプリケーションの上部中央にあるプレイボタンを押してテストプレイを開始してください。
「Player」のゲームオブジェクトには「Rigidbody2D」がアタッチされているので、「Gravity」によって重力が発生し、落ちます。そして、「Player」「Floor」には当たり判定があるので地面に接地したようになります。左右キーまたはAキーDキーを押すと左右に移動します。
さいごに
これでUnity2Dアクションゲームの「移動」の制作講座を終了します。
次回は、「ジャンプ」の制作講座を行います。引き続きどうぞよろしくお願い致します。
絵を描いたり、音楽作ったり、ゲーム作ったり、映像作ったりが大好きな平成元年男
職業:デザイナー / IT系専門学校非常勤講師 / 音楽スクール非常勤講師 / その他