Files
Fighting_Rthythm_game/addons/godot_mcp/commands/animation_commands.gd

238 lines
7.2 KiB
GDScript

@tool
extends "res://addons/godot_mcp/commands/base_command.gd"
func get_commands() -> Dictionary:
return {
"list_animations": _list_animations,
"create_animation": _create_animation,
"add_animation_track": _add_animation_track,
"set_animation_keyframe": _set_animation_keyframe,
"get_animation_info": _get_animation_info,
"remove_animation": _remove_animation,
}
func _find_animation_player(node_path: String) -> AnimationPlayer:
var node := find_node_by_path(node_path)
if node is AnimationPlayer:
return node as AnimationPlayer
return null
func _list_animations(params: Dictionary) -> Dictionary:
var result := require_string(params, "node_path")
if result[1] != null:
return result[1]
var node_path: String = result[0]
var player := _find_animation_player(node_path)
if player == null:
return error_not_found("AnimationPlayer at '%s'" % node_path)
var animations: Array = []
for anim_name in player.get_animation_list():
var anim := player.get_animation(anim_name)
animations.append({
"name": anim_name,
"length": anim.length,
"loop_mode": anim.loop_mode,
"track_count": anim.get_track_count(),
})
return success({"node_path": node_path, "animations": animations, "count": animations.size()})
func _create_animation(params: Dictionary) -> Dictionary:
var result := require_string(params, "node_path")
if result[1] != null:
return result[1]
var node_path: String = result[0]
var result2 := require_string(params, "name")
if result2[1] != null:
return result2[1]
var anim_name: String = result2[0]
var player := _find_animation_player(node_path)
if player == null:
return error_not_found("AnimationPlayer at '%s'" % node_path)
var length: float = float(params.get("length", 1.0))
var loop_mode: int = int(params.get("loop_mode", 0)) # 0=none, 1=linear, 2=pingpong
var anim := Animation.new()
anim.length = length
anim.loop_mode = loop_mode
var lib := player.get_animation_library("")
if lib == null:
lib = AnimationLibrary.new()
player.add_animation_library("", lib)
lib.add_animation(anim_name, anim)
return success({"name": anim_name, "length": length, "created": true})
func _add_animation_track(params: Dictionary) -> Dictionary:
var result := require_string(params, "node_path")
if result[1] != null:
return result[1]
var node_path: String = result[0]
var result2 := require_string(params, "animation")
if result2[1] != null:
return result2[1]
var anim_name: String = result2[0]
var result3 := require_string(params, "track_path")
if result3[1] != null:
return result3[1]
var track_path: String = result3[0]
var player := _find_animation_player(node_path)
if player == null:
return error_not_found("AnimationPlayer at '%s'" % node_path)
var anim := player.get_animation(anim_name)
if anim == null:
return error_not_found("Animation '%s'" % anim_name)
var track_type_str: String = optional_string(params, "track_type", "value")
var track_type: int
match track_type_str:
"value": track_type = Animation.TYPE_VALUE
"position_2d": track_type = Animation.TYPE_POSITION_3D # Godot uses 3D type for 2D too
"rotation_2d": track_type = Animation.TYPE_ROTATION_3D
"scale_2d": track_type = Animation.TYPE_SCALE_3D
"method": track_type = Animation.TYPE_METHOD
"bezier": track_type = Animation.TYPE_BEZIER
"blend_shape": track_type = Animation.TYPE_BLEND_SHAPE
_: track_type = Animation.TYPE_VALUE
var track_idx := anim.add_track(track_type)
anim.track_set_path(track_idx, NodePath(track_path))
var update_mode_str: String = optional_string(params, "update_mode", "")
if not update_mode_str.is_empty() and track_type == Animation.TYPE_VALUE:
match update_mode_str:
"continuous": anim.value_track_set_update_mode(track_idx, Animation.UPDATE_CONTINUOUS)
"discrete": anim.value_track_set_update_mode(track_idx, Animation.UPDATE_DISCRETE)
"capture": anim.value_track_set_update_mode(track_idx, Animation.UPDATE_CAPTURE)
return success({"track_index": track_idx, "track_path": track_path, "track_type": track_type_str})
func _set_animation_keyframe(params: Dictionary) -> Dictionary:
var result := require_string(params, "node_path")
if result[1] != null:
return result[1]
var node_path: String = result[0]
var result2 := require_string(params, "animation")
if result2[1] != null:
return result2[1]
var anim_name: String = result2[0]
var player := _find_animation_player(node_path)
if player == null:
return error_not_found("AnimationPlayer at '%s'" % node_path)
var anim := player.get_animation(anim_name)
if anim == null:
return error_not_found("Animation '%s'" % anim_name)
var track_index: int = int(params.get("track_index", 0))
if track_index < 0 or track_index >= anim.get_track_count():
return error_invalid_params("Invalid track_index: %d" % track_index)
var time: float = float(params.get("time", 0.0))
var value = params.get("value")
# Parse value string for common types
if value is String:
var s: String = value
var expr := Expression.new()
if expr.parse(s) == OK:
var parsed = expr.execute()
if parsed != null:
value = parsed
var key_idx := anim.track_insert_key(track_index, time, value)
var easing: float = float(params.get("easing", 1.0))
if easing != 1.0:
anim.track_set_key_transition(track_index, key_idx, easing)
return success({"track_index": track_index, "time": time, "key_index": key_idx, "easing": anim.track_get_key_transition(track_index, key_idx)})
func _get_animation_info(params: Dictionary) -> Dictionary:
var result := require_string(params, "node_path")
if result[1] != null:
return result[1]
var node_path: String = result[0]
var result2 := require_string(params, "animation")
if result2[1] != null:
return result2[1]
var anim_name: String = result2[0]
var player := _find_animation_player(node_path)
if player == null:
return error_not_found("AnimationPlayer at '%s'" % node_path)
var anim := player.get_animation(anim_name)
if anim == null:
return error_not_found("Animation '%s'" % anim_name)
var tracks: Array = []
for i in anim.get_track_count():
var track_info := {
"index": i,
"path": str(anim.track_get_path(i)),
"type": anim.track_get_type(i),
"key_count": anim.track_get_key_count(i),
}
var keys: Array = []
for k in anim.track_get_key_count(i):
keys.append({
"time": anim.track_get_key_time(i, k),
"value": str(anim.track_get_key_value(i, k)),
"easing": anim.track_get_key_transition(i, k),
})
track_info["keys"] = keys
tracks.append(track_info)
return success({
"name": anim_name,
"length": anim.length,
"loop_mode": anim.loop_mode,
"step": anim.step,
"tracks": tracks,
})
func _remove_animation(params: Dictionary) -> Dictionary:
var result := require_string(params, "node_path")
if result[1] != null:
return result[1]
var node_path: String = result[0]
var result2 := require_string(params, "name")
if result2[1] != null:
return result2[1]
var anim_name: String = result2[0]
var player := _find_animation_player(node_path)
if player == null:
return error_not_found("AnimationPlayer at '%s'" % node_path)
var lib := player.get_animation_library("")
if lib == null or not lib.has_animation(anim_name):
return error_not_found("Animation '%s'" % anim_name)
lib.remove_animation(anim_name)
return success({"name": anim_name, "removed": true})