【Unity】Vector3.MoveTowardsを使って1マスずつ移動する方法
ここでは下の動画のように、移動時にある一定の大きさのマスから外れることなく、1マスずつ移動する方法を説明します。

この動画はUnity1weekという1週間ゲームジャムで作ったゲームを元にしています。実際の操作感を知りたい場合は以下のリンクからプレイできますので、試してみてください。
ゲームはこちらからプレイできます環境
- Unity 2017.1.0f3
このページの構成
ポイント
- 手順としては以下のとおりです。
- ① 現在の位置が移動開始時に指定した目的地と同じか確認する(移動中かどうかを判定する)。
- ② 移動中でなければ入力を受け付け、移動後の位置を算出する。
- ③ Vector3.MoveTowardsを使って移動する。
スクリプト全文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController_simple : MonoBehaviour { Vector3 MOVEX = new Vector3(0.64f, 0, 0); // x軸方向に1マス移動するときの距離 Vector3 MOVEY = new Vector3(0, 0.64f, 0); // y軸方向に1マス移動するときの距離 float step = 2f; // 移動速度 Vector3 target; // 入力受付時、移動後の位置を算出して保存 Vector3 prevPos; // 何らかの理由で移動できなかった場合、元の位置に戻すため移動前の位置を保存 Animator animator; // アニメーション // Use this for initialization void Start () { target = transform.position; animator = GetComponent<Animator> (); } // Update is called once per frame void Update () { // ① 移動中かどうかの判定。移動中でなければ入力を受付 if (transform.position == target) { SetTargetPosition (); } Move (); } // ② 入力に応じて移動後の位置を算出 void SetTargetPosition(){ prevPos = target; if (Input.GetKey (KeyCode.RightArrow)) { target = transform.position + MOVEX; SetAnimationParam (1); return; } if (Input.GetKey (KeyCode.LeftArrow)) { target = transform.position - MOVEX; SetAnimationParam (2); return; } if (Input.GetKey (KeyCode.UpArrow)) { target = transform.position + MOVEY; SetAnimationParam (3); return; } if (Input.GetKey (KeyCode.DownArrow)) { target = transform.position - MOVEY; SetAnimationParam (0); return; } } // WalkParam 0;下移動 1;右移動 2:左移動 3:上移動 void SetAnimationParam(int param){ animator.SetInteger ("WalkParam", param); } // ③ 目的地へ移動する void Move(){ transform.position = Vector3.MoveTowards (transform.position, target, step * Time.deltaTime); } } |
処理の説明
Vector3.MoveTowardsについて
全体の処理としてはややこしくないと思うので特に説明することもないのですが、移動時に使用している Vector3.MoveTowards についてだけ簡単に説明します。
Vector3.MoveTowards は「現在地」から「目的地」まで「一定速度」で移動させてくれる関数です。引数の “current” に現在地、”target” に目的地、”maxDistanceDelta” に1フレームの最大移動距離(=速度)を指定することで目的地まで移動させることができます。
公式スクリプトリファレンスpublic static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta);
現在の位置 current から target に向けて移動します。
この関数によって返された値は直線上の current と target の間にある maxDistanceDelta ごとに移動する target 寄りの位置になります。target が maxDistanceDelta よりも近い場合、 返される値は target の位置と同等になります。(すなわち、target 以上には進みません) maxDistanceDelta が負の値だと、target から遠ざかっていきます。
同じような処理をするものとして Vector3.Lerp(Vector3.Slerp) があります。こちらを使うと移動速度が一定ではなくなり、最初と最後の速度が緩やかな、なめらかな移動になります。
ただし1マスずつ減速してしまうので連続移動には向いていません。タップで指定した位置まで移動する場合など、ある程度離れた位置に一気に移動する場合には使えるかも。
