0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Godot 4.0】スマホ3Dゲームを作るための勉強 その3 Node3Dで位置と向きを設定する

Last updated at Posted at 2023-02-22

ゲームエンジンgodot4.0で3Dスマホゲームを作りたいと思いますが、その前にお勉強しています。
Godot_v4.0-rc1_win64.exe.zipを使用しています。

目的

 Node3Dを理解する

Godot3.5の時はSpatialという名前でしたが、4.0で名称がNode3Dに変更しました。

Node3Dとは

 Godot 3DエンジンはNode3Dを継承(inheritance)するノードを3D空間に表示します。
 Node3Dを継承しているノードとは、子ノードを追加するウィンドウでNode3Dにぶら下がっているすべてのノードです。今まで登場したMeshInstance3Dや、DirectionalLight3D、Camera3DもNode3Dを継承しているため3D空間に配置することができます。

GodotParts.pptx - PowerPoint 2023_02_21 10_17_00.png

 MeshInstance3Dを選択して、右側のインスペクタを表示すると上の方には自身のMeshInstance3Dの設定・属性値が表示されています。継承元の情報・属性は下の方に表示されていて、Node3Dの情報・属性などがあります。他のNode3Dを継承したノードもインスペクタの下の方にNode3Dがあります。

GodotParts.pptx - PowerPoint 2023_02_21 10_24_22.png

global座標とlocal座標

 シーンのルートノードを配置する座標系をglobal座標系といいます。
 ノードを親子関係にした場合、子は親のlocal(ローカル)座標系に存在します。

 ここでは雪だるまをつくって、ローカル座標の便利さを確認しようと思います。
 

 新規プロジェクトを作成して、3Dシーンを押下してNode3Dを追加します。 
 Node3Dを右クリックしてMeshInstance3Dを追加してください。名称をMeshInstance3D_bodyに変更してください。
 インスペクタのMeshInstance3DのMeshのをクリックして、新規SphereMeshを選択します。

 Node3Dを右クリックしてMeshInstance3Dを追加してください。名称をMeshInstance3D_headに変更してください。
 インスペクタのMeshInstance3DのMeshのをクリックして、新規SphereMeshを選択します。
 MeshInstance3D_headを選択して、Node3DのTransformのpositonのyを0.7mに設定してください。
 次にMeshInstance3Dの球をクリックしてください。Meshの詳細パラメータが表示されます。
 radius(半径)を0.5から0.3mにして、Heightを0.6mにすると少し小さいに球になります。

 雪だるまが完成しました。

(_) TestGlobalLocal - Godot Engine 2023_02_21 10_55_50.png

 では体を移動しましょう。
 MeshInstance3D_bodyを選択して、ギズモの赤い矢印をドラッグして左にうごかしましょう。
 頭(MeshInstance3D_head)はついてきませんね。
 このときのインスペクタ内のNode3D-Transform-positionのXの値を覚えておきましょう。
 
(_) TestGlobalLocal - Godot Engine 2023_02_21 10_59_21.png

 では次にMeshInstance3D_headを選択して、ギズモの赤い矢印をドラッグして左に動かして、体の上に頭が乗るようにしましょう。
 このときのインスペクタ内のNode3D-Transform-positionのXの値を確認すると、MeshInstance3D_bodyと同じような値になっていると思います。
 
(_) TestGlobalLocal - Godot Engine 2023_02_21 13_02_26.png

 でも本当は体を動かしたときは、頭も一緒についてきてほしいですよね。
 その場合は、ベースとするノードを決めて、ほかの一緒に動いてほしいノードはその子供にします。

 (下記操作をする前に、MeshInstance3D_headとMeshInstance3D_bodyのXの値は同じにしてください。)

 シーンの中でMeshInstance3D_headをドラッグアンドドロップしてMeshInstance3D_bodyに重ねると、MeshInstance3D_bodyが親でMeshInstance3D_headが子供になってぶら下がるようになります。

キャプチャ 2023_02_21 13_17_49.png

 あたらめてMeshInstance3D_bodyを選択してギズモを表示して、赤い矢印をドラッグすると頭がついてきます。
 この時にMeshInstance3D_headを選択してインスペクタ内のNode3D-Transform-positionのXを確認すると、0mになっていると思います。

 はじめの例ではglobal座標系にbody(MeshInstance3D_body)とhead(MeshInstance3D_head)の位置を定義していました。そのためbodyを動かしてもheadはそのままの位置でした。
GodotParts.pptx - PowerPoint 2023_02_23 12_08_24.png

 後の例ではノードを親子にしました。
 Node3Dは親子にすると、子のNode3D(head)は親(body)の位置からの差分(位置、回転)を表すようになります(local transform)。今回の例では、頭の位置は体の中心からY軸方向に0.7mにあるという相対的な位置関係を表しています。
 そのため、bodyを移動しても、head(子)はbody(親)との位置関係を保持するため、headがbodyについてきます。headのx座標はbodyとの関係を保持しているので、0mのままです。
GodotParts.pptx - PowerPoint 2023_02_23 12_08_27.png

 Godotの3D表示内の赤、青、緑の軸の座標系、3次元空間全体をglobal座標系といいます。
 それに対して、個々のノードが持つ座標系をローカル座標系といいます。

 これはとても便利な仕組みで、複数のノードで構成されているキャラクターを動かすときに、ひとつの親ノードを動かすだけで全部ついてくるし、多関節なものもうまく管理することができます。

global座標とlocal座標の注意点

 ノードを追加するときの階層を意識する必要があります。
 BodyとGunをもつ砲台から弾丸を発射する場合に、その弾丸を追加する例で考えます。

 砲台Node3D_Palayer_01 親ノードにBody01とGun01とGun01から発射されたBullet01をぶら下げています。
 砲台Node3D_Palayer_02 親ノードはBody02とGun02のみが子ノードとして、Bullet02はルートノードにぶら下げています。

C__Users_hathr_Videos_Captures 2023_02_22 9_24_14.png

 砲台Node3D_Palayer_01 を選択して移動すると、砲台Node3D_Palayer_01の子のBullet01も一緒についてきてしまいます。多くの場合意図しない動作になります。
 砲台Node3D_Palayer_02選択してを移動すると、Bullet02はついてきません。

(_) node_3d.tscn - 03_Node3D_2 - Godot Engine 2023_02_22 9_19_20.png

 こうしてエディターで見ると当たり前でわかりやすいのですが、プログラムからBulletを追加するときには、背景=global座標系を持つノードにBulletを追加する必要があります。

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?