中级教程

播放角色动画

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

播放角色动画是让化身和非玩家角色(NPC)对观众表现得生动、现实和吸引人的重要部分。除了提供沉浸式视觉效果外,角色动画还为玩家的动作提供反馈,指导他们如何在环境中导航,并传达有关他们角色及其他角色的重要信息。

危险空间站 .rbxl文件为参考,本教程展示了如何使用两种不同的技术播放角色动画,包括以下指导:

  • 使用您自己的自定义动画替换默认角色动画资产ID。
  • 在3D空间内响应角色动作触发动画。

完成本教程后,您将具备定制动画以适应各种游戏情况的技能。

更改默认动画

每个具有默认Humanoid对象的角色,无论是玩家控制的化身还是非玩家角色(NPC),都包含一组在角色进行特定体验内动作(如奔跑、攀爬和跳跃)时播放的默认动画。Roblox为每个体验提供这些动画,而无需额外的脚本工作。

默认跌落动画
默认游泳动画
默认攀爬动画

然而,如果这些默认动画不符合您世界环境、审美或整体叙事的设计要求,您可以将其替换为适用于每个加入您体验的玩家的自定义动画。

为了演示,下面的部分教您如何用创建角色动画中的自定义行走循环动画替换默认的行走动画。使用相同的过程,您可以将任何默认动画替换为您的动画资产ID。

默认行走动画
自定义行走动画

创建脚本

每个角色的Humanoid对象包含一个子Animator对象,该对象存储角色的所有默认动画。为了将任何这些默认动画设置为新的资产ID,您必须在ServerScriptService中创建一个脚本,以便它可以在玩家加载到体验时引用并覆盖Animator对象的默认值。

要创建一个将引用默认动画资产ID的脚本:

  1. 资源管理器窗口中,向ServerScriptService添加一个新的脚本。

    1. 悬停在ServerScriptService上,然后单击⊕按钮。
    2. 从上下文菜单中插入一个脚本
  2. 在新脚本中,粘贴以下代码:


    local Players = game:GetService("Players")
    local function onCharacterAdded(character)
    local humanoid = character:WaitForChild("Humanoid")
    local animator = humanoid:WaitForChild("Animator")
    print("找到动画师!")
    end
    local function onPlayerAdded(player)
    player.CharacterAdded:Connect(onCharacterAdded)
    end
    Players.PlayerAdded:Connect(onPlayerAdded)

ResetDefaultAnimations脚本首先获取Players服务,该服务包含连接到服务器的所有Player对象。当每个玩家的角色加载到体验时,onCharacterAdded函数等待,直到它检测到角色的HumanoidAnimator对象。

当它首次检测到Animator对象时,脚本会打印“找到动画师!”以让您知道脚本正常工作。

替换资产ID

现在您知道您的脚本能够检测玩家何时加载并连接到服务器,您可以修改脚本以专门引用要用自定义动画替换的动画ID。

以下表格包含您可以在Animator对象中调用和替换的所有默认角色动画。请注意,Idle有两个变体,您可以编程使其播放频率较高或较低。

角色动作动画脚本引用
奔跑animateScript.run.RunAnim.AnimationId
行走animateScript.walk.WalkAnim.AnimationId
跳跃animateScript.jump.JumpAnim.AnimationId
闲置

animateScript.idle.Animation1.AnimationId
animateScript.idle.Animation2.AnimationId

跌落animateScript.fall.FallAnim.AnimationId
游泳animateScript.swim.Swim.AnimationId
游泳(闲置)animateScript.swimidle.SwimIdle.AnimationId
攀爬animateScript.climb.ClimbAnim.AnimationId

要替换默认的行走动画资产ID:

  1. 调用默认行走动画脚本引用,然后用自己的自定义动画资产ID替换资产ID。例如,以下代码示例引用了创建角色动画中的行走循环动画。


    local Players = game:GetService("Players")
    local function onCharacterAdded(character)
    local humanoid = character:WaitForChild("Humanoid")
    local animator = humanoid:WaitForChild("Animator")
    print("找到动画师!")
    local animateScript = character:WaitForChild("Animate")
    animateScript.walk.WalkAnim.AnimationId = "rbxassetid://122652394532816"
    end
    local function onPlayerAdded(player)
    player.CharacterAdded:Connect(onCharacterAdded)
    end
    Players.PlayerAdded:Connect(onPlayerAdded)
  2. 播放测试您的体验,以确保自定义行走动画覆盖默认动画。

    1. 从下拉菜单中选择测试,然后单击其右侧的播放按钮以开始播放测试。

      Studio的夹层测试模式下拉菜单中的测试选项。
    2. 与您的头像在空间站中四处走动。

触发动画

上一技术专注于替换默认的动画,每当角色执行特定的体验内动作时自动播放,但您可以通过编程方式在任何角色动作响应中触发动画,例如捡起物品或受到危害伤害时。

在此示例中,当玩家触碰到金色平台时,他们触发了一个非默认的角色跳舞动画。

