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

Roblox中FBX模型角色动画延迟、爬楼功能实现求助

问题描述
  • 已在Roblox Studio中导入FBX模型并完成动画制作,但Humanoid存在两个问题:无法爬楼梯、动画延迟1秒
  • 需要消除动画延迟,实现角色带动画的跳跃与爬楼功能

相关截图说明

  • 截图1:展示Explorer面板中Animate脚本挂载在角色模型下的位置
  • 截图2:展示角色模型的层级结构以及包含的动画资源文件

当前动画脚本

model = script.Parent
Humanoid = model:WaitForChild("Humanoid")
RunService = game:GetService("RunService")

Humanoid:ChangeState(Enum.HumanoidStateType.None)

idleAnimation = script:WaitForChild('idle');
walkAnimation = script:WaitForChild('walk');
runAnimation = script:WaitForChild('run');
jumpAnimation = script:WaitForChild('jump');

Pose = "none"
LastPose = Pose
PoseTime = tick()

ToolAnimTime = 0

local animation: AnimationTrack = nil;
function playAnim(anim)
    if animation ~= nil and animation.IsPlaying then
        --print(animation.Animation.Name, ' == ', anim.Name, ' = ', animation.Animation.Name == anim.Name)
        if animation.Animation.Name == anim.Name then
            return;
        end
        
        animation:Stop();
    end
    
    print('playAnim ', anim.Name)
    
    animation = Humanoid:LoadAnimation(anim)
    animation.Looped = false
    animation:Play()
end

function SetPose(pose)
    LastPose = Pose
    Pose = pose
    PoseTime = tick()
end

function OnRunning(Speed)
    if Speed > 0 then
        SetPose("Running")
    else
        SetPose("Standing")
    end
end

function OnDied()
    SetPose("Dead")
end

function OnJumping()
    SetPose("Jumping")
end

function OnClimbing()
    SetPose("Climbing")
end

function OnGettingUp()
    SetPose("GettingUp")
end

function OnFreeFall()
    SetPose("FreeFall")
end

function OnFallingDown()
    SetPose("FallingDown")
end

function OnSeated()
    SetPose("Seated")
end

function OnPlatformStanding()
    SetPose("PlatformStanding")
end

function OnSwimming(Speed)
    return OnRunning(Speed)
end

function MoveFreeFall()
    --RightShoulder.MaxVelocity = 0.15
    --LeftShoulder.MaxVelocity = 0.15
    --RightShoulder.DesiredAngle = 0.5
    --LeftShoulder.DesiredAngle = -0.5
    --RightHip.DesiredAngle = -0.5
    --LeftHip.DesiredAngle = 0.5
end

function MoveSit()
    --RightShoulder.MaxVelocity = 0.15
    --LeftShoulder.MaxVelocity = 0.15
    --RightShoulder.DesiredAngle = (math.pi / 2)
    --LeftShoulder.DesiredAngle = -(math.pi / 2)
    --RightHip.DesiredAngle = 1
    --LeftHip.DesiredAngle = -1
end


function Move()
    if (Pose == "Jumping") then
        playAnim(jumpAnimation)
        return
    elseif (Pose == "FreeFall") then
        MoveFreeFall()
        return
    elseif (Pose == "Seated") then
        MoveSit()
        return
    end

    local ClimbFudge = 0

    if (Pose == "Running") then
        playAnim(runAnimation);
    elseif (Pose == "Climbing") then
        playAnim(jumpAnimation);
    else
        playAnim(idleAnimation);
    end

end

Humanoid.Died:connect(OnDied)
Humanoid.Running:connect(OnRunning)
Humanoid.Jumping:connect(OnJumping)
Humanoid.Climbing:connect(OnClimbing)
Humanoid.GettingUp:connect(OnGettingUp)
Humanoid.FreeFalling:connect(OnFreeFall)
Humanoid.FallingDown:connect(OnFallingDown)
Humanoid.Seated:connect(OnSeated)
Humanoid.PlatformStanding:connect(OnPlatformStanding)
Humanoid.Swimming:connect(OnSwimming)
RunService.Stepped:connect(Move)

问题修复方案

1. 消除动画延迟

