forked from wxm/Fighting_Rthythm_game
238 lines
7.2 KiB
GDScript
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})
|