这种播放动画的方法是有用的,因为它为玩家提供了如何与环境中的物体互动的即时反馈。为此,接下来的部分向您展示如何在角色太靠近有害的蒸汽泄漏时触发动画,以 subtly 教导玩家避免走得太靠近墙壁。

插入体积

触发独特游戏行为的常见方法之一是使用体积,即3D空间中的隐形区域,以检测角色或物体何时与环境的特定区域互动。当您将体积与脚本配对时,可以使用它们的碰撞反馈编程触发动作,例如减少玩家的健康或播放动画。

一间豪宅房间的远景。房间中央有一个框的轮廓,以标示触发游戏事件的体积。
杜瓦尔驱动的神秘使用体积来触发改变房间视觉外观的游戏事件。

在您的体验中添加体积时,重要的是要调整其范围,以便它仅覆盖您希望触发动画的空间。如果您将体积做得太小,玩家可能永远不会与该区域发生碰撞以播放动画;相反,如果您将体积做得太大,动画将在玩家达到感兴趣的项目或区域之前播放,他们可能无法理解触发动画的动作。

要在蒸汽泄漏周围插入一个将触发动画的体积:

  1. 资源管理器窗口中,添加一个新的块部件。
  2. 位置和调整块的大小,直到它覆盖您希望触发动画的区域。
  3. 属性窗口中,
    1. 名称设置为AnimationDetector

    2. 透明度设置为1,使块不可见。

      一个块的轮廓可见在蒸汽通风口周围,以标示体积的位置。

创建脚本

现在您已经定义了触发动画的区域,是时候创建一个脚本,以编程方式检测玩家何时与体积碰撞。然后,您可以监听碰撞事件以触发任何对游戏需求合适的动画。

例如,此动画技术使用LocalScript而不是Script,以便在玩家与体积碰撞时立即提供反馈。如果服务器监听碰撞并播放动画,玩家在他们的客户端触碰到体积和看到动画播放之间可能会有延迟,因为从服务器到客户端的复制时间。

要创建一个局部脚本,该脚本将检测本地玩家的角色何时触碰体积:

  1. 资源管理器窗口中,向StarterCharacterScripts添加一个新的脚本。此放置确保脚本及其子项在玩家加入重新生成回体验时克隆到玩家角色中。

    1. 展开StarterPlayer,然后悬停在其StarterCharacterScripts子项上,单击⊕按钮。
    2. 从上下文菜单中插入一个LocalScript并重命名为TriggerAnimation
  2. 在新脚本中,粘贴以下代码:


    local Workspace = game:GetService("Workspace")
    local animation = script:WaitForChild("Animation")
    local humanoid = script.Parent:WaitForChild("Humanoid")
    local animator = humanoid:WaitForChild("Animator")
    local animationTrack = animator:LoadAnimation(animation)
    local animationDetector = Workspace:WaitForChild("AnimationDetector")
    local debounce = false
    animationDetector.Touched:Connect(function(hit)
    if debounce then
    return
    end
    local hitCharacter = hit:FindFirstAncestorWhichIsA("Model")
    if hitCharacter ~= localCharacter then
    return
    end
    debounce = true
    animationTrack:Play()
    animationTrack.Ended:Wait()
    debounce = false
    end)

TriggerAnimation脚本首先获取Workspace服务,该服务包含3D世界中存在的所有对象。这一点很重要,因为脚本需要引用作为体积的Part对象。

对于加载或重新生成回体验的每个玩家角色,脚本等待:

  • 它的子Animation对象,您将在下一部分中添加。
  • 角色的HumanoidAnimator对象。
  • 工作区中的名为AnimationDetector的体积对象。

当任何东西与体积发生碰撞时,Touched事件处理函数会获取第一个祖先,它是Model,如果碰撞到体积的BasePart是角色模型的后代,它应该就是角色。如果是,该函数接着检查Model是否为本地玩家的角色。如果是,该函数接下来将:

  • 将debounce设置为true
  • 播放并等待动画结束。
  • 将debounce重置为false

将debounce从false更改为true,再改回false,在动画播放完后唤醒是一种防抖模式,可防止动画在玩家连续碰撞体积时反复触发。有关此防抖模式的更多信息,请参见检测碰撞

添加动画

如果您现在播放测试您的体验,您的TriggerAnimation脚本仍然无法对本地玩家与体积的碰撞播放动画。这是因为它在等候一个带有资产ID的子Animation对象,供它引用,而这个Animation对象目前并不存在。

要为局部脚本添加一个动画以供在玩家与体积碰撞时引用:

  1. 资源管理器窗口中,向TriggerAnimation添加一个新的动画。

    1. 悬停在TriggerAnimation上,单击⊕按钮。
    2. 从上下文菜单中插入一个Animation
  2. 选择新动画对象,然后在属性窗口中,将AnimationID设置为您希望在玩家触碰体积时触发的动画资产ID。例如,危险空间站示例引用rbxassetid://3716468774以播放角色向后跌落的动画。

  3. 播放测试您的体验,以确保在玩家接近第一个蒸汽泄漏时可以播放动画。

©2026 Roblox Corporation、Roblox、Roblox 标志及 Powering Imagination 是我们在美国及其他国家或地区的注册与未注册商标。