当前脚本的核心问题是每次播放动画都重复调用LoadAnimation,这个操作会产生性能开销导致延迟。同时RunService.Stepped每帧触发Move,会反复触发同一动画播放,加剧卡顿。

修改方案:

model = script.Parent
Humanoid = model:WaitForChild("Humanoid")
RunService = game:GetService("RunService")

-- 预加载所有动画轨道,避免重复加载
local idleAnimation = script:WaitForChild('idle')
local walkAnimation = script:WaitForChild('walk')
local runAnimation = script:WaitForChild('run')
local jumpAnimation = script:WaitForChild('jump')
local climbAnimation = script:WaitForChild('climb') -- 新增爬楼动画

local animationTracks = {
    Idle = Humanoid:LoadAnimation(idleAnimation),
    Walk = Humanoid:LoadAnimation(walkAnimation),
    Run = Humanoid:LoadAnimation(runAnimation),
    Jump = Humanoid:LoadAnimation(jumpAnimation),
    Climb = Humanoid:LoadAnimation(climbAnimation)
}

-- 预设动画循环属性
animationTracks.Idle.Looped = true
animationTracks.Walk.Looped = true
animationTracks.Run.Looped = true
animationTracks.Jump.Looped = false
animationTracks.Climb.Looped = true

Pose = "none"
LastPose = Pose

function playAnim(trackName)
    -- 停止非目标动画
    for _, track in pairs(animationTracks) do
        if track.IsPlaying and track ~= animationTracks[trackName] then
            track:Stop()
        end
    end
    -- 播放目标动画
    local targetTrack = animationTracks[trackName]
    if not targetTrack.IsPlaying then
        targetTrack:Play()
    end
end

function SetPose(pose)
    LastPose = Pose
    Pose = pose
end

-- 保留原有的状态监听函数...
function OnRunning(Speed)
    if Speed > 0 then
        SetPose("Running")
    else
        SetPose("Standing")
    end
end

function OnDied()
    SetPose("Dead")
end

function OnJumping()
    SetPose("Jumping")
end

function OnClimbing()
    SetPose("Climbing")
end

function OnGettingUp()
    SetPose("GettingUp")
end

function OnFreeFall()
    SetPose("FreeFall")
end

function OnFallingDown()
    SetPose("FallingDown")
end

function OnSeated()
    SetPose("Seated")
end

function OnPlatformStanding()
    SetPose("PlatformStanding")
end

function OnSwimming(Speed)
    return OnRunning(Speed)
end

function MoveFreeFall()
    -- 保留原逻辑...
end

function MoveSit()
    -- 保留原逻辑...
end

-- 修改Move函数,仅在Pose变化时切换动画
function Move()
    if Pose == LastPose then return end

    if Pose == "Jumping" then
        playAnim("Jump")
    elseif Pose == "FreeFall" then
        MoveFreeFall()
    elseif Pose == "Seated" then
        MoveSit()
    elseif Pose == "Running" then
        playAnim("Run")
    elseif Pose == "Climbing" then
        playAnim("Climb")
    else
        playAnim("Idle")
    end

    LastPose = Pose
end

-- 绑定事件
Humanoid.Died:Connect(OnDied)
Humanoid.Running:Connect(OnRunning)
Humanoid.Jumping:Connect(OnJumping)
Humanoid.Climbing:Connect(OnClimbing)
Humanoid.GettingUp:Connect(OnGettingUp)
Humanoid.FreeFalling:Connect(OnFreeFall)
Humanoid.FallingDown:Connect(OnFallingDown)
Humanoid.Seated:Connect(OnSeated)
Humanoid.PlatformStanding:Connect(OnPlatformStanding)
Humanoid.Swimming:Connect(OnSwimming)
RunService.Stepped:Connect(Move)

2. 修复爬楼梯功能

  • 模型碰撞检查:确保角色的HumanoidRootPart、Torso及肢体部位的碰撞盒大小合理,没有遮挡或过小导致爬楼检测失效
  • 动画适配:导入专门的爬楼动画资源,替换原脚本中爬楼时播放的跳跃动画
  • Humanoid参数设置:开启AutoJumpEnabled,调整WalkSpeed和JumpPower至合理数值,确保角色能正常触发爬楼状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:45:34