Godot入門:Skeleton3Dの使い方と活用法

はじめに

3Dゲームで人間やキャラクターが走ったり、ジャンプしたり、攻撃したりする——こうした動きを実現するには「スケルタルアニメーション」が欠かせません。キャラクターモデルに骨(ボーン)を入れて、その骨を動かすことで肉(メッシュ)も一緒に変形する仕組みです。

今回解説するSkeleton3Dは、このボーンの骨格を管理する中枢ノードです。Skeleton3Dを使いこなせば、3Dキャラクターのアニメーションはもちろん、ラグドール物理、武器のアタッチメント、インバースキネマティクス(IK)といった高度な機能も実装できます。

Skeleton3Dとは?

Skeleton3Dは、3Dキャラクターの「骨格(ボーン構造)」を管理するノードです。複数のボーンの階層構造・相対位置・回転を保持し、MeshInstance3Dのスキニング(メッシュ変形)と連携することで、キャラクターを動かします。

継承ツリー:

Skeleton3D → Node3D → Node → Object

Skeleton3Dの主な役割は以下の通りです。

  • ボーン管理:複数のボーン(腕、脚、頭など)をツリー構造で管理
  • スキニング:ボーンの動きに応じてメッシュ(MeshInstance3D)を自動変形
  • AnimationPlayer連携:キーフレームアニメーションでボーンを制御
  • BoneAttachment3D連携:武器やアクセサリーを特定のボーンにアタッチ
  • IK(インバースキネマティクス)対応:手や足の位置から逆算してボーン角度を算出




Skeleton3Dのボーン構造
ヒューマノイド型キャラクターの骨格。複数のボーンが階層構造で接続される

このノードを使うべき場面

使う場面:

  • 3Dキャラクターアニメーション:人間やキャラクターが歩く・走る・攻撃するアニメーション
  • 表情アニメーション:顔のボーンを動かして喜怒哀楽を表現
  • ラグドール物理:キャラクターが死亡した際に、ボーンを物理シミュレーション対象にして自然な倒れ方を実現
  • 武器・アクセサリアタッチ:BoneAttachment3Dで手持ち武器や帽子をボーンに固定
  • IK制御:手や足の位置を指定して、逆算でボーン角度を計算(例:足がバランス良く地面に着く)

使わない場面:

  • 単純な立方体や動かない物体:Skeleton3Dはキャラクター・生物・複雑な構造物用。単純なメッシュの変形や拡大縮小ならTransform3Dで十分
  • モーフターゲット(ブレンドシェイプ)のみの変形:顔のリップシンクやシェイプキーアニメーションだけならMeshInstance3Dのblendshape機能で可能

主なプロパティと機能

プロパティ 説明 デフォルト
bone_count int(読み取り専用) Skeleton3D が管理するボーン数 0
motion_scale float アニメーション全体のスケール(100%=1.0)。全ボーンの動きを一括調整 1.0

主なメソッド:

# ボーン数を取得
get_bone_count() -> int

# ボーンのインデックスから名前を取得
get_bone_name(bone_index: int) -> String

# ボーンの名前からインデックスを検索
find_bone(name: String) -> int

# ボーンのグローバルポーズ(ワールド座標の変換)を取得
get_bone_global_pose(bone_index: int) -> Transform3D

# ボーンのローカルポーズ(親基準の変換)を取得
get_bone_pose(bone_index: int) -> Transform3D

# ボーンの回転をセット(ローカル空間)
set_bone_pose_rotation(bone_index: int, rotation: Quaternion)

# ボーンの位置をセット
set_bone_pose_position(bone_index: int, position: Vector3)

# すべてのボーンをリセット
reset_bone_poses()

コード例1:AnimationPlayerでスケルタルアニメーションを再生(基本)

extends Node3D

@onready var animation_player = $AnimationPlayer
@onready var skeleton = $Skeleton3D

func _ready():
	# "walk" という名前のアニメーションを再生
	animation_player.play("walk")

func _input(event):
	if event is InputEventKey and event.pressed:
		match event.keycode:
			KEY_W:
				animation_player.play("walk")
			KEY_I:
				animation_player.play("idle")
			KEY_J:
				animation_player.play("jump")
			KEY_A:
				animation_player.play("attack")

コード例2:スクリプトでボーンの回転を直接制御(リアルタイムIK例)

extends Node3D

@onready var skeleton = $Skeleton3D
@export var target_pos: Vector3 = Vector3(1, 0, 0)

func _ready():
	# ボーンの名前を表示(デバッグ用)
	for i in range(skeleton.get_bone_count()):
		print("Bone ", i, ": ", skeleton.get_bone_name(i))

