はじめに
3Dゲームで人間やキャラクターが走ったり、ジャンプしたり、攻撃したりする——こうした動きを実現するには「スケルタルアニメーション」が欠かせません。キャラクターモデルに骨(ボーン)を入れて、その骨を動かすことで肉(メッシュ)も一緒に変形する仕組みです。
今回解説するSkeleton3Dは、このボーンの骨格を管理する中枢ノードです。Skeleton3Dを使いこなせば、3Dキャラクターのアニメーションはもちろん、ラグドール物理、武器のアタッチメント、インバースキネマティクス(IK)といった高度な機能も実装できます。
Skeleton3Dとは?
Skeleton3Dは、3Dキャラクターの「骨格(ボーン構造)」を管理するノードです。複数のボーンの階層構造・相対位置・回転を保持し、MeshInstance3Dのスキニング(メッシュ変形)と連携することで、キャラクターを動かします。
継承ツリー:
Skeleton3D → Node3D → Node → Object
Skeleton3Dの主な役割は以下の通りです。
- ボーン管理:複数のボーン(腕、脚、頭など)をツリー構造で管理
- スキニング:ボーンの動きに応じてメッシュ(MeshInstance3D)を自動変形
- AnimationPlayer連携:キーフレームアニメーションでボーンを制御
- BoneAttachment3D連携:武器やアクセサリーを特定のボーンにアタッチ
- IK(インバースキネマティクス)対応:手や足の位置から逆算してボーン角度を算出

このノードを使うべき場面
使う場面:
- 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("ラグドール物理有効化")

まとめ
Skeleton3Dは「3Dキャラクターの骨格を管理し、スキニング・アニメーション・アタッチメントを実現する」中核ノードです。AnimationPlayerと組み合わせれば、キャラクターに複雑な動きを与えることができます。
- 階層構造が肝:ボーンがツリー状に接続され、親の回転が子に伝播する
- AnimationPlayerとセット:キーフレームアニメーションでボーンを制御し、スキニングで自動メッシュ変形
- 高度な機能も搭載:IK、ラグドール物理、武器アタッチメントなど、実装の幅が広い
次回は、ボーンに「子オブジェクト」(武器、帽子など)をアタッチする「BoneAttachment3D」を解説します。

シリーズ: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をもとに執筆しています。


コメント