自定义角色

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

您可以导入自定义网格来创建从NPC到动画帆船布料的所有内容。我们使用了导入器的自定义设置来引入更奇异的自定义角色,例如神秘的黑洞生物和友好的、但不太自觉的服务机器人。

以下部分将介绍我们如何使用绑定和蒙皮PBR(表面外观)和VFX构建我们更复杂的角色之一,命名为“生物”。我们希望它能发光、发出一些光、留下粒子烟雾的轨迹,并具有流畅的运动,这涉及到为一个有足够关节创建的模型进行蒙皮,以生成其触手的逼真波浪。

生物横幅

绑定

在我们为生物进行绑定时,我们发现最好以中性姿势建模角色,因为这种姿势最适合向多个方向弯曲。如果我们把生物的触手建模为已经卷曲的姿势,如果我们将触手动画为向相反方向弯曲,会导致拉伸。以下截图展示了生物的自然状态:

从中性姿势开始,我们经济地添加了关节,重点关注需要最多运动的区域。关节越少越好,因为您在进行角色蒙皮时需管理它们,并且在动画时控制的内容会更少。在之前的截图中,生物的中心看起来有很多关节,但主干只有一个关节。

其他大多数关节都位于触手和下颚处。对于触手,我们希望有很多二次运动,即分层的运动,以创建一个逼真的效果,让它们看起来都在独立移动。然而,触手的中心质量如此接近,以至于为它们的每一个设立关节都感觉浪费,无论是在性能上还是在动画上。因此,我们将中心质量视为一个较大的触手,并在末端添加了更小的“尾巴”。

生物前面,Maya

我们发现以下指导原则很有用,以确保角色网格正确导入到Studio中:

  • 每个关节和骨头必须有唯一的名称。
  • 网格的名称不得与关节和骨头相同。
  • 网格在蒙皮/绑定之前不得有变换;换句话说,变换应该为0,比例应该为1。
  • 网格法线应该朝外(模型不应是内外反转)。
  • 骨架不应有任何比例因子;所有关节的比例应为[1, 1, 1]。

蒙皮

当我们完成生物的骨架后,下一步是对网格进行蒙皮。蒙皮可能是一项繁琐的任务,因此为了简化问题,最好熟悉您的DCC应用程序中的不同初始蒙皮设置,以找到您喜欢的设置。 由于这是一个有机角色,我们在每个关节上使用了大量的衰减,并在它们之间进行了重叠。这样,弯曲感就会平滑而不是尖锐。以下截图分别展示了糟糕的蒙皮和平滑的蒙皮:

糟糕的蒙皮
平滑的蒙皮

我们发现以下指导原则产生了最佳的蒙皮结果:

  • 蒙皮影响(意味着它们在移动时影响模型的一部分)每个顶点的最大影响应为4个。
  • 关节和网格名称需要唯一,彼此之间也需唯一。
  • 您想导入Studio的任何关节必须对模型的蒙皮有一定影响,否则引擎不会导入它。 每当可能时,请在模型的原始或“绑定”姿势下进行蒙皮。

将网格导入Studio

将自定义角色导入Studio是流程中最令人兴奋的部分之一,因为您可以在自己构建的体验中查看自己的创作!

要将网格导入Studio:

  1. 从DCC应用程序导出角色,并确保以下事项:

    • 所有法线、比例和名称都是正确的。
    • 角色具有所有关节和骨头层次结构,以及所有网格。
    • 每部分网格的三角形数量均在10,000个以下。
    • 网格的总大小在任何轴上均不超过2000个单位。
    • 请查看网格要求,获取完整的模型规范列表。
    生物在DCC工具中
  2. 导入器中,导入自定义的.fbx.obj文件。

    生物导入到Studio

让生物发光

一旦生物的模型稳定并且不再需要立即导入Studio,我们就开始组合表面外观对象、光源和视觉效果。我们这样做是为了确保模型的质量足够好,然后再进行对其任何一个方面的放置和编辑。

