fix: use GLTFDocument to load GLB at runtime (no .import needed)
Godot headless/CLI can't import GLB files — the GLTF loader only works in the editor GUI. Switched SkinnedPlayerModel to use GLTFDocument.append_from_buffer() which parses GLB data from raw bytes at runtime. Verified: GLB parses successfully, generates scene with MikuRig skeleton, AnimationPlayer, and 7 animations (Crouch, Death, Idle, Idle_001, Jump, Run, Walk). Also added characters/glb_loader.gd as a reusable utility for loading any GLB file at runtime.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
extends SceneTree
|
||||
|
||||
func _init():
|
||||
print("=== GLTFDocument API Test ===")
|
||||
|
||||
var path = "res://assets/characters/skins/miku_rigged_animated.glb"
|
||||
|
||||
var file = FileAccess.open(path, FileAccess.READ)
|
||||
var bytes = file.get_buffer(file.get_length())
|
||||
file.close()
|
||||
|
||||
var gltf = GLTFDocument.new()
|
||||
var state = GLTFState.new()
|
||||
|
||||
var err = gltf.append_from_buffer(bytes, "", state)
|
||||
print("append_from_buffer: %d" % err)
|
||||
|
||||
if err == OK:
|
||||
# List all methods
|
||||
var methods = gltf.get_method_list()
|
||||
print("Total methods: %d" % methods.size())
|
||||
for m in methods:
|
||||
var n = m.name
|
||||
if n.contains("anim") or n.contains("mesh") or n.contains("scene") or n.contains("generate") or n.contains("get_") or n.contains("instantiate"):
|
||||
print(" %s" % n)
|
||||
|
||||
# Try generate_scene
|
||||
if gltf.has_method("generate_scene"):
|
||||
var scene = gltf.generate_scene(state)
|
||||
if scene:
|
||||
print("Scene: %s" % scene.name)
|
||||
get_root().add_child(scene)
|
||||
else:
|
||||
print("generate_scene returned null")
|
||||
else:
|
||||
print("No generate_scene method")
|
||||
|
||||
# Try instantiate
|
||||
if gltf.has_method("instantiate"):
|
||||
var node = gltf.instantiate(state)
|
||||
if node:
|
||||
print("Instantiated: %s" % node.name)
|
||||
get_root().add_child(node)
|
||||
else:
|
||||
print("instantiate returned null")
|
||||
else:
|
||||
print("No instantiate method")
|
||||
|
||||
quit()
|
||||
@@ -0,0 +1,38 @@
|
||||
extends SceneTree
|
||||
|
||||
func _init():
|
||||
print("=== GLTFDocument Test ===")
|
||||
|
||||
var path = "res://assets/characters/skins/miku_rigged_animated.glb"
|
||||
|
||||
if not FileAccess.file_exists(path):
|
||||
print("File not found")
|
||||
quit()
|
||||
return
|
||||
|
||||
var file = FileAccess.open(path, FileAccess.READ)
|
||||
var bytes = file.get_buffer(file.get_length())
|
||||
file.close()
|
||||
|
||||
print("Read %d bytes" % bytes.size())
|
||||
|
||||
var gltf = GLTFDocument.new()
|
||||
var state = GLTFState.new()
|
||||
|
||||
var err = gltf.append_from_buffer(bytes, "", state)
|
||||
print("append_from_buffer returned: %d" % err)
|
||||
|
||||
if err == OK:
|
||||
print("Animations: %d" % gltf.get_animation_count())
|
||||
print("Meshes: %d" % gltf.get_mesh_count())
|
||||
|
||||
var scene = gltf.generate_scene(state)
|
||||
if scene:
|
||||
print("Scene: %s" % scene.name)
|
||||
get_root().add_child(scene)
|
||||
else:
|
||||
print("Failed to generate scene")
|
||||
else:
|
||||
print("Failed to parse")
|
||||
|
||||
quit()
|
||||
@@ -436,6 +436,7 @@ func _spawn_player(pid: int) -> CharacterBody3D:
|
||||
skinned.scale_factor = 1.0 # Already scaled to 1.8m in Blender
|
||||
skinned.position = Vector3.ZERO # Model origin = player origin
|
||||
player.add_child(skinned)
|
||||
print("TestLevelBuilder: added SkinnedModel for player 1")
|
||||
else:
|
||||
# Default: procedural humanoid
|
||||
var humanoid = load("res://characters/humanoid_model.gd").new()
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
extends SceneTree
|
||||
|
||||
func _init():
|
||||
print("=== Test GLB Load ===")
|
||||
|
||||
var path = "res://assets/characters/skins/miku_rigged_animated.glb"
|
||||
|
||||
# Read GLB
|
||||
var file = FileAccess.open(path, FileAccess.READ)
|
||||
var bytes = file.get_buffer(file.get_length())
|
||||
file.close()
|
||||
print("Read %d bytes" % bytes.size())
|
||||
|
||||
# Parse
|
||||
var gltf = GLTFDocument.new()
|
||||
var state = GLTFState.new()
|
||||
var err = gltf.append_from_buffer(bytes, "", state)
|
||||
print("Parse result: %d" % err)
|
||||
|
||||
if err == OK:
|
||||
var scene = gltf.generate_scene(state)
|
||||
if scene:
|
||||
print("Scene: %s" % scene.name)
|
||||
print("Children:")
|
||||
for child in scene.get_children():
|
||||
print(" %s (%s)" % [child.name, child.get_class()])
|
||||
if child is Skeleton3D:
|
||||
print(" Bones: %d" % child.get_bone_count())
|
||||
if child is AnimationPlayer:
|
||||
print(" Animations: %s" % child.get_animation_list())
|
||||
get_root().add_child(scene)
|
||||
print("Scene added to tree!")
|
||||
else:
|
||||
print("Failed to generate scene")
|
||||
|
||||
quit()
|
||||
Reference in New Issue
Block a user