Unityでキャラクターを動かしてみよう。
Unity上でキャラクターを動かす。ゲームの基本ですね。2D上でもいいし、3Dでも構いません。どんな方法が思いつきますか?
まずは、結論から。Unity上でキャラクターを動かす方法は3つあります。
- Transformを使う(位置情報を直接操作する)
- Rigidbodyを使う(力を加える)
- Character Controllerを使う
他にもいろいろと駆使すればできる事はあるかもしれませんが、基本はこの3つです。
ゲーム内で主人公やNPCが動いているのはおおむねこれらの機能で動いている(はず)です。
では、実際にどのようになっているのでしょうか?詳しく見てみましょう。
キャラクターが動くということ
そもそもキャラクターが動くということはいったいどういう事でしょうか?例えば、コントローラーやキーボードの右や左を押すとキャラクターも右に左に移動します。このとき内部で何が起こっているのか考えてみます。
キャラクターが動くというアクションは、プレイヤーの入力を受けて、ゲーム内のキャラクターに反映させる一連のプロセスです。このプロセスは、いくつかの重要なステップに分けて考えることができます。
入力の検出
まず、プレイヤーがコントローラーやキーボードの右や左のボタンを押すと、この入力はUnityの入力システムによって検出されます。Unityでは、Input
クラスというコードを使用して具体的なキー入力やマウスの動きを取得します。これは、水平方向(右や左)の入力を-1
から1
の範囲で取得し、プレイヤーが右を押せば1
、左を押せば-1
という値を返します。
入力の処理
取得した入力値をもとに、キャラクターの位置や状態を更新する必要があります。これには、キャラクターに設定されたTransform
やRigidbody
、CharacterController
などのコンポーネントが使用されます。
ここで、先ほどの3つに分かれるわけです。
物理的な反応
特にRigidbody
を使用している場合、Unityの物理エンジンが介入し、重力や他の物理的な力も計算に入れる必要があります。この物理演算により、キャラクターは実際の物理法則に基づいて動き、例えば摩擦や質量の影響を受けます。
以上のステップを通じて、Unity内でキャラクターを動かす一連のプロセスが完了します。つまり、入力を数値で受け取りそれで位置情報を更新したり、力を加えたりして、画像や3Dモデルのキャラクターを動かします。
位置情報を直接操作(Transform)
Unityでオブジェクトを動かす基本的な方法の一つに、Transform
コンポーネント(位置情報などの集合体)を通じて位置情報を直接操作する方法があります。ここでは、シンプルなキューブを例に、位置情報を使ったオブジェクトの移動方法とそのメリット・デメリットについて説明します。
UnityのTransformコンポーネント
Unity内のすべてのオブジェクトにはTransform
コンポーネントがあります。このコンポーネントは、オブジェクトの位置(position)、回転(rotation)、スケール(scale)を管理しています。今回は、特に位置に焦点を当てて説明します。
シンプルなキューブの作成
まず、Unityエディタで新しい3Dプロジェクトを開始し、シーンにキューブを追加します。
- 「ヒエラルキーウィンドウ」から「3D オブジェクト」→「キューブ」を選択してキューブをシーンに追加します。
- キューブを選択し、Inspectorウィンドウで位置、回転、スケールを調整します。
まずはキューブを出します。ヒエラルキーの+から出せますよ。
すると、シーンビューに立方体のキューブが出現します。
このキューブにはTransformプロパティがありますね。位置、回転、スケールが置かれています。
入力に基づく位置の更新
キーボードの左右の矢印キーから入力を受け取り、それをキューブの位置更新に利用します。そのための手順は次のとおりです。
- 「プロジェクトウィンドウ」から「スクリプト」を作成
- 「スクリプト」にコードを記述
- その「スクリプト」をキューブに「アタッチ」
プロジェクトウィンドウにある+ボタンからスクリプトを押して、スクリプトを作成します。
*バージョンによってスクリプトの表示は異なるようです「C#スクリプト」「MonoBehaviourスクリプト」など
作られたスクリプトはAssetsなどにあります。名前を「Player」としました。エディタでこれを開きましょう。
コードはこんな感じです。最小限のコードですがこれを「アタッチ」することで、キューブが左右に動くようになります。
using UnityEngine;
public class Player : MonoBehaviour
{
//移動速度
public float speed = 5.0f;
void Update()
{
//左右ボタンの入力値受け取り
float moveHorizontal = Input.GetAxis("Horizontal");
//入力値を移動に変換
transform.position += new Vector3(moveHorizontal, 0, 0) * speed * Time.deltaTime;
}
}
スクリプトのアタッチについて動画のとおりです。インスペクターにドラック&ドロップでできます。
アタッチしたらゲームをスタートさせます。すると、次のとおり動きます。
以上、位置情報によるキャラクターの移動です。
位置情報で移動させることのメリットとデメリット
メリット
- 直感的で簡単:位置を直接変更する方法は非常に直感的で、理解しやすいです。プログラミング初心者にとっても扱いやすい方法です。
- 完全な制御:物理エンジンに依存せずにオブジェクトの位置を正確に制御できます。細かい位置調整や一定の速度での移動が必要な場合に適しています。
デメリット
- 物理的なリアルさに欠ける:
Transform
を使用した移動は物理エンジンを介さないため、衝突処理や摩擦などの物理的な要素を自動で処理しないです。これにより、リアルな物理反応を期待する場合には不向きです。 - スムーズな移動に工夫が必要:フレームレートの変動に弱く、高速で移動するオブジェクトが不自然に見えることがあります。スムーズなアニメーションを実現するためには、追加の調整が必要です。
力を加える(Rigidbody)
Unityでのオブジェクトの動かし方として、「Rigidbody」を使った方法は、物理法則に基づいたリアルな動きをシミュレートするのに適しています。この章では、Rigidbodyコンポーネントを使用して力を加える方法でキューブを動かすプロセスを解説します。
Rigidbodyの基本
Rigidbody
はUnityの物理エンジンにオブジェクトを組み込むためのコンポーネントで、重力や摩擦といった物理的な影響をオブジェクトに適用できます。これを使うことで、リアルな衝突、反発、重力の効果を簡単にシミュレーションできます。
キューブにRigidbodyを追加
- シーン内にキューブを作成します(ヒエラルキーウィンドウ → 3D オブジェクト → キューブ)。*位置情報のときと同じ。
- キューブを選択し、Inspectorパネルで「Add Component」ボタンをクリックします。
- 「Physics」カテゴリから「Rigidbody」を選択して追加します。
キューブのインスペクターにコンポーネントを追加します。
追加されたRigidbodyはインスペクターにに表示されます。質量や摩擦などが追加されます。
力を加えるスクリプト
次に、キューブがキーボードの入力に応じて動くように、以下のスクリプトを作成し、キューブにアタッチします。先ほどのPlayerスクリプトを次のように変更します。
using UnityEngine;
public class Player : MonoBehaviour
{
Rigidbody rb;
//加える力の倍率
public float force = 10f;
void Start()
{
//リジッドボディを変数に格納
rb = GetComponent<Rigidbody>();
}
void Update()
{
//左右の入力を受け取り
float moveHorizontal = Input.GetAxis("Horizontal");
//入力された値をVector3型に変更させる
Vector3 movement = new Vector3(moveHorizontal, 0, 0);
//倍率と入力からチカラを加える
rb.AddForce(movement * force);
}
}
このコードでは、Update
メソッド内でユーザーの入力を取得し、それに基づいて力を加えています。AddForce
メソッドを使用して、キューブに水平方向の力を加えることで移動を実現しています。 では、動かしてみましょう。 その前に、リジッドボディで重力が付いたので、このまま再生すると落下してしまいます。 そのため、床を置いてから再生してみます。どうなるでしょうか?
ちょっと早すぎるようですね。力の倍率を下げましょう。また、床との摩擦で回転してしまっています。回転をオフにしましょう。
インスペクターのリジッドボディで回転の調整が可能です。
では、再挑戦です。
いい感じになりました。このような動きが物理演算による移動です。
力を加える方法のメリットとデメリット
メリット
- リアリズム: Rigidbodyを使用すると、Unityの物理エンジンが自動で重力や衝突などを処理するため、よりリアルな動きが可能です。
- インタラクティブ: 環境や他のオブジェクトとの物理的なインタラクションが自然に発生します。
デメリット
- 制御が難しい: 力を加えるとオブジェクトの動きが予測しづらくなることがあります。特に、連続した力の加え方には注意が必要です。
- パフォーマンス問題: 物理計算はCPUを多く使用するため、多数のオブジェクトにRigidbodyが使われる場合、パフォーマンスが低下することがあります。
Character Controller
Unityでのキャラクター操作に特化したコンポーネントとしてCharacter Controller
があります。このコンポーネントは、特に人間や動物などのキャラクターの移動に適しており、地形との衝突処理や階段の上り下りなどを自動で扱うことができます。この章では、Character Controller
を使ってキャラクターを動かす基本的な方法を紹介します。
Character Controllerの基本
Character Controller
は、物理エンジンを使わずにキャラクターの移動を管理するコンポーネントです。これにより、開発者はキャラクターの動きを直接制御でき、滑らかで自然な動きを実現できます。
シンプルなキャラクターの設定
- シーンにキャラクターとなるキューブを配置します。
- オブジェクトを選択し、Inspectorパネルで「Add Component」をクリックし、「Character Controller」を検索して追加します。
Physics内にあるCharacter Controllerコンポーネントを追加します。
移動スクリプトの追加
それでは、以下のようにPlayerスクリプトを変更します。
using UnityEngine;
public class Player : MonoBehaviour
{
private CharacterController controller;
//スピードの値
public float speed = 6.0f;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{ //入力を追加
float moveHorizontal = Input.GetAxis("Horizontal");
//入力値をVector3に変換
Vector3 move = new Vector3(moveHorizontal, 0.0f, 0.0f);
//コントローラーに値を入力
controller.Move(move * speed * Time.deltaTime);
}
}
では、このスクリプトをアタッチして動かしましょう。
Rigidbodyは外しているため重力はかかりません。
Character Controllerのメリットとデメリット
メリット
- 衝突検出と処理の自動化: 地形や障害物との衝突を自動的に処理し、キャラクターが自然に動けるようにします。
- 簡単な操作性: 物理法則を直接扱わなくても、キャラクターの移動を簡単に制御できます。
デメリット
- 限定的な物理応答:
Character Controller
は物理エンジンを使用しないため、重力や摩擦などの物理的な相互作用が限定的です。 - カスタマイズの制限: 一部の高度な動きや特殊なインタラクションを実現するには、スクリプトによる追加のカスタマイズが必要です。
まとめ
以上、キャラクターの動かし方についてみてきました。最後に簡単にまとめてみましょう。
- 位置情報で動かす(位置の更新)
- 力を加えて動かす(物理演算)
- Character Controllerで動かす(Unityの機能)
これら3つを使う事でキャラクターを動かすことができます。これらはどれがいいというわけではなく、どのようなゲームにするべきかで何を使うかを考えるべきものです。
動きだけではなくゲーム全体で考える事が必要ですので、よく考えて何を使うか決めてください。