func _physics_process(delta):
	# 右腕(shoulder_R, elbow_R, hand_R)を簡易IKで制御
	var shoulder_idx = skeleton.find_bone("shoulder_R")
	var elbow_idx = skeleton.find_bone("elbow_R")
	var hand_idx = skeleton.find_bone("hand_R")

	if shoulder_idx >= 0 and elbow_idx >= 0:
		# 肩から手へのベクトル
		var shoulder_pos = skeleton.get_bone_global_pose(shoulder_idx).origin
		var target_dir = (target_pos - shoulder_pos).normalized()

		# 簡易的に肘を曲げる(実際のIKはもっと複雑)
		var elbow_rot = Quaternion.from_euler(
			Vector3(0.5 * sin(Time.get_ticks_msec() / 1000.0), 0, 0)
		)
		skeleton.set_bone_pose_rotation(elbow_idx, elbow_rot)

コード例3:BoneAttachment3Dで武器をボーンに装備

# シーン構成:
# - Skeleton3D
#   - MeshInstance3D(キャラクター)
#   - BoneAttachment3D("hand_R" ボーンにアタッチ)
#     - MeshInstance3D(剣モデル)

extends Node3D

@onready var skeleton = $Skeleton3D
@onready var bone_attachment = $Skeleton3D/BoneAttachment3D

func _ready():
	# BoneAttachment3Dを設定(Godot 4.xではノードプロパティで指定)
	bone_attachment.bone_name = "hand_R"  # または bone_index で指定

func change_weapon(weapon_scene_path: String):
	# 前の武器を削除
	for child in bone_attachment.get_children():
		child.queue_free()

	# 新しい武器をロードして装備
	var weapon = load(weapon_scene_path).instantiate()
	bone_attachment.add_child(weapon)

もっと使いこなす:カスタマイズできるパラメータ

まずは基本を動かしてみてから、余裕が出たら試してみてください。

パラメータ 目的 実装例
motion_scaleを調整 全アニメーションの再生速度や振幅をスケール skeleton.motion_scale = 0.5で全動き50%に
skeleton.motion_scale = 2.0で倍速
複数のアニメーション層(AnimationTree) 上半身と下半身のアニメーションを独立制御(例:歩きながら攻撃) AnimationTree の StateMachine で複数レイヤーを設定
ラグドール切り替え キャラクター死亡時にボーンを物理エンジンに切り替え 各ボーンをPhysicalBone3Dに変換し、アニメーション制御を解除
IKチェーン(Advanced) 手や足の目標位置からボーン角度を逆算 Skeleton3D.set_bone_pose_* で IK アルゴリズムを実装(or AnimationTreeで FABRIK)
ボーン名の標準化 異なるモデル間でボーン名の対応付けを自動化 ボーン検索に find_bone() を使い、存在しないボーンは skip

応用例:死亡時にラグドールに切り替える

extends CharacterBody3D

@onready var skeleton = $Skeleton3D
@onready var animation_player = $AnimationPlayer

var is_dead = false

func die():
	if is_dead:
		return

	is_dead = true
	animation_player.stop()

	# すべてのボーンをPhysicalBone3Dに変換(簡略版)
	# 実装の詳細は複雑なため、Godot の公式ドキュメント参照
	print("ラグドール物理有効化")




AnimationPlayerでのアニメーション編集
AnimationPlayer でボーン回転をキーフレーム化。timeline上でアニメーションを制御

まとめ

Skeleton3Dは「3Dキャラクターの骨格を管理し、スキニング・アニメーション・アタッチメントを実現する」中核ノードです。AnimationPlayerと組み合わせれば、キャラクターに複雑な動きを与えることができます。

  • 階層構造が肝:ボーンがツリー状に接続され、親の回転が子に伝播する
  • AnimationPlayerとセット:キーフレームアニメーションでボーンを制御し、スキニングで自動メッシュ変形
  • 高度な機能も搭載:IK、ラグドール物理、武器アタッチメントなど、実装の幅が広い

次回は、ボーンに「子オブジェクト」(武器、帽子など)をアタッチする「BoneAttachment3D」を解説します。




複数のアニメーション例
Skeleton3D でサポートされる複数のアニメーション。ボーンの角度・位置を変更して様々な動きを表現

シリーズ:Godot 4 ノード解説

001〜040:各種ノード | 041~070:個別ノード解説

  • 041: CanvasLayer
  • 042: ParallaxLayer
  • 043: Parallax2D
  • 044: Control
  • 045: PanelContainer
  • 046: TabContainer
  • 047: MarginContainer
  • 048: AnimationPlayer
  • 049: AnimationTree
  • 050: Tween
  • 051: CPUParticles2D
  • 052: GPUParticles2D
  • 053: Sprite2D
  • 054: CharacterBody2D
  • 055: RigidBody2D
  • 056: StaticBody2D
  • 057: Area2D
  • 058: AudioStreamPlayer
  • 059: AudioStreamPlayer2D
  • 060: AudioStreamPlayer3D
  • 061: MultiMeshInstance3D
  • 062: MeshInstance3D
  • 063: CSGBox3D
  • 064: CSGMesh3D
  • 065: OmniLight3D
  • 066: GridMap
  • 067: Path3D
  • 068: PathFollow3D
  • 069: NavigationAgent3D
  • 070: Skeleton3D

この記事はGodot 4.xをもとに執筆しています。

コメント