GDScript:2D上で物体を移動させる
もっとも基本的な2Dノードを動かす方法について解説。
キーボードの左右上下を押したときに画像が動くようにする。
参考ドキュメント:2D movement overview
前準備
プロジェクトを作成し、Node2D/KinematicBody2D/Iconのノードを追加する。
(ノードの追加については2Dプロジェクト作成手順:リンクを参照)
▲!で警告が出ているが気にしない。(衝突判定をしないだけなので問題ない)
KinematicBody2DにGDScriptをアタッチ(追加)する。
入力マップ(インプットマップ)の確認
次にキー入力に対応したイベント名の確認をする。
プロジェクト → プロジェクト設定→入力マップを開く。
この一覧からキーボードの上下左右を押したときのイベント名を確認する。
管理人の環境ではui_left/ui_right/ui_down/ui_upとなっていた。
必要な変数の定義
移動させるために必要な変数を下記のように指定する。
var speed = 150
var velocity = Vector2()
変数は var xxx = yyy の形で宣言する。(xxxが変数名、yyyが値)
var xxxだけでも変数の宣言は出来る。
ただし、型(変数がどのようなものか)を最初に確定しないとバグのもとになるため最初に代表的な初期値を代入する等して型を最初に確定させておくと安全。
動く処理の追加
デフォルトで入っている func _physics_process(delta): 内に動く処理を追加していく。
ちなみにfunc _physics_process(delta):とは毎フレームごとに実行される関数である。刻一刻と変化する処理は基本的にこの中に定義することが多い。
func _physics_process(delta):
#前回フレーム時の値が残らないよう、毎フレームごとに速度パラメータを初期化する
velocity = Vector2()
#キー入力の取得および速度方向の決定(これは後で関数を定義する)
get_key()
#速度方向の正規化と速度ベクトル長
velocity = velocity.normalized() * speed
#動かす
move_and_slide(velocity)
ベクトル変数に.normalized()を加えると長さ1のベクトルに正規化される。
get_key()で右下と言った入力があった場合、ベクトルの長さが√2≒1.414...になってしまい動く速度が1.4倍ほどになってしまう。
それを防ぐために長さ1のベクトルで正規化したうえでspeedをかける。
※ただし、ドラ○エのようなマス目ごとマップで動くような場合には正規化はしないこと。
2Dのノードを動かす場合にはmove_and_slide(ベクトル)を使用する。
キー入力取得
get_key()の関数を定義する。
やることとしては「キー入力の取得」と「取得したキー入力に応じた速度パラメータの方向を指定する」の2つ。
func get_key():
#もし右キーが押されたら、x軸方向へ1を加える。
if Input.is_action_pressed("ui_right"):
velocity.x += 1
#もし左キーが押されたら、x軸方向から1を減らす。
if Input.is_action_pressed("ui_left"):
velocity.x -= 1
#もし下キーが押されたら、y軸方向へ1を加える。
if Input.is_action_pressed("ui_down"):
velocity.y += 1
#もし上キーが押されたら、y軸方向から1を減らす。
if Input.is_action_pressed("ui_up"):
velocity.y -= 1
x軸方向は+が右、-が左。y軸方向は+が下、-が上。
※y軸方向は数学的な意味と逆なので注意。
例えば右キーを押した場合にはvelocityは(1,0)となる。
全体まとめ
これまでの内容をすべて書くと以下のコードになる。これで実行するとキー入力に応じて画像が動く。
extends KinematicBody2D
var speed = 150
var velocity = Vector2()
func _physics_process(delta):
velocity = Vector2()
get_key()
velocity = velocity.normalized() * speed
move_and_slide(velocity)
func get_key():
if Input.is_action_pressed("ui_right"):
velocity.x += 1
if Input.is_action_pressed("ui_left"):
velocity.x -= 1
if Input.is_action_pressed("ui_down"):
velocity.y += 1
if Input.is_action_pressed("ui_up"):
velocity.y -= 1