播放角色动画

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

播放角色动画 是使头像和非可玩角色 (NPC) 表现出色、逼真且吸引观众的重要部分。除了提供沉浸式视觉效果外,角色动画还为玩家的动作提供反馈,指导他们如何在环境中导航,并提供有关他们角色及其他角色的重要信息。

使用 Hazardous Space Station .rbxl 文件作为参考,本教程向您展示如何使用两种不同的技术播放角色动画,包括以下指导:

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

完成本教程后,您将具备为各种游戏情况自定义动画的技能。

更改默认动画

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

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

但是,如果这些默认动画不符合您世界的环境、审美或整体叙事的设计要求,您可以用适用于每个加入您游戏的玩家的自定义动画替换它们。

为了演示,以下部分教您如何用来自 Create Character Animations 的自定义行走循环动画替换默认行走动画。使用相同的过程,您可以用自己的动画资产 ID 替换任何默认动画。

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

创建脚本

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

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

  1. Explorer 窗口中,向 ServerScriptService 添加一个新脚本。

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

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

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

当它第一次检测到 Animator 对象时,脚本会打印 "找到 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。例如,以下代码示例引用来自 Create Character Animations 的行走循环动画。

    local Players = game:GetService("Players")
    local function onCharacterAdded(character)
    local humanoid = character:WaitForChild("Humanoid")
    local animator = humanoid:WaitForChild("Animator")
    print("找到 Animator!")
    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. 从下拉菜单中选择 Test,然后单击其右侧的 Play 按钮以开始游戏测试。

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

触发动画

虽然前面的技术专注于替换在角色执行特定游戏内动作时自动播放的默认动画,但您可以以编程方式触发动画以响应 3D 空间中的 任何 角色动作,例如捡起物品或受到危险的伤害。

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

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

插入体积

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

一间豪宅房间的远景。房间中间有一个框的轮廓,表示触发游戏事件的体积。
《Duvall Drive 的谜团》使用体积触发改变房间视觉外观的游戏事件。

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

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

  1. Explorer 窗口中,添加一个新的块部件。
  2. 定位并调整块的大小,直到它覆盖您想要触发动画的区域。
  3. Properties 窗口中,
    1. Name 设置为 AnimationDetector

    2. Transparency 设置为 1 以使块不可见。

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

创建脚本

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

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

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

  1. Explorer 窗口中,向 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 脚本仍然无法在本地玩家与体积碰撞时播放动画。这是因为它在等待一个子 Animation 对象,该对象具有可以引用的动画资产 ID,而该 Animation 对象当前不存在。

要为本地脚本添加一个动画,以便在玩家与体积碰撞时引用:

  1. Explorer 窗口中,向 TriggerAnimation 添加一个新动画。

    1. 将鼠标悬停在 TriggerAnimation 上并单击 ⊕ 按钮。
    2. 从上下文菜单中插入一个 Animation
  2. 选择新动画对象,然后在 Properties 窗口中,将 AnimationID 设置为您希望在玩家触碰体积时触发的动画资产 ID。例如,Hazardous Space Station 示例引用 rbxassetid://3716468774 来播放角色向后跌倒的动画。

  3. 进行游戏测试以确保当玩家靠近第一个蒸汽泄漏时,动画会播放。

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