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を設定。TransformScale1000にします。
ライトの追加
環境ライト
  • ルートノードに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として保存。
アイテムモデルを追加(ゴドチューに設定)
  • 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ゲームの基本が完成しました!

これでゲームが完成です!完成したゲームを遊びたい方はこちらから!

完成したプロジェクトのダウンロードはこちらから!


このチュートリアルをもとに、さまざまな機能を拡張してみてください。質問があればぜひ下記でコメントしてください!
最終更新日: 2025/01/30 02:45

コメント