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_countint(読み取り専用)Skeleton3D が管理するボーン数0
motion_scalefloatアニメーション全体のスケール(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.xをもとに執筆しています。

コメント