You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot角色向上移动时报Animation not found动画不存在错误

问题现象
  • 项目角色已配置右、左、上三个方向的移动动画,运行时动画视觉上可正常播放,但控制台持续输出报错:play: Animation not found: Run_Up、play: Animation not found: Idle_Up
  • 报错仅在角色向上移动时触发,切换到其他方向移动后报错立即停止

相关参考截图:

  • 错误日志:错误日志
  • 错误详情:错误详情
  • 动画列表:动画资源列表
  • 场景结构:节点树结构

原有角色控制脚本:

extends KinematicBody2D

var VELOCIDAD_MAXIMA = 100
var ACELERACION = 350
var FRICCION = 850

enum {
    RUN,
    PUSH
}

onready var animation_player = $AnimationPlayer

export var velocidad = Vector2.ZERO#(0, 0) 
export var direccion_vector = Vector2.DOWN#(0, 1)
export var direccion = Vector2.ZERO#(0, 0)
export var push_finished = false

var estado = RUN

var targets = []

func run_state(delta):
    var input_vector = Vector2.ZERO

    input_vector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
    input_vector.y = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
    input_vector = input_vector.normalized()
    
    if input_vector != Vector2.ZERO:
        direccion_vector = input_vector
        velocidad = velocidad.move_toward(input_vector * VELOCIDAD_MAXIMA, ACELERACION * delta)
        _play_animation("Run")
    #Si el usuario no esta tocando al personaje
    
    elif velocidad.length() == 0 && Input.is_action_pressed("action"):
        _play_animation("Push")
        if $RayCast2D.is_colliding():
            push_finished = false
            estado = PUSH
    
    else:
        velocidad = velocidad.move_toward(input_vector * VELOCIDAD_MAXIMA, FRICCION * delta)
        _play_animation("Idle")
    
    velocidad = move_and_slide(velocidad)
    
func push_state(_delta):
    var collider = $RayCast2D.get_collider()
    collider._on_interact($RayCast2D.rotation_degrees)
    
    if collider:
        estado = RUN
    velocidad = move_and_slide(velocidad)

func animation_finished():  
    if !Input.is_action_pressed("action"):
        estado = RUN
        velocidad = Vector2.ZERO
    
func _physics_process(delta):
    match estado:
        RUN:
            run_state(delta)
        PUSH:
            push_state(delta)
        
func _play_animation(animation_type: String) -> void:
    var animation_name = animation_type + "_" + _get_direction_string(direccion_vector.angle())
    
    if animation_name != animation_player.current_animation:
        animation_player.stop(true)
    
    animation_player.play(animation_name)

func _get_direction_string(angle: float) -> String:
    var angle_deg = round(rad2deg(angle))

    #glanced up
    if angle_deg == -90:
        $RayCast2D.rotation_degrees = 180
        return "Up"

    #glanced down
    if angle_deg == 90:
        $RayCast2D.rotation_degrees = 0
        return "Right"

    #glanced left
    if angle_deg == 180:
        $RayCast2D.rotation_degrees = 90
        return "Left"
    
    #glanced right
    if angle_deg == 0:
        $RayCast2D.rotation_degrees = -90
        return "Right"
    
    return "Right"
故障原因
  1. 方向判断逻辑容错性为0:_get_direction_string用==对浮点运算得到的角度做精确等值判断,斜向输入、轴值漂移、浮点精度误差都会导致角度值不是刚好的-90/0/90/180,出现方向匹配错误。初始值direccion_vector = Vector2.DOWN对应90度角被直接映射为Right,本身逻辑就不严谨。
  2. 动画播放逻辑缺失校验:_play_animation每帧都会调用animation_player.play(),既不校验拼接出的动画名是否真实存在,也不在当前已在播放目标动画时跳过调用,无效调用反复触发控制台报错。
  3. 动画名匹配存在偏差:Godot动画名大小写敏感,若AnimationPlayer中存储的向上方向动画名和代码拼接出的Run_Up/Idle_Up不完全一致(比如命名为Run_up/Idle_up),就会触发找不到动画的错误。
修复方案
  1. 打开AnimationPlayer面板,核对所有动画名,确保右、左、上三个方向的Run/Idle动画命名严格为Run_Right、Run_Left、Run_Up、Idle_Right、Idle_Left、Idle_Up,大小写完全匹配。
  2. 替换原有_get_direction_string和_play_animation函数,改用角度区间判断方向,增加动画存在性校验,避免重复调用play接口:
func _play_animation(animation_type: String) -> void:
    var dir_str = _get_direction_string(direccion_vector.angle())
    var animation_name = animation_type + "_" + dir_str
    # 动画不存在时直接跳过,不触发播放
    if not animation_player.has_animation(animation_name):
        return
    # 仅在未播放目标动画时才切换,避免每帧重复调用play
    if animation_player.current_animation != animation_name:
        animation_player.play(animation_name)

func _get_direction_string(angle: float) -> String:
    var angle_deg = round(rad2deg(angle))
    # 负角度转正,简化区间判断
    if angle_deg < 0:
        angle_deg += 360
    
    var dir: String
    # 按45度区间划分四个方向,覆盖斜向输入场景
    if angle_deg > 315 or angle_deg <= 45:
        dir = "Right"
        $RayCast2D.rotation_degrees = -90
    elif angle_deg > 45 and angle_deg <= 135:
        # 下方向暂时映射为Right,后续补充下方向动画时可直接改为Down
        dir = "Right"
        $RayCast2D.rotation_degrees = 0
    elif angle_deg > 135 and angle_deg <= 225:
        dir = "Left"
        $RayCast2D.rotation_degrees = 90
    elif angle_deg > 225 and angle_deg <= 315:
        dir = "Up"
        $RayCast2D.rotation_degrees = 180
    
    return dir

内容的提问来源于stack exchange,提问作者willybc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 06:12:13