3Dゲームを作るチュートリアル
Godot Engine バージョン4.3
このチュートリアルでは、Godot 4.3を使って基本的な3Dゲームを作成する方法を説明します。ゲーム内容は、プレイヤーがシーン内を移動してオブジェクトを収集するというシンプルなものです。
完成するゲーム概要
ゲーム内容: プレイヤーがゴドチューを拾い、スコアを獲得する。
- 目標: 時間内に可能な限り多くのゴドチューを収集する。
- 学べる内容:
- 3Dシーンの構築
- 基本的な3Dプレイヤーの操作
- 簡単なスコアシステムの実装
1. プロジェクトのセットアップ
新しいプロジェクトを作成
- Godot 4.3で新しいプロジェクトを作成します。
- 名前:
Simple3DGame
3Dシーンを作成
- 新しいシーンを作成し、ルートノードとして
Node3D
を選択します。
- シーン名を
Main.tscn
として保存します。
2. ゲームの3D環境を構築
地面の作成
地面ノードを追加
Node3D
の子ノードとしてStaticBody3D
を追加。
- さらにその子ノードに
MeshInstance3D
を追加し、PlaneMesh
を設定。Sizeを1000
に設定します。
- 次にまた子ノードに
CollisionShape3D
を追加し、HeightMapShape3D
を設定。Transform
のScale
を1000
にします。
ライトの追加
環境ライト
- ルートノードに
DirectionalLight3D
を追加してシーン全体を照らします。
- 照射方向を調整します。
- ルートノードに
WorldEnvironment
を追加してEnvironment
を設定して明るさを調整します。
下記のようになっていればOKです!
3. プレイヤーの作成
新しいシーンを作成
- ルートノードとして
CharacterBody3D
を選択。
- 名前を
Player.tscn
として保存します。
プレイヤーモデルを追加
CharacterBody3D
の子ノードにMeshInstance3D
を追加し、CapsuleMesh
を設定します。
CollisionShape3Dの追加
CharacterBody3D
の子ノードにCollisionShape3D
を追加し、形状をCapsuleShape
に設定します。
スクリプトを追加 プレイヤーの動きを制御するために、以下のスクリプトを
Player.tscn
に追加します:extends CharacterBody3D
# プレイヤーの移動に関する定数const SPEED = 5.0 # プレイヤーの移動速度const JUMP_VELOCITY = 4.5 # ジャンプ時の速度
# 物理処理関数(毎フレーム実行される)func _physics_process(delta): # プレイヤーが床に接していない場合(空中にいる場合) if not is_on_floor(): # 床にいない場合、重力を適用 velocity += get_gravity() * delta
# ジャンプボタンが押され、プレイヤーが床にいる場合 if Input.is_action_just_pressed("ui_accept") and is_on_floor(): velocity.y = JUMP_VELOCITY # 垂直方向の速度をジャンプ速度に設定
# プレイヤーの移動入力(X軸とZ軸の方向) var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") # 入力方向に基づいて移動ベクトルを計算 var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction: # 入力があれば、プレイヤーをその方向に移動 velocity.x = direction.x * SPEED velocity.z = direction.z * SPEED else: # 入力がなければ、水平移動の速度を徐々に減速 velocity.x = move_toward(velocity.x, 0, SPEED) velocity.z = move_toward(velocity.z, 0, SPEED)
# 移動処理とスライディング(床との衝突を処理) move_and_slide()
入力マッピングの設定
move_forward
:W
move_backward
:S
move_left
:A
move_right
:D
判定の設定を追加
CharacterBody3D
の子ノードにArea3D
を追加します。
Area3D
の子ノードにCollisionShape3D
を追加し、CapsuleMesh
を設定します。サイズは1.1
にします。
Area3D
の_on_body_entered
をスクリプトと紐付ける。
# 衝突したオブジェクトが指定された条件を満たす場合に呼ばれるfunc _on_body_entered(body): # 衝突したオブジェクトが「Item」カテゴリであるかを確認 if body.get("category") and body.category == "Item": # アイテムを取得したことを示すシグナルを発行 collected.emit() # アイテムオブジェクトをシーンから削除 body.queue_free()
カメラの設定(一人称)
CharacterBody3D
の子ノードにNode3D
を設定してhead
に名前を変更します。プレイヤーの目線の位置に調整します。
- 先ほどの
head
の子ノードにCamera3Dを追加します。
下記のように設定してください。
次に
head
にスクリプトを設定して一人称の動きを設定します。スクリプトに下記のコードを入力してください。
extends Node3D
# マウスの感度var sens = 0.005 # 感度の設定(値が小さいほどマウス移動に対する回転が少なくなる)
# ノードが準備できたときに呼ばれるfunc _ready(): # マウスをキャプチャして、画面外にマウスカーソルが出ないようにする Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) # 入力イベントを処理する関数func _input(event): # マウスの動きイベントかどうかを確認 if event is InputEventMouseMotion: # マウスの水平移動に応じて、親ノードを回転 get_parent().rotate_y(-event.relative.x * sens) # 自身(このノード)をX軸回転させる # マウスの垂直移動に応じて、このノードを回転 rotate_x(-event.relative.y * sens) # 回転角度が-90度から90度の間に収まるように制限(視点が極端に上下に動かないようにする) rotation.x = clamp(rotation.x, deg_to_rad(-90), deg_to_rad(90))
4. ゴドチューの作成
新しいシーンを作成
- ルートノードとして
RigidBody3D
を選択。
- 名前を
Item.tscn
として保存。
アイテムモデルを追加(ゴドチューに設定)
- ゴドチューのMeshはここからダウンロードしてください。
RigidBody3D
の子ノードにMeshInstance3D
を追加し、ゴドチューをドラッグ&ドロップして設定。
CollisionShape3Dを追加
RigidBody3D
の子ノードにCollisionShape3D
を追加し、形状をBoxShape
に設定。
スクリプトを追加 以下のスクリプトを
Item.tscn
に追加:extends RigidBody3D
@export var category = "Item"
下記のようになっていればOKです!
5. スコアシステムの実装
HUDの作成
- ルートノードに
CanvasLayer
を追加。
- 子ノードに
Label
を追加し、名前をScoreLabel
に設定。
- テキストを
Score: 0
に設定。
スコア管理スクリプト 以下のスクリプトを
Main.tscn
に追加:extends Node3D
var score = 0
func _ready(): $Player.connect("collected", self, "_on_item_collected")
func _on_item_collected(): score += 1 $CanvasLayer/ScoreLabel.text = "Score: " + str(score)
6. ランダムなゴドチューの生成
ランダム生成スクリプト 以下のスクリプトを
Main.tscn
に追加:@export var item_scene: PackedScene@export var spawn_area = Vector3(20, 1, 20)@export var object_size = 20
func create_object(): for n in object_size: var item = item_scene.instantiate() item.position = Vector3(randf_range(-spawn_area.x, spawn_area.x), spawn_area.y, randf_range(-spawn_area.z, spawn_area.z)) item.rotation_degrees.y = randf_range(0, 360) add_child(item)
7. ゲームをテストして完成!
最後にゲームを実行して動作を確認します。チュートリアルを通じて、3Dゲームの基本が完成しました!
このチュートリアルをもとに、さまざまな機能を拡張してみてください。質問があればぜひ下記でコメントしてください!
1
100%
最終更新日: 2025/01/30 02:45