Unityでキャラクターを移動させたいときの方法の備忘

テクノロジー・プログラミング プログラミング

Unityで作成したオブジェクトを動かすプログラムの備忘です。2Dプログラムで見下ろしアクション型のゲームを作成中なので、その前提で記載していますが、基本的な考え方は他のゲームでも同じはずです。

2023/12/21追記:unityroomでゲームを公開しました。以下で書いた移動方法を使っていますので、よければ見てみてください。

前提知識

前提として、Unityでオブジェクトの場所を座標軸で把握しているという知識が必要です。

座標軸というのは、X軸、Y軸、Z軸という学生の時の数学で習う座標のことで、2D見下ろし型であれば、X軸が横、Y軸が縦の座標になります(Z軸まで入ると高さの概念も加わりますが、2Dでは知識不足のため不明)。

X軸とY軸のイメージ

Unityにおいて移動するとは、この座標軸を動かすという意味になります。

移動方法

方法は結構色々あるようですが、ここでは3つほど記載しておきます。

Rigidbodyの機能を使う

作成時はこちらを参考にさせていただきました。

UnityにはRigidbodyという物理演算を行うためのComponentがデフォルトで用意されています。
これを使えば、落下する動きや衝突した時の動きなどを簡単に作ってくれます。

プログラム側でvelocityに移動方向を指定してあげれば、指定した移動方向に移動してくれます。
指定する際はVector2で二次元の方向を指定します。斜め方向の移動も可能です(というより、意識しないと自動で斜め移動もしてしまいます)。

以下のサンプルコードは、キーボードの入力を受けて対象のオブジェクトを動かすコードになります。ほとんど前述の参考サイトそのままですが、斜め移動が出来ないようにif文で制御しています。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // 移動速度の指定
    [SerializeField]
    private int moveSpeed;

    // オブジェクトのRigidbody2Dをアタッチする
    public Rigidbody2D rb;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        // 斜め移動ができないように、Horizontalの入力を優先する
        if (Input.GetAxisRaw("Horizontal") != 0)
        {
            rb.velocity = new Vector2(Input.GetAxisRaw("Horizontal"), 0).normalized * moveSpeed;
        }
        else
        {
            rb.velocity = new Vector2(0, Input.GetAxisRaw("Vertical")).normalized * moveSpeed;
        }
    }
}

なお、RigidbodyのComponentの設定によって、予期せぬ動きをしてしまう場合があるので、注意してください。
詳細は書きませんが、自分の場合、見下ろし型2Dで作成しているので、デフォルトの設定からGravity Scaleを0に(自動でYのマイナス方向に動く動作をなしにする)、Freeze RotationのZにチェックを入れて(障害物にぶつかったとき回転してしまう)から動かしています。

オブジェクトのベクトルを指定する

移動先のベクトルを直接指定する方法です。移動しているように見えますが、実際には細かい瞬間移動を繰り返しているようなイメージになります。そのため、colliderの衝突判定がうまく機能しない場合があるようです(自分が動かしている限りでは、発生していないですが)。

サンプルコードは以下の通りです。自分の位置(this.transform.position)を把握して、移動方向にベクトルを足し算(引き算)することで移動させます。この場合だとx軸にプラス=右側への移動になります。

float moveSpeed  = 1.0f;
this.transform.position += new Vector3(moveSpeed   * Time.deltaTime, 0f, 0f);

Time.deltaTimeというのは、移動速度を一定にするために必要なようです。深い理解は出来ていないですが、環境によってCPUの処理速度が異なるものを調整してくれるみたいで、自分の環境でもこれを除外するとオブジェクトが早く動いたり遅く動いたりと確かに一定になりませんでした。
深く考えずに、とりあえず入れておいたほうがよいコマンドだと思います。

移動先のベクトルを指定する

ベクトルを指定するもう一つの方法です。先ほどは、オブジェクトそのもののベクトルを指定しましたが、こちらではオブジェクトが向かう先の目的地を指定して、一定の速度で移動させてくれます。

目的地なく一定速度でまっすぐ動かしたいときは前述の方法、動かす先が決まっている場合はこちらの方法といった使い分けになると思います。

float moveSpeed  = 1.0f;
move_target = this.transform.position+ new Vector3(1f, 1f, 0f); // 現在の場所から1fずつ右上の場所
this.transform.position = Vector3.MoveTowards(this.transform.position, move_target, moveSpeed * Time.deltaTime);

引数は、スタート地点、ゴール地点、スピード、という風に指定してあげます。

おわり

以上、Unityでオブジェクトを移動させる3つの方法でした。

自分が現在使ったものだけをあげたので、他にもあるようですが、おおよそは上記で事足りるのではないかなと思います。参考になれば幸いです。

※記事中の画像イメージには、ぴぽや倉庫様とUnity Assetのこちらのアセットの素材を使用しています。

コメント

タイトルとURLをコピーしました