godot-3d-gameplay について
Godot の既存アーキテクチャを保ちながら、3D ゲームプレイを実装するスキルです。物理、カメラ、ライティング、レンダリングを扱い、事前調査とゲーム内検証に基づいて設計します。
主な機能
- 01プロジェクト設定と既存シーンの調査
- 02ゲーム上の役割に応じた物理ボディの選択
- 03物理フレームで動く型付きプレイヤー制御
- 04カメラリグと入力アクションの設定
- 05視認性を考慮した環境ライティング調整
- 06ゲームプレイ、表示、性能のテスト
活用シーン
- 01既存の Godot プロジェクトへのプレイヤー制御追加
- 02レベル形状に応じたカメラ衝突の組み込み
- 03対象レンダラーに合わせたライティング調整
- 04斜面や足場での移動の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pbzona/ godot-skills --skill godot-3d-gameplayインストール後、Claude Code で/godot-3d-gameplayを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/controllers-and-cameras.mdenvironments-and-lighting.mdphysics-testing-and-debugging.md詳細
Godot 3D ゲームプレイ
物理、カメラ、レンダリングを連携させたシステムとして、3D ゲームプレイを実装します。汎用コントローラーで既存システムを置き換えるのではなく、プロジェクトの既存アーキテクチャを維持し、観察した挙動に基づいて調整します。
編集前の確認
この確認が完了するまで、シーン、スクリプト、プロジェクト設定を作成しないでください。
project.godotを見つけ、プロジェクトのルートを確認します。config/features、レンダリング方式、物理演算のティックレート、ディスプレイ設定、3D 物理レイヤー名、既存の Input Map アクションを読み取ります。- 利用可能な場合は、プロジェクトで使用されている Godot 実行ファイルを
--versionで実行します。API はその正確な Godot 4.x リリースに合わせてください。プロジェクトやリソース形式を、告知なしにアップグレードしないでください。 - 代表的な
.tscn、.gd、インポート済みの 3D アセットを調べます。シーンの所有関係、ノードの命名、型付き GDScript のスタイル、シグナルのスタイル、グループ、オートロード、フォルダー構成、ノード参照でエクスポートノード、ユニーク名、パスのどれを使っているかを記録します。 - 現在のプレイヤー、カメラ、レベル、環境、コリジョンレイヤーとマスク、モデルのスケール、適用済みのトランスフォーム、入力バインディングを確認します。編集前に、メッシュやリソースが共有されているかも確認します。
- 対象のレンダラーとハードウェアを特定します。Forward+ のデスクトップシーン、Mobile レンダラーのゲーム、Compatibility プロジェクトでは、必要なライティングや環境の設定が異なります。
- 実行可能なベースラインを確立し、既存の警告を記録します。既存のエラーを、今回の変更によるものとして扱わないでください。
エディターのバージョン、プロジェクトの feature タグ、要求された API が一致しない場合は、リソースを作成する前に作業を止め、バージョンの不一致を解決します。
要件に合う最小限の設計を選ぶ
- 床、壁、斜面、動くプラットフォームへの対応が必要な、スクリプト駆動のアバターには
CharacterBody3Dを使用します。 - キャラクターを運ぶ必要がある、スクリプトまたはアニメーション駆動のプラットフォームには
AnimatableBody3Dを使用します。 - 力やインパルスによって動かすボディには
RigidBody3Dを使用します。毎フレームトランスフォームを上書きして、キャラクターのように動かさないでください。 - 変化する理由が異なるコリジョン、ゲームプレイ状態、ビジュアル、カメラピボットは、それぞれ別の子ブランチに分けます。
- キーボードとゲームパッドのバインディングでゲームプレイコードを共有できるように、物理キー定数ではなく Input Map アクションを使用します。
- レベルのジオメトリが対象とカメラの間を移動する可能性がある場合は、
SpringArm3Dカメラリグを使用します。 - まず
WorldEnvironmentを 1 つ、主要なライトを 1 つ配置します。基本画像が明瞭に見えるようになってから、ポストプロセスや影付きライトを追加します。
実装ワークフロー
- 観察可能な挙動を定義します。移動の基準座標系、最高速度、加速度、空中制御、斜面の限界、ジャンプのルール、カメラの範囲、カメラのコリジョン、ビジュアルの目標を決めます。
- 再利用可能なプレイヤーシーンを作成するか、既存のシーンを調整します。カプセルなどの単純なコリジョンシェイプを足元に合わせ、ビジュアルモデルのトランスフォームをローカルに保ち、インスタンス化しやすいようにルートを単位行列の状態にします。
- Input Map のアクション名とデッドゾーンを確認します。意味が一致する既存のプロジェクトアクションを再利用します。
_physics_process(delta)で物理演算を実装します。CharacterBody3D.velocityは 1 秒あたりの単位数として扱い、物理ティックごとにmove_and_slide()を 1 回呼び出します。- プロジェクトに入力ルーターがない場合は、
_unhandled_input(event)で視点操作イベントを実装します。ヨーとピッチは別々のピボットで管理し、プレイヤーのコライダーはスプリングアームの判定対象から除外します。 - まず視認性を重視して環境とライティングを整えます。空または背景、アンビエント光、キーライトの向き、露出、フォグ、影を、ひとつの構成要素として調整します。
- アニメーションやエフェクトを仕上げる前に、代表的なジオメトリでコントローラー、カメラ、ライティングを一緒にテストします。
型付きコントローラーの例
調査したプロジェクトに合わせて、名前と構成を調整します。view_camera をインスペクターで割り当て、move_left、move_right、move_forward、move_back、jump アクションを定義します。
extends CharacterBody3D
@export_range(0.1, 30.0, 0.1) var move_speed: float = 7.0
@export_range(0.1, 100.0, 0.1) var ground_acceleration: float = 28.0
@export_range(0.1, 100.0, 0.1) var air_acceleration: float = 9.0
@export_range(0.1, 30.0, 0.1) var jump_velocity: float = 8.5
@export var view_camera: Camera3D
var gravity: float = float(
ProjectSettings.get_setting("physics/3d/default_gravity", 9.8)
)
func _ready() -> void:
assert(is_instance_valid(view_camera), "Assign the movement camera")
func _physics_process(delta: float) -> void:
var move_input: Vector2 = Input.get_vector(
&"move_left", &"move_right", &"move_forward", &"move_back"
)
# Camera +Z points backward, matching the positive Y returned for move_back.
var camera_back: Vector3 = view_camera.global_transform.basis.z
var camera_right: Vector3 = view_camera.global_transform.basis.x
camera_back.y = 0.0
camera_right.y = 0.0
camera_back = camera_back.normalized()
camera_right = camera_right.normalized()
var wish_direction: Vector3 = (
camera_right * move_input.x + camera_back * move_input.y
).limit_length(1.0)
var target_velocity: Vector3 = wish_direction * move_speed
var response: float = (
ground_acceleration if is_on_floor() else air_acceleration
)
velocity.x = move_toward(velocity.x, target_velocity.x, response * delta)
velocity.z = move_toward(velocity.z, target_velocity.z, response * delta)
if is_on_floor():
if velocity.y < 0.0:
velocity.y = 0.0
if Input.is_action_just_pressed(&"jump"):
velocity.y = jump_velocity
else:
velocity.y -= gravity * delta
move_and_slide()
こうした挙動を場当たり的に再実装するのではなく、ボディの floor_max_angle、floor_snap_length、floor_stop_on_slope、プラットフォームレイヤー、platform_on_leave を調整します。コヨーテタイム、ジャンプバッファリング、スプリント、ルートモーションは、ゲームの仕様で必要な場合にのみ追加します。
検証
まずプロジェクト独自のチェックを実行し、その後、該当するすべての手順を実施します。
- 対応するエディターでインポートと解析を行います。プロジェクトがヘッドレス検証に対応している場合は、
<godot> --headless --path <project> --editor --quitを実行し、出力全体を確認します。 - プレイヤーシーンと、少なくとも1つの統合済みレベルを実行します。有効なゲームプレイカメラがちょうど1つであることを確認します。
- 移動開始、停止、方向転換、斜め入力、入力なしでの減速、ジャンプの押下と長押し、天井への接触、段差、階段、緩やかな斜面と上限を超える斜面、壁、角、動くプラットフォームをテストします。
- カメラを全範囲にわたって回転させます。移動方向、ピッチ制限、カメラの衝突、障害物を避けた後の復帰、ニアクリップ面の交差、マウスキャプチャの解除を確認します。
- 物理挙動を安定させたまま、低フレームレートと高フレームレートでテストします。フレームレートに依存するカメラの平滑化やアニメーションコードがないか確認します。
- コリジョン形状を表示し、リモートシーンツリーを使って、コライダーの位置合わせ、レイヤー、マスク、有効な環境、実行時のトランスフォームを確認します。
- 暗所、明所、屋内、屋外の代表的な視点を比較します。露出、シルエット、シャドウアクネ、ピーターパンニング、フォグの視認性、マテリアルの反応を確認します。
- 負荷の高いシャドウ、ボリューメトリックエフェクト、スクリーンスペースエフェクト、多数の動的ライトを残す前に、対象クラスのハードウェアでプロファイリングします。
- ベースラインを再実行し、変更したファイル、設定、テスト、および実施できなかったデバイスや視覚的なチェックを報告します。
注意点
move_and_slide()の前にCharacterBody3D.velocityにdeltaを掛けること。ボディが必要とするのは速度であり、フレームごとの変位ではありません。- 物理ボディを
positionやglobal_transformで移動してから、スライド衝突や床の状態が正確だと期待すること。 - カメラのピッチが付いた前方ベクトルをそのまま使うこと。意図しない垂直方向の移動が加わります。
- カメラをアニメーションするビジュアルボーンに直接親子付けすること、またはカメラを狙うためにプレイヤー全体を回転させること。
- 詳細なレンダリングメッシュと同等に詳細なコリジョンを用意すること、またはスケールが不均一なコリジョン形状を使うこと。
is_on_floor()を予測用のクエリとして扱うこと。これは直前のmove_and_slide()の結果を示します。- プロジェクト設定で定義済みの場合に、キー、コリジョンレイヤー番号、ノードパス、重力をハードコードすること。
- レンダラーの対応状況や GPU 負荷を確認する前に、環境エフェクトをすべて有効にすること。
- シーンインスタンス1つだけを変更すべき場合に、共有の
Environment、マテリアル、メッシュ、シェイプリソースを編集すること。 - ヘッドレス解析を視覚的な検証として扱うこと。カメラ、マテリアル、シャドウ、フォグの確認には、引き続きレンダリングされた状態での検査が必要です。