播放角色动画

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

播放角色动画 是使虚拟形象和不可玩的角色(NPC)对您的观众有表达力、真实性和吸引力的重要部分。除了提供沉浸式视觉外,角色动画还提供玩家对其行动的反馈、环境导航的指南以及关于他们的角色和其他人的重要信息。

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

  • 用自定义动画替换默认角色动画的资产ID。
  • 在 3D 空间中响应角色行动触发动画。

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

更改默认动画

每个具有默认 Humanoid 对象的角色,无论是玩家控制的虚拟形象还是非玩家角色(NPC),都包含一组 默认动画 ,它们每当角色执行特定体验操作,例如跑步、攀登和跳跃时播放。Roblox 为每个体验提供出盒的动画,无需额外的编程努力。

默认坠落动画

默认游泳动画
>

默认攀爬动画

然而,如果这些默认动画不满足您世界环境、审美或整体叙事的设计要求,您可以用与每个加入您体验的玩家相关的自定义动画进行交换。这种游戏设计技巧可以帮助你的角色和体验感觉更个人、更有吸引力、更沉浸。

为了说明,下面的部分教你如何使用 创建角色动画 的自定义步行周期动画来替换默认的步行动画。使用相同的过程,您可以用自己的动画资产ID替换任何默认动画。

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

创建脚本

每个角色的 Humanoid 对象包括一个存储所有角色默认动画的子对象 Animator 。为了将这些默认动画设置为新的资产ID,您必须在 Class.ServiceScriptService 创建一个脚本,以便它可以引用并覆盖玩家加载到体验中的 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("Animator found!")
    end
    local function onPlayerAdded(player)
    player.CharacterAdded:Connect(onCharacterAdded)
    end
    Players.PlayerAdded:Connect(onPlayerAdded)

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

当它第一次检测到 Animator 对象时,脚本然后打印“发现动画师!”以让你知道脚本正如预期般运行。

替换资产ID

现在你知道你的脚本能够检测玩家加载并连接到服务器时,你可以修改你的脚本来特别引用你想要与自定义动画交换的动画 id(s)。

下表包含所有默认角色动画,您可以在 Animator 对象中调用并替换。请注意,空闲有两种变化,您可以编程播放更多或更少频率。

角色行动动画脚本参考
运行 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("Animator found!")
    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 进入游戏测试模式。

      Play button highlighted in Studio's playtesting options.
    2. 使用你的虚拟形象在空间站周围走动。

触发动画

虽然以前的技巧专注于替换默认动画,随着角色执行特定经验操作时自动播放,但你可以通过编程触发动画来在 3D 空间内响应任何角色行动,例如捡起物品或受到危险的伤害。

在这个例子中,当玩家触碰金色平台时,他们会触发非默认角色舞蹈动画。

播放动画的这种方法有用,因为它可以让玩家立即反馈他们在环境中与对象的互动方式。为了说明,下面的部分向您展示如何在角色距离危险蒸汽泄漏太近时触发动画,以悄悄地教导玩家避免走得太近墙壁。

插入音量

触发独特游戏行为的最常见方法之一是使用 音量 或 3D 空间内的隐形区域检测角色或对象与环境特定区域互动的时间。当你将音量与脚本匹配时,你可以使用其碰撞反馈来通过编程触发行动,例如减少玩家的生命值或播放动画。

A far out view of a mansion room. An outline of a box is in the middle of the room to signify the volume that triggers gameplay events.
Duvall Drive 的神秘使用卷umen触发会改变房间视觉外观的游戏事件。

当将音量添加到你的体验时,它的重要性在于缩放它,以便它仅覆盖你想触发动画的空间。如果你使你的音量过小,玩家可能永远不会碰到区域播放动画;相反,如果你使音量过大,动画将在玩家到达物品或感兴趣区域之前播放,他们可能不会理解他们做了什么才触发了动画。

要插入一个在蒸汽泄漏触发动画周围的音量:

  1. Explorer 窗口中,添加新的块部分。
  2. 位置和调整块,直到它覆盖你想触发动画的区域。
  3. 属性 窗口中,
    1. 名称 设置为 动画检测器

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

      An outline of a block is visible around a steam vent to signify the position of the volume.

创建脚本

现在您已经有一个为启动动画定义的区域,是时候创建一个脚本来检测玩家何时与音量碰撞了。然后,您可以收听碰撞事件,触发任何有意义的动画,以满足您的游戏需求。

例如,这个动画技巧使用了一个 LocalScript 而不是一个 Script 来提供玩家在碰撞音量时立即反馈。如果服务器要收听碰撞并播放动画,那么在玩家触碰音量并观看动画的同时,服务器到客户端的复制时间可能会导致延迟。

要创建一个本地脚本,当本地玩家的角色触碰音量时检测到:

  1. 浏览器 窗口中,添加一个新脚本到 起始角色脚本 。这种布置确保脚本和其子脚本在加入 时克隆到玩家角色上,重生到体验中时。

    1. 扩展 起始玩家 ,然后将鼠标悬停在其 起始角色脚本 子上,然后单击 ⊕ 按钮。
    2. 从上下文菜单中插入 LocalScript ,并将其重命名为 触发动画
  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与音量相关的字符是角色模型的后裔,那么这应该是角色。如果是,函数然后检查是否 是本地 玩家的角色。如果是,那么函数将:

  • 将缓冲设置为 true
  • 播放并等待动画结束。
  • 将缓冲设置恢复到 false

将从 false 设置为 truefalse 的缓冲设置重置后,动画完成播放后,动画不再重复触发,因为玩家继续碰撞音量时,缓冲模式防止动画继续触发。了解有关此缓冲模式的更多信息,请参阅检测碰撞

添加动画

如果你现在玩测试你的体验,你的 TriggerAnimation 脚本仍然无法在响应本地玩家音量碰撞时播放动画。这是因为它正在等待一个具有可参考的动画资产ID的孩子对象Animation ,而那个对象Animation目前不存在。

要为本地脚本添加动画,以便玩家与音量碰撞时参考:

  1. 探索器 窗口中,添加新的动画到 触发动画

    1. 将鼠标悬停在 触发动画 上,然后单击⊕按钮。
    2. 从上下文菜单中插入 动画
  2. 选择新的动画对象,然后在 属性 窗口中,将 动画ID 设置为玩家触发音量时想要触发的动画资产ID。例如,危险空间站 样本参考 rbxassetid://3716468774 播放倒下的角色动画。

  3. 测试你的体验以确保当玩家靠近第一次蒸汽泄漏时,你的动画播放。