Unity上でオブジェクト(GameObject)を移動する方法を3つ解説します。
なお、今回解説する3つは使い分けが可能なので、自分の実装したい機能に最も適した方法を使ってください。
結論から言いますと、オブジェクトを移動する方法は以下の3つです。
<オブジェクトの移動方法>
・位置(ポジション)を直接変更する方法
・速度(ヴェロシティ)を変更する方法
・加速度(フォース)を与える方法
位置、速度、加速度の数値をいじることでUnity上ではオブジェクトを移動させることができるのは、なんとなくでも納得いくかと思います。
それぞれの移動方法のメリットは、以下の通り。
位置:Unityエディタ上で簡単に確認できる。位置をそのまま変更できる。
速度:移動する速度を設定できる。一定速度で移動させたいときに便利。
加速度:物理演算を元にオブジェクトが移動する。現実空間での挙動を再現したいときに有効。
Unityは物理エンジンなので、現実空間と同様に力や速度を計算することができます。そのため以上の方法でオブジェクトが移動できるわけですね。
前置きが長くなりましたが、それぞれの移動方法について解説していきます。
使用するスクリプトには”TransformObject”というファイル名を付けました。
わかりやすく解説するため、コードは以下の部分を使いまわします。やっていることはRigidBodyの定義だけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TransformObject : MonoBehaviour { //RigidBody定義 public Rigidbody rigidbody; void Start() { rigidbody = this.GetComponent<Rigidbody>(); } // Update is called once per frame void Update() { //オブジェクト移動用コード } } |
解説時は、update{}の中にオブジェクト移動用のコードを入れています。
■位置(ポジション)を直接変更する方法
位置を直接変更して移動すると、以下のような挙動になります。
この動画ではわかりずらいですが、位置を直接変更しているため、瞬間移動しつつ移動しているイメージです。
コードは以下の通り。
1 2 3 4 5 |
// Update is called once per frame void Update() { this.transform.position += new Vector3(0.1f, 0, 0); } |
this.transform.positionが、オブジェクトの位置を示します。そこへ毎フレーム一定の数値を足し合わせています。
Update{}に記述されたコードは、毎フレームごとに処理が行われるため、このコードでは(0.1f, 0, 0)の値が、オブジェクトの位置に毎フレームおきに加わります。
この位置を直接変更し移動する方法の利点は、移動方法の中でも理解しやすいことです。
Unity上で常に以下のPositionの部分で数値を確認できるので、数学がわからなくても簡単に理解できるかと思います。
なお、この方法はRigidBodyをアタッチしていないオブジェクトでも移動することができます。コード1つで移動できるので大変便利です。
■速度(ヴェロシティ)を変更する方法
次に速度を変更し、オブジェクトを移動する方法を解説します。
まずは結果から。
回転してしまいますね。
回転している原因は、RigidBodyコンポーネントで重力を有効にしているためです。RigidBodyで重力をオフにしてみましょう。
すると以下のように回転せずに移動できるようになります。※RigidBody>Constraints>Freeze Rotationを調節しても回転せずに移動できます。
オブジェクトの速度を変更して移動させるコードの解説です。
1 2 3 4 5 6 7 8 9 10 11 12 |
public class TransformObject : MonoBehaviour { Rigidbody rigidbody; void Start() { rigidbody = this.GetComponent<Rigidbody>(); } // Update is called once per frame void Update() { this.rigidbody.velocity = new Vector3(1f, 0, 0); } } |
重要なポイントは、RigidBodyを定義している点と、this.rigidbody.velocityを(1.0f, 0, 0)の一定値にしていることです。これで一定速度で移動することができます。
速度を変更する方法はRigidBodyがアタッチされていないオブジェクトでは使えませんので注意してくださいね。
速度を変更してオブジェクトを移動させる方法のメリットは、一定速度で移動できる点です。
■加速度(フォース)を与える方法
最後に加速度を与える方法です。
※オブジェクトが回転する場合は、RigidBody>重力をオフorRigidBody>Constraints>Freeze Rotationを有効化
力が加わり続けるため、移動する速さがどんどん速くなっていますね。
コードを解説します。
1 2 3 4 5 6 7 8 9 10 |
Rigidbody rigidbody; void Start() { rigidbody = this.GetComponent<Rigidbody>(); } // Update is called once per frame void Update() { Vector3 force = new Vector3(1, 0, 0); this.rigidbody.AddForce(force, ForceMode.Force); } |
毎フレームおきに、オブジェクトへ(1, 0, 0)の力を加えています。
AddForceは以下のような記述式です。
1 |
AddForce(加えるベクトル, ForceMode.力の与え方); |
第一引数に力として与えたいベクトル、第二引数で力を与える方法について指定します。
第二引数のForceModeは4つほどあります。
Force | 質量を使用して、リジッドボディへ継続的な力を加えます。 |
Acceleration | その質量を無視して、リジッドボディへ継続的な加速を追加します。 |
Impulse | その質量を使用し、リジッドボディにインスタントフォースインパルスを追加します。 |
VelocityChange | 質量を無視して、リジッドボディにインスタント速度変化を追加します。 |
※Unity公式レファレンスより引用(https://docs.unity3d.com/ja/current/ScriptReference/ForceMode.html)
ForceMode.Forceが実空間上の物理演算に一番近いです。現実と同じような挙動をしてほしいときはForceモードを使いましょう。
なお、現実と同様に、与える力が小さいと、オブジェクトがうまく動かない場合があります。例えば洗濯機を指で押しても動かないのと同じことです。
この場合はオブジェクトの質量を軽くするか、与える力を大きくすることで、オブジェクトを移動させることができます。
■オブジェクトを移動させる方法の違いは?
最後に、それぞれの違いについて簡単にまとめておきます。
・位置(ポジション)を直接変更する方法
・Unityエディタ上で常に確認できるため、初心者におすすめ
・位置そのものを変更するため、瞬間移動のように移動する
・飛び飛びで移動するため、接触判定するときにおかしくなる可能性があるので注意
・RigidBodyがなくても使える
・速度(ヴェロシティ)を変更する方法
・一定速度で動かしたいときに便利
・速度制限したいときに有効
・RigidBodyがないと使えない
・加速度(フォース)を与える方法
・現実と同じような挙動をしてほしいときはこれ
・質量も考慮して力を設定する必要がある
・RigidBodyがないと使えない
以上3つの移動方法を覚えておけば使い分けて所望の動きを実装できるかと思います。
最後まで読んでいただきありがとうございました。