extends AnimatedSprite3D class_name View @onready var status: Status = (%Status as Status) class Trans: var condition: StringName var compareType: String var conditionValue var from: StringName var to: StringName var trigger_name: StringName var trans_dict: Dictionary = {} # {condition/trigger:{from:Trans[]}} var status_change_cache = [] var move_sprite_frames: SpriteFrames func init(default: SpriteFrames): sprite_frames = default move_sprite_frames = default status.character_status_changed.connect(_on_character_status_changed) animation_finished.connect(_on_animation_finished) animation_changed.connect(_on_animation_changed) frame_changed.connect(_on_frame_changed) trans_register() play_animation("idle_loop") func reset(): sprite_frames = move_sprite_frames if status.is_on_floor: play_animation("idle_loop") else: play_animation("jump4_loop") func trans_register() -> void: # 地面行走 trans("idle_loop", "run1", "speed_xz", ">", 1) run("run1", "run2_loop") trans("run1", "run3", "speed_xz", "<", 1) trans("run2_loop", "run3", "speed_xz", "<", 1) run("run3", "idle_loop") trans("run3", "run1", "speed_xz", ">", 1) # 跳跃 trigger("any", "jump1", "trigger_jump") run("jump1", "jump2_loop") trans("jump2_loop", "jump3", "speed_y", "<=", 0) run("jump3", "jump4_loop") trans("jump4_loop", "jump5", "is_on_floor", "=", true) run("jump5", "idle_loop") trans("jump5", "run1", "speed_xz", ">", 1) #地面受击 trigger("any", "hit", "trigger_hit") trigger("any", "mhit", "trigger_mhit") trigger("any", "lhit", "trigger_lhit") run("hit", "idle_loop") run("mhit", "idle_loop") run("lhit", "idle_loop") #地面眩晕受击 trigger("any", "stunhit", "trigger_stun_hit") run("stunhit", "ground_stun1_loop") #空中受击 trigger("any", "airhit1", "trigger_air_hit_up") trigger("any", "airhit4_loop", "trigger_air_hit_down") run("airhit1", "airhit2_loop") trans("airhit2_loop", "airhit3", "speed_y", "<=", 0) run("airhit3", "airhit4_loop") trans("airhit4_loop", "airhit5_select", "is_on_floor", "=", true) #空中受击落地 run_with_condition("airhit5_select", "airhit5_stun", "is_stun", "=", true) run_with_condition("airhit5_select", "airhit5", "is_stun", "=", false) run("airhit5_stun", "ground_stun1_loop") run("airhit5", "ground1_loop") #起身 trans("ground1_loop", "ground2", "is_stagger", "=", false) run("ground2", "idle_loop") trans("ground_stun1_loop", "ground_stun2", "is_stun", "=", false) run("ground_stun2", "idle_loop") #落地反弹 trigger("any", "rebound", "trigger_rebound") run("rebound", "airhit2_loop") func _process(_delta) -> void: if status.is_be_throw: return if status.is_pause: return for status_change_cache_single in status_change_cache: update_trans(status_change_cache_single) status_change_cache.clear() func _on_character_status_changed(status_name, _value) -> void: if status_name in trans_dict: status_change_cache.append(status_name) return if status_name == "is_right": scale.x = 1 if status.is_right else -1 if status.is_be_throw: return if status_name == "is_skill_running" or status_name == "is_pause": if not status.is_skill_running and status.is_pause == is_playing(): if status.is_pause: pause() else: play_animation(animation) if status_name == "basic_offset" or status_name == "shake_offset": position = status.basic_offset + status.shake_offset # global_position = Util.snap_vector3(global_position) if status.is_pause: return if status_name in ["deformation_rate", "flash_white_rate"]: update_material() func _on_animation_finished(): update_trans("animation_end") func _on_animation_changed() -> void: update_material_tex() func _on_frame_changed() -> void: update_material_tex() func run(from: StringName, to: StringName): _add_trans(from, to, "animation_end", "", "", "", "") func run_with_condition(from: StringName, to: StringName, condition, compareType, conditionValue): _add_trans(from, to, "animation_end", condition, compareType, conditionValue, "") func trans(from: StringName, to: StringName, condition, compareType, conditionValue): _add_trans(from, to, condition, condition, compareType, conditionValue, "") func trigger(from: StringName, to: StringName, trigger_name: StringName): _add_trans(from, to, trigger_name, "", "", "", trigger_name) func _add_trans(from: StringName, to: StringName, key: String, condition, compareType, conditionValue, trigger_name: StringName): var new_trans = Trans.new() new_trans.condition = condition new_trans.compareType = compareType new_trans.conditionValue = conditionValue new_trans.from = from new_trans.to = to new_trans.trigger_name = trigger_name if not key in trans_dict: trans_dict[key] = {} if not from in trans_dict[key]: trans_dict[key][from] = [] trans_dict[key][from].append(new_trans) func update_trans(key: String) -> void: if not key in trans_dict: return if status.current_animation in trans_dict[key]: update_trans_single(trans_dict[key][status.current_animation]) if "any" in trans_dict[key]: update_trans_single(trans_dict[key]["any"]) func update_trans_single(trans_list) -> void: for trans_single in trans_list: if trans_single.condition != "": var value = status.get_status(trans_single.condition) match trans_single.compareType: ">": if value <= trans_single.conditionValue: continue "<": if value >= trans_single.conditionValue: continue ">=": if value < trans_single.conditionValue: continue "<=": if value > trans_single.conditionValue: continue "=": if value != trans_single.conditionValue: continue if trans_single.trigger_name != "": if status.get_status(trans_single.trigger_name): status.set_status(trans_single.trigger_name, false) else: continue play_animation(trans_single.to) func update_view(): position = status.basic_offset + status.shake_offset # global_position = Util.snap_vector3(global_position) func update_material() -> void: call_deferred("_update_material") return func _update_material(): if not sprite_frames: return var material: ShaderMaterial = material_override as ShaderMaterial var material2: ShaderMaterial = material_override.next_pass as ShaderMaterial var deformation_rate: float = status.deformation_rate * (0.6 if status.is_floating else 0.4) if material: material.set_shader_parameter("flash_white", status.flash_white_rate) material.set_shader_parameter("deformation_dir", status.deformation_dir) material.set_shader_parameter("deformation_rate", deformation_rate) if material2: material2.set_shader_parameter("flash_white", status.flash_white_rate) material2.set_shader_parameter("deformation_dir", status.deformation_dir) material2.set_shader_parameter("deformation_rate", deformation_rate) func update_material_tex() -> void: call_deferred("_update_material_tex") return func _update_material_tex(): if not sprite_frames: return var material: ShaderMaterial = material_override as ShaderMaterial var material2: ShaderMaterial = material_override.next_pass as ShaderMaterial var tex: Texture2D = sprite_frames.get_frame_texture(animation, frame) if material: material.set_shader_parameter("tex", tex) if material2: material2.set_shader_parameter("tex", tex) func play_animation(animation_name: String) -> void: status.set_status("current_animation", animation_name) if not sprite_frames: return if not sprite_frames.has_animation(animation_name): update_trans("animation_end") return if animation_name == animation: frame = 0 frame_progress = 0 play() else: play(animation_name, Setting.animation_speed_scale)