开发者们,你们好!
我们很高兴地宣布 3D 层叠服装技术现在已经可以在你的作品中使用了!
层叠服装是特殊建模的 3D 资源,任何虚拟形象都可以穿戴与其他任意层叠服装的搭配组合。层叠服装可在虚拟形象的身体与其他层叠服装物品的基础上任意拉伸构型,而不会穿模或破图。
层叠服装需先在 Maya 或 Blender 中完成设计,然后导入进 Roblox Studio 并通过 WrapLayer 和 WrapTarget 应用至虚拟形象上。正是这两个新实例背后的技术使层叠服装的实现成为了可能。
本帖将对层叠服装的结构细节,以及如何在你的作品中启用、创造与添加层叠服装进行说明。
作品注意事项:层叠服装目前在虚拟角色产品目录中尚不可用。同样地,本次发布阶段内,在运用了层叠服装技术的作品中获取或装备的配件和服装也无法在该作品之外显现。
目前 Roblox 尚不建议开发者在作品内将层叠服装资源商品化。
启用层叠服装的作品通常会消耗更多性能。请在下方的论坛帖子中报告任何与性能有关的故障问题,同时附上运行设备与硬件配置规格。
层叠服装结构
层叠服装是一种 3D 配件,通过附件连接至虚拟形象的身体部位。
通过你在建模时创建的额外几何图形,层叠服装可以得当地贴合虚拟形象与配件。这些不可见的外表面与内表面称为外笼形与内笼形,其作用类似碰撞盒,可避免一件服装物品在 3D 空间中穿过另一件服装物品。
关于在 Maya 或 Blender 中建模层叠服装的详细要求,请参考层叠服装资源要求。
在 Studio 中设置内笼形与外笼形
如果 3D 资源的建模正确,可通过以下定义笼形的实例之一作为 MeshPart 导入到 Studio 中:
- WrapTarget 定义可在上面叠加配件的第一个外部表面。在层叠服装的情况下,WrapTargets 几乎总是参考虚拟形象的外笼形。外笼形通过 CageMeshID 来设置。
- WrapLayer 定义父项配件的内笼形与外笼形,以便将配件叠加在现有的表面之上,同时也为在它上面的额外层提供一层外表面。内笼形通过 ReferenceMeshID 来进行设置。
创建层叠服装
在 Blender 和 Maya 中创建你的层叠服装模型,并导出为 .fbx 文件。层叠服装资源必须符合以下要求:
- 资源必须包含一个内笼形网格和一个外笼形网格。
- 资源内的笼形层必须有相同的 UV 贴图。
- 资源必须配置权重并且设为正确的骨头或骨架的父项。
关于如何准备用于层叠服装的 3D 资源,请参考层叠饰品资源要求。
示例 3D 资源与项目文件
参考文件可从这里下载,包含以下内容:
- Clothing_Editor_Baseplate.rbxl - 此空间包含 100 多个可任意探索与测试的层叠服装配件
- 各种配件 (.fbx) - 可直接导入至 Studio 的 3D 配件模型(见下文)
在作品中启用层叠服装
首先需要启用 Studio 的测试版功能。在 File(文件)菜单中,选择 Beta Features(测试版功能)并启用 3D Layered Clothing(3D 层叠服装)。
层叠服装需要启用 LoadCharacterLayeredClothing 来允许虚拟形象装备 3D 饰品。在你的作品中启用层叠服装渲染的方法如下:
- 在资源管理器中,选择 StarterPlayer 并在 Properties(属性)窗口中找到 Character(角色)部分。
将 LoadCharacterLayeredClothing 属性设为 Enabled(启用)。
导入层叠服装作品
用 Avatar Importer(虚拟形象导入器)插件将 .fbx 导入进 Studio。切记, .fbx 文件和与其关联的纹理 .png 文件必须位于同一个文件夹内。导入层叠服装文件的方法如下:
- 在 Plugins(插件)选项卡中,选择 Avatar Importer(虚拟形象导入器)
2.选择 Custom(自定义)
- 选择你的 .fbx 文件。资源会在工作区中作为一个名为 FBXImportGeneric 的 MeshPart 出现
可选:为你的资源添加 PBR 纹理
在提供的许多资源文件中都包含额外的 PBR 纹理,用于表现出真实的光照和表面效果。可通过 SurfaceAppearance 来向 MeshPart 添加这些纹理文件:
- 用 Asset Manager(资源管理工具)上传关联的 .PNG 文件。
注意:导入资源之前必须先发布作品。
2. 选择 FBXImportGeneric 模型内的 Tshirt_001 MeshPart,并添加一个 SurfaceAppearance 对象。
3. 在 SurfaceAppearance 中用创建的对应纹理 ID 设置外观映射。使用文件名的对应后缀来映射纹理:
- ColorMap:“_DIF”
- MetalnessMap:“_MET”
- NormalMap:“_NOR”
- RoughnessMap:“_RGH”
将 MeshPart 设置为配件
将 MeshPart 组织为可供虚拟形象装备的配件实例的方法如下:
- 在工作区中添加一个 Accessory(配件)实例,并将你的层叠服装配件命名为“Tshirt_001”。
- 将 Tshirt_001 MeshPart 拖拽至 Accessory(配件)实例,将其设为 MeshPart 的父项。
- 将“Tshirt_001”MeshPart 重命名为“Handle”(握柄),以符合配件命名惯例。
- 确认“Handle”MeshPart 含有 WrapLayer 实例。
- 在 Handle(握柄)内添加一个 Attachment(附件)。
6.将 Attachment(附件)重命名为“BodyFrontAttachment”来确保它能被附加到对应的身体部件上。有效的附件名称列表请参见附件点 。
应用层叠服装至虚拟形象
在当前的开发者版本中,装备配件有两种主要方式:
- 通过 Humanoid:AddAccessory(),无需指定 Asset ID(资源 ID)。
- 通过 HumanoidDescription System,需指定 Asset ID(资源 ID)。
在将来的版本中,你将可以上传层叠服装资源来生成你自己的 Asset ID(资源 ID)。
** 不指定 Asset ID(资源 ID)装备配件**
此方法应用于在 Asset ID(资源 ID)尚不可用的情况下装备层叠服装。在游戏中装备配件的方法如下:
将 Tshirt_001 配件拖拽至 ServerStorage。
在 ServerScriptStorage 中,添加一个带有以下内容的 Script(脚本):
local myAccessoryAsset = "Tshirt_001" --将 Tshirt_001 替换为你的配件的名称
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAppearanceLoaded:Connect(function(character)
while nil == character.Parent do
wait()
end
local humanoid = character:WaitForChild("Humanoid")
if humanoid then
humanoid:AddAccessory(game.ServerStorage:WaitForChild(myAccessoryAsset))
end
end)
end)
指定 Asset ID(资源 ID)装备配件
HumanoidDescription 用于描述一个 Humanoid(人形对象)角色装备的所有资源。AccessoryBlob 是 Humanoid(人形对象)装备的所有配件的表,可以在 HumanoidDescription 属性面板中直接编辑,也可以通过 HumanoidDescription.SetAccessories() 在以编程方式编辑。
Asset ID(资源 ID)可通过上传资源取得,也可使用现有的 Catalog Asset ID(目录资源 ID)。在上传层叠服装功能开放之前,请使用代码示例中的现有 Asset ID(资源 ID)或示例资源。
通过属性面板装备
在属性面板中编辑配件团块并装备层叠服装的方法如下:
- 选择 Workspace(工作区)并添加“HumanoidDescription”。
在 Properties(属性)中,按以下格式设置“Accessory Blob”(配件团块)属性:
[{“AssetId”: 6984765766, “Order”:1, “AccessoryType”:“Jacket”, “Puffiness”:0.5}]
如果有多个配件,使用以下格式;
[{“Order”:1, “AccessoryType”:“Jacket”, “Puffiness”:0.5, “AssetId”:6984765766},
{“Order”:2, “AccessoryType”:“Sweater”, “Puffiness”:0.7, “AssetId”:6984771334}]
注意:Puffiness(膨胀度)是可选键,会影响服装物品的体积。
创建好 HumanoidDescription 后,你可以在工作区中的一个脚本里使用以下代码示例,在玩家被生成时将 HumanoidDescription 应用至所有玩家。
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAppearanceLoaded:Connect(function(character)
while nil == character.Parent do
wait()
end
local humanoid = character:WaitForChild("Humanoid")
if humanoid then
humanoid:ApplyDescription(game.Workspace.HumanoidDescription)
end
end)
end)
因 HumanoidDescription 只包含单个配件的数据,玩家将生成为带有一个配件的默认块状角色造型。
通过脚本装备
通过 HumanoidDescription.SetAccessories() 装备层叠服装的方法如下:
- 在 ServerScriptService 中创建一个脚本。
- 复制下面的示例并选择 Play(游玩)。
-- 防止作品在我们应用配件之前 autoloading(自动加载)玩家
game.Players.CharacterAutoLoads = false
-- 此表设置层叠服装物品的顺序。数字较大的层会叠加在数字较小的层上方。
local DefaultLayeredClothingOrder = {
[Enum.AccessoryType.LeftShoe] = 3,
[Enum.AccessoryType.RightShoe] = 3,
[Enum.AccessoryType.Pants] = 4,
[Enum.AccessoryType.Shorts] = 5,
[Enum.AccessoryType.DressSkirt] = 6,
[Enum.AccessoryType.TShirt] = 7,
[Enum.AccessoryType.Shirt] = 8,
[Enum.AccessoryType.Sweater] = 9,
[Enum.AccessoryType.Jacket] = 10,
[Enum.AccessoryType.Hair] = 11,
}
-- 为新的层叠服装配件创建一个条目(一件橙色夹克):
local lcAccessoryData = {}
lcAccessoryData["AccessoryType"] = Enum.AccessoryType.Jacket
lcAccessoryData["AssetId"] = 6984765766 -- 橙色夹克
lcAccessoryData["Order"] = DefaultLayeredClothingOrder[Enum.AccessoryType.Jacket]
-- SetAccessories 预期一个配件条目的表:
local accessories = {}
accessories[1] = lcAccessoryData
-- 以新配件加载玩家
game.Players.PlayerAdded:Connect(function(player)
-- 从 UserId 获取 HumanoidDescription 并复制
local currentHumanoidDescription = game.Players:GetHumanoidDescriptionFromUserId(player.UserId)
local newHumanoidDescription = currentHumanoidDescription:Clone()
-- 向人形对象应用新的描述:
newHumanoidDescription:SetAccessories(accessories, --[[includeRigidAccessories = ]] false)
player:LoadCharacterWithHumanoidDescription(newHumanoidDescription)
end)
注意:HumanoidDescription 也支持刚性配件。使用 HumanoidDescription.GetAccessories(true) 和 HumanoidDescription.SetAccessories(Accessory Table, true) 形参来包含刚性配件。
HumanoidDescription 也可通过 Players:CreateHumanoidModelFromDescription() 应用至带有 HumanoidDescription 的NPC。