2021/04/01(木) [n年前の日記]
#1 [godot] Godot Engine の Pathノードについて調べてる
Godot Engine 3.2.3 x64上で、物体を動かすために、何かしらの軌道を指定したい。そういう時には Pathノードを使えるのではないかと思えてきたので調べていたり。
Pathノードを使うと、軌跡だか、軌道だか、曲線だか、とにかくそういう感じの情報を用意することができる。また、PathFollowノードを使うと、Pathを辿るような動きを作ることができる。
3Dで使うPathノードと、2D使うPath2Dノードがあるので、まずは2D版の Path2Dノードを使ってみて、どういう感じのノードなのか把握したい。以下の動画を参考にして作業。
_Godot Engine - Know Your Nodes: PathFollow2D - YouTube
_Enemies Follow a Path & Spawn Tower Defense Style ~ Godot 3.2 Tutorial - YouTube
Pathノードを使うと、軌跡だか、軌道だか、曲線だか、とにかくそういう感じの情報を用意することができる。また、PathFollowノードを使うと、Pathを辿るような動きを作ることができる。
3Dで使うPathノードと、2D使うPath2Dノードがあるので、まずは2D版の Path2Dノードを使ってみて、どういう感じのノードなのか把握したい。以下の動画を参考にして作業。
_Godot Engine - Know Your Nodes: PathFollow2D - YouTube
_Enemies Follow a Path & Spawn Tower Defense Style ~ Godot 3.2 Tutorial - YouTube
◎ Path2Dノードについて。 :
テスト用のプロジェクトを新規作成して、以下のようなノード構成にしてみた。
Mainノード(Node2D)の下に、Path2Dノードを追加して、その下に、PathFollow2Dノードを追加した。また、PathFollow2Dノードだけでは分かりづらいので、その下に、任意のテクスチャ画像を表示できる TextureRectノードも追加した。
Path2Dノードを選択すると、編集ウインドウ?の右上に、Path編集をするためのツールアイコンが増える。それらを使って、下の形のような Path を作成した。
Path編集用のツールは、それぞれ以下のようになっている。
左側から…。
点追加ツールで、各点を追加していった後、点選択ツールで、Shiftキーを押しながら点をドラッグすると接線ハンドルを出すことができる。接線ハンドルをドラッグしてやれば、曲線の曲がり具合を調整できる。
PathFollow2Dノードを選択して、Offset値を変更してやれば、Path2Dの形に沿って PathFollow2Dノードの位置が変わっていくことが分かる。また、Rotate がオンになっていれば、Path2Dの向きに応じて PathFollow2D も回転する。ちなみに、Loop がオンになっていれば、最後まで移動した後、また最初から移動するらしい。
一応、TextureRect についても設定項目を載せておく。ここでは 64x64ドットの飛行機のpng画像をテクスチャとして指定している。
Pivot Offset を弄れば、回転する際の基準点の位置を変更できる。また、Rotation で、回転角度も変更できる。
一応、使った画像も置いときます。CC0 / Public Domain ってことで。
_airplane_01_64x64.png
PathFollow2Dノードを動かすために、PathFollow2Dノードにスクリプトを追加する。内容は以下。
_pathfollow2d.gd
何をやっているかと言えば…。_process(delta) が毎フレーム呼ばれるので、その中で、PathFollow2Dノードの Offset値を更新している。これで、時間経過と共に、PathFollow2DノードがPath2Dノードの形をなぞるように動くはず。
Webブラウザ上でも動くように、HTML5でエクスポートしてみた。一応、手元の Firefox 87.0 x64 上では動いてる。
_path2d_test1.html
これで、Path2Dノードを辿る動きが実現できた。
Mainノード(Node2D)の下に、Path2Dノードを追加して、その下に、PathFollow2Dノードを追加した。また、PathFollow2Dノードだけでは分かりづらいので、その下に、任意のテクスチャ画像を表示できる TextureRectノードも追加した。
Path2Dノードを選択すると、編集ウインドウ?の右上に、Path編集をするためのツールアイコンが増える。それらを使って、下の形のような Path を作成した。
Path編集用のツールは、それぞれ以下のようになっている。
左側から…。
- 点を選択
- コントロールポイントを選ぶ
- 点を空きスペースに追加
- 点を削除
- 曲線を閉じる
点追加ツールで、各点を追加していった後、点選択ツールで、Shiftキーを押しながら点をドラッグすると接線ハンドルを出すことができる。接線ハンドルをドラッグしてやれば、曲線の曲がり具合を調整できる。
PathFollow2Dノードを選択して、Offset値を変更してやれば、Path2Dの形に沿って PathFollow2Dノードの位置が変わっていくことが分かる。また、Rotate がオンになっていれば、Path2Dの向きに応じて PathFollow2D も回転する。ちなみに、Loop がオンになっていれば、最後まで移動した後、また最初から移動するらしい。
一応、TextureRect についても設定項目を載せておく。ここでは 64x64ドットの飛行機のpng画像をテクスチャとして指定している。
Pivot Offset を弄れば、回転する際の基準点の位置を変更できる。また、Rotation で、回転角度も変更できる。
一応、使った画像も置いときます。CC0 / Public Domain ってことで。
PathFollow2Dノードを動かすために、PathFollow2Dノードにスクリプトを追加する。内容は以下。
_pathfollow2d.gd
extends PathFollow2D export var speed = 300 func _ready(): pass # Replace with function body. func _process(delta): set_offset(get_offset() + speed * delta) # if loop == false and get_unit_offset() >= 1: # queue_free()
何をやっているかと言えば…。_process(delta) が毎フレーム呼ばれるので、その中で、PathFollow2Dノードの Offset値を更新している。これで、時間経過と共に、PathFollow2DノードがPath2Dノードの形をなぞるように動くはず。
- get_offset() で、現在の Offset値を取得できる。
- set_offset() で、Offset値を更新できる。
- delta には、前回フレームから現在フレームまでの経過時間が秒単位で入ってくる。例えば、60FPSで動いてるなら、deltaには、1秒/60フレーム = 約0.016秒が入ってくる。
Webブラウザ上でも動くように、HTML5でエクスポートしてみた。一応、手元の Firefox 87.0 x64 上では動いてる。
_path2d_test1.html
これで、Path2Dノードを辿る動きが実現できた。
◎ Offset と Unit Offset。 :
PathFollow2Dノードには、Offset と Unit Offset というプロパティがある。
- Offset : Path の長さに対してどのあたりかを示す。
- Unit Offset : Path の全長を1としたときにどのあたりかを示す。0.0 - 1.0 の値を取る。
◎ Pathノードを試す。 :
Path2D、PathFollow2Dノードを使って2D的な使い方は分ったので、Path、PathFollowノードを使って3D的にはどうなるのか試してみる。
Spatialノードを Mainノードとして、以下のようなノード構成にしてみた。
PathFollowノードに追加したスクリプトは以下。
_pathfollow.gd
Webブラウザ上で動かせるように、HTML5でエクスポート。
_path3d_test1.html
2Dの時と似たような感じで使えた。
しかし、何週もさせているうちに、向きがおかしくなっていくことに気づいた。
何かの誤差が溜まっていくのだろうか…?
PathFollowノードには、Rotation Mode というプロパティがあるけれど、ココを変えると結果が違ってくるようではある…。
Rotation Mode = Y だとずれていくけれど、Oriented にすれば何周してもずれなくなっていく。
_PathFollow - Godot Engine (stable) documentation in English
Pathノードの Curve3D、up_vector_enabled が true になってないと、PathFollow の Rotation Mode で Oriented が使えないらしい。
ちなみに、PathFollow の Offset ではなく、Unit Offset を更新していくようにスクリプトを書き替えて試してみたけど、ループの境目、Unit Offset を 1.0 から 0.0 に変更するタイミングで、向きが180度変わってしまう状態になった。なんでだろ…。
Spatialノードを Mainノードとして、以下のようなノード構成にしてみた。
PathFollowノードに追加したスクリプトは以下。
_pathfollow.gd
extends PathFollow export var speed = 20 func _ready(): pass # Replace with function body. func _process(delta): set_offset(get_offset() + speed * delta)
Webブラウザ上で動かせるように、HTML5でエクスポート。
_path3d_test1.html
2Dの時と似たような感じで使えた。
しかし、何週もさせているうちに、向きがおかしくなっていくことに気づいた。
何かの誤差が溜まっていくのだろうか…?
PathFollowノードには、Rotation Mode というプロパティがあるけれど、ココを変えると結果が違ってくるようではある…。
Rotation Mode = Y だとずれていくけれど、Oriented にすれば何周してもずれなくなっていく。
_PathFollow - Godot Engine (stable) documentation in English
Pathノードの Curve3D、up_vector_enabled が true になってないと、PathFollow の Rotation Mode で Oriented が使えないらしい。
ちなみに、PathFollow の Offset ではなく、Unit Offset を更新していくようにスクリプトを書き替えて試してみたけど、ループの境目、Unit Offset を 1.0 から 0.0 に変更するタイミングで、向きが180度変わってしまう状態になった。なんでだろ…。
[ ツッコむ ]
以上です。