ボールを飛ばしたり、車を動かしたり、ゲーム内のオブジェクトを動かしたい!
本記事の内容
・Unityでオブジェクトにスピードを持たせる方法
・Unityでオブジェクトの挙動(回転や移動)に制限を掛ける方法
前回の記事のおさらい
現実の物理的な挙動をするにはRigidbodyとColliderが必要
前回の記事では、Unityで現実の物理的挙動を行うには、RigidbodyとColliderが必要という解説をしました。今回は、前回の解説記事のうち、触れていない「加速と摩擦と回転」について解説します。
前回の解説記事は以下にあります。
加速
物体に力を加えて加速させるにはプログラムから
ゲームの中で物体を加速させるシーンは、一例ですがこのようなケースがあります。
- サッカーゲームでシュートするときに、ボールを向いている方向に飛ばす
- レーシングゲームで車がアクセルを踏んでスタートする
- プレイヤーキャラクターを左右・上下(ジャンプ)に動かす
- 落ち物パズルで、↓ボタンを押したら加速して落とす
このようなケースにおいても、Rigidbodyは活躍します。今回は、プレイヤーの移動・ジャンプして進むケースを例にして解説していきます。
キーボードの入力に応じて左右に移動し、スペースを押したらジャンプするキャラクターを作ってみましょう。
左右への移動は、左右への加速する処理を使います。ジャンプする処理は、上方向への加速する処理を使います。(アタリマエ・・・)
まずは事前準備から。適当なキャラクターの画像をゲーム内に配置して、Rigidbody2DとCollider(BoxでもCupseleでも良いです)を設定しましょう。
また、キャラクターが地面に立てるように、地面にも当たり判定をつけておきましょう。当たり判定はColliderコンポーネントを設定するんでしたね。
次に、スクリプトをAIに作成してもらいます。このようなスクリプト作成指示を出してみました。(ChatGPT4を使っています)
ChatGPTへのプロンプト
あなたはUnityのエンジニアです。Unityで2Dゲームを制作しています。
キャラクターのスクリプトを作成してください。キャラクターの処理として実装したい内容は以下の通りです。
・キーボードの入力で左右に移動
・キーボードのSpaceキーを押すとジャンプ移動
作成されたスクリプトはこちらです。
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 5f; // キャラクターの移動速度
public float jumpForce = 10f; // ジャンプの力
private Rigidbody2D rb; // Rigidbodyコンポーネントへの参照
private bool isGrounded = true; // 地面にいるかどうか
// 最初に一度だけ呼ばれるメソッド
void Start()
{
// Rigidbodyコンポーネントを取得
rb = GetComponent<Rigidbody2D>();
}
// フレームごとに呼ばれるメソッド
void Update()
{
// 水平方向の入力を取得 (-1から1)
float moveInput = Input.GetAxis("Horizontal");
// Rigidbodyを使ってキャラクターを左右に移動
rb.velocity = new Vector2(moveInput * moveSpeed, rb.velocity.y);
// Spaceキーが押されたらジャンプ
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
isGrounded = false; // ジャンプ後は一時的にジャンプ不可にする
}
}
// 他のオブジェクトとの衝突を検出するメソッド
void OnCollisionEnter2D(Collision2D collision)
{
// 地面に触れているか確認
if (collision.collider.tag == "Ground")
{
isGrounded = true;
}
}
}
まずはスクリプトを作成し、キャラクターのオブジェクトにアタッチしてみましょう。
次に、このコードを読み解いてみましょう。
変数の解説
まず、変数として、moveSpeed
、jumpForce
この2つは、float型のパラメータです。コメントのとおり、キャラクターの移動を制御している値です。
rb
は、参照先です。今回Rigidbody2Dの機能を使うため、影響を与える先のRigidbody(プレイヤーの物理挙動に影響を掛けたいので、プレイヤーのRigidbodyを割り当てる必要があります)を取得しています。
isGrounded
は、地面にいるかを判定するbool型のフラグです。地面にいる間しかジャンプは出来ない(二段ジャンプを除く)ので、いま地面にいるか、空中にいるかを判定する項目ですね。
関数(メソッド)の解説
次は関数についてです。
- Start:Update文でRigidbody(物理演算)処理を行うために、一度だけ実行されるRigidbody2Dを取得する処理です。
- Update:ゲームプレイ中毎フレーム実行される処理です。ユーザの入力があったかを検知して処理を行います。
- OnCollisionEnter2D:物体に接触した時に実行する関数です。
また、OnCollisionEnter2D(Collision2D collision)の処理の中に、collision.tag == "Ground"
という内容があります。
これは、Unityのタグという機能を使って、プレイヤーが接触している相手のオブジェクトが地面か、それ以外かを判定します。この制御を行うためには、地面のオブジェクトに、Groundという名前のTagを設定する必要があります。
タグを追加を選択し、
「+」ボタンを押して、Tagを追加。
地面のオブジェクトにタグを設定。
コードの読み方については、こちらの記事で解説しているので参考にしてください。
これで再生してみると、キーボードの左右入力で、キャラクターが動くようになり、スペースキーでジャンプが出来ます。
動きがぎこちないですが、このパラメータを調整することで、マシになります。
また、Spaeキーを押した時のAddForceという処理は、物体に力を加えるイメージです。現実と同じで、物体が重ければ重いほど力を入れても吹き飛びません。ちなみに質量の場合、1なら1KGで計算されています。
うまくジャンプ出来ないときは、質量の設定も確認してみるといいでしょう。
この動きとキャラクターが歩くアニメーションを再生すれば、一気にキャラクターに命が宿りますね!
加速をする処理のバリエーション
加速の掛け方にはいくつか種類があります。今回のスクリプトでは、AddForce
を使いましたが、爆発などで一気に加速する場合や、徐々に加速するなど、様々なケースによって力の加え方の使い分けが可能です。
それぞれの使い分けは、こちらの記事が詳しく解説しているので、よかったら参照ください。
回転や位置を固定して移動させる方法
Constraintで動きを制限して動かす
前提として、Unityや3Dソフトでは、空間をX軸、Y軸、Z軸で表現します。
UnityではX軸が左右、Y軸が上下、(3Dの場合のみ)Z軸が前後を指しています。
2.5Dゲーム(3D空間を2Dの視点で移動するゲーム、スマブラとかそうですね)を作る場合や、キャラクターがダメージを受けて吹っ飛ぶ時に回転させずに吹き飛ばしたい場合など、一定の方向には動かさず物理演算を行いたいケースがあります。
そういう場合に、使うのがConstraintのオプションです。
例えば、このマリトッツォが密集した場所で、Rigidbodyを持っており、Constraintの制御がない場合は、密集して回転します。しかし、Constraintを掛けることで回転をせずに集合することが出来ます。
Constraintは、こちらから設定できます。
落ち物パズルなど、回転させたくなケースで活用できますね!
Rigidbodyを使う時の注意事項
最後に、Rigidbodyを使う時に少しだけ注意すべき点があります。それは、
大量のオブジェクトで使うと処理が重くなる
ことです。
特にスマホ向けでゲームを作ろうとしている場合、何百ものオブジェクトでRigidbodyを多用するとスマホが熱くなったり、カクつきの原因になるので、Rigidbodyを使わなくも良い処理は使わない(例えばアニメーションで動かす)ようにするとよいです。
まとめ
以上、よく使うRigidbodyについての解説でした。使えると非常にゲームの質が上がるのでぜひ使い方をマスターしましょう!!
それでは、素敵なゲーム制作ライフを!
コメント
コメント一覧 (1件)
[…] 【動かせ!】UnityのRigidbody・Colliderを使って物体を加速させよう […]