发光生物示例

我们知道我们想让生物看起来黑暗,而焦点是它的眼睛和“抓住”的触手。高对比度的重点往往会吸引注意力,因此拥有几个强烈的对比能够确保观众知道关注的重点。Studio支持自发光的霓虹材料,因此早期我们将眼睛分开,使其可以与角色的其余部分成为自己的材料。对于触手,我们也做了类似的处理,让它们只有尖端发光。

生物眼睛在Studio中

霓虹材料并不发出真正的光,因此经过一些测试后,我们添加了独立的部分来控制光源的放置和发光方向。这确保了照明以增强眼睛的发光效果,并且也投射出自己的光源。

Studio中的点光源

请注意,SpotLights在靠近其他表面或玩家时为生物增添了视觉效果。

生物光源示例

此外,我们希望生物的触手能释放一些粒子,以便在移动时留下烟雾轨迹。由于触手非常长,将ParticleEmitter添加到整个触手会使粒子从整个触手发出而不是从尖端。为了应对这一点,我们在触手的末端附近使用了一个小部件,以便我们可以控制粒子的发射大小、位置和方向。

粒子示例

让视觉特效跟随角色

当生物动画时,已绑定角色的网格位置不会更新,因此我们需要一种方法来确保视觉特效、声音特效和光源都正确地跟随生物。为此,我们创建了一个VFX控制器脚本,并使用CollectionService来告知包含VFX的部件生物的骨骼位置,并跟随它们。

  1. 我们在StarterPlayerStarterPlayerScripts中放置了以下LocalScript。这基本上运行VFX更新功能。

    本地脚本

    -- 将此代码段添加到现有的本地脚本中以创建PreSimulation
    -- 连接
    local RunService = game:GetService("RunService")
    local vfx = require(workspace.VfxUpdateModule)
    RunService.PreSimulation:Connect(vfx.updateVfx)
    模块脚本

    -- 该模块附加部件到动画,因此它们会在动画播放时更新。
    -- 这是一种绕过当前关节和骨骼限制的解决方法,
    -- 不一定总是必要。
    --
    -- 前提条件:
    -- 要包含的模型需要有“AnimatedVfxModel”标签,以及一个
    -- 包含所有希望与动画同步的部件的文件夹。每个部件需要有
    -- 一个名为“AttachedBoneName”的属性,指向希望附着的骨骼名称。
    -- 部件也应该已经相对于所需骨骼处于正确的位置。
    --
    -- 使用方法:
    -- 一个本地脚本应该要求此模块,然后连接
    -- VfxUpdateModule.updateVfx至RunService.PreSimulation事件。
    local VfxUpdateModule = {}
    local CollectionService = game:GetService("CollectionService")
    -- SETUP - 这应该在每个客户端上运行一次。
    -- 收集所有带有标签的模型
    local vfxModels = CollectionService:GetTagged("AnimatedVfxModel")
    local vfxTable = {} -- 我们将存储所有部件和偏移量的地方
    -- 为每个模型分配一个表,以保存所有的vfx部件和偏移量
    for _, model in vfxModels do
    vfxTable[model] = {}
    local vfxParts = model:FindFirstChild("VFX"):GetChildren() -- 找到VFX文件夹
    -- 通过属性找到骨骼并计算每个部件的偏移量。
    for _,part in vfxParts do
    local name = part:GetAttribute("AttachedBoneName")
    local bone = model:FindFirstChild(name, true)
    if bone then
    local offset = (bone.TransformedWorldCFrame:inverse() * part.CFrame)
    vfxTable[model][part] = {bone, offset}
    else
    warn("Vfx部分引用了找不到的骨骼。")
    end
    end
    end
    print(vfxTable)
    -- UPDATE - 这应该链接到每个客户端的RunService.PreSimulation
    -- 遍历所有模型,然后更新模型上的所有部件以匹配骨骼框架。
    function VfxUpdateModule.updateVfx()
    for model, vfxParts in vfxTable do
    for part, bone in vfxParts do
    part.CFrame = bone[1].TransformedWorldCFrame * bone[2]
    end
    end
    end
    return VfxUpdateModule
  2. 我们创建了一个VFXUpdateModuleModuleScript,以告知任何适当标记为AnimatedVfxModel的对象在播放事件上进行更新。

  3. 我们使用其属性中的标签部分,对必要的模型组进行了AnimatedVfxModel的标记。使用标签允许VFXUpdateModule知道要查找的第一个VFX子项,并应用更新。

    Studio中的视觉特效示例
  4. 最后,我们为希望进行动画的部件添加了一个AttachedBoneName自定义属性,并添加了希望其跟随的关节的确切名称。

为生物上纹理

接下来,我们设置了PBR(物理基础渲染)纹理贴图。这些强大的位图赋予生物多样的光泽和表面变化,使它看起来有许多小凸起和缺陷。这种视觉效果在生物靠近玩家时帮助展现其外观。

生物纹理比较

以下是我们创建表面外观纹理贴图的步骤:

  1. 该角色的纹理贴图都在每张“表”上。这使得生物更高效,并且需要处理的纹理贴图或SurfaceAppearance对象更少。

  2. 对于需要发光或自发光的区域,例如“抓住的触手”,我们还在SurfaceAppearance上使用透明度与这些部件融为一体。

    照明示例

    我们发现遵循以下指导原则在创建表面外观纹理贴图时有帮助:

    • 确保您的贴图不大于1024×1024。
    • 您的绿色通道可能需要翻转,具体取决于您使用的应用程序。

为生物动画

动画是非常主观的,并具有个人风格。选择包括动作捕捉、在DCC应用程序中手动"关键帧"动画,或使用Studio强大的动画编辑器

正如我们之前提到的,我们希望确保拥有足够的关节以实现流畅的运动,以及足够的肢体,使生物动画感觉自然且分层。分层,也称为二次运动,是您在日常生活中看到的——当您伸出手臂时,每个关节都在对上臂的初始冲动做出反应,并且您身体中的每个关节不会同时移动或休息。

我们使用这种技术让生物的动画感觉像是四肢在响应身体驱动的运动,如下所示:

生物动画示例

如果使用外部DCC应用程序进行动画,我们发现以下指导原则效果最佳:

  • 将帧速率设置为至少30 FPS。
  • 使用与您正在应用的相同角色创建动画。
  • 将您的动画数据作为单独的.fbx文件导出。

因为我们在Studio外部对角色进行了动画,因此我们需要使用动画编辑器来导入动画.fbx文件。编辑器允许您选择任何带有关节或马达的化身,并通过时间线中的点驱动它们。

要导入动画:

  1. 在工具栏的化身选项卡中,单击剪辑编辑器

  2. 选择您要在Roblox中动画的绑定角色。该角色应与您在外部DCC应用程序中绑定的角色相同。

  3. 单击编辑器窗口左上角的**⋯按钮,选择从FBX动画导入**,并找到您导出的.fbx动画文件。

    动画导入示例2
  4. 当您对动画满意时,您可以导出它以发现动画ID,您随后可以在Roblox脚本中使用该ID来运行它。例如,您可以向导入角色的模型组添加一个Script,并使用以下代码运行动画:

    动画脚本示例

    local animationId = "YOUR_ANIMATION_ID"
    local char = script.Parent
    local animController = char:FindFirstChildWhichIsA("Humanoid") or char:FindFirstChildOfClass("AnimationController")
    local animation = Instance.new("Animation")
    animation.AnimationId = "rbxassetid://" .. tostring(animationId)
    local animTrack = animController:LoadAnimation(animation)
    animTrack:Play(0, 1, 1)

最终结果

在对颜色、光亮度和一些额外粒子效果进行几次最后的微调,以使其在窗前产生更强的光环效果后,这就是空间站中的最终结果!

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