在 Roblox 中,动画被锁定给拥有那些动画的用户所拥有的体验。为了防止在将体验转移到群组时动画破碎,您必须将动画资产发布给新体验群组所有者。
如果您有大量需要上传的动画,您可以使用社区支持的工具 Roblox 动画传输 重新上传动画并将其旧的 AnimationIds 重新映射到新的相应 AnimationIds。
前提条件
在传输动画之前,你必须安装 npx。npx 允许你从包裹中运行命令,而无需在系统上安装这些包裹。要检查 npx , 请在终端窗口安装 node.js 并运行 npx –version .
了解有关必要条件的更多信息,请参阅 Roblox 动画传输 README。
将地图动画Id映射到名称
如果你的动画被存储在体验中的预先准备角色模型下的动画实例中,你可以生成一个文本文件来映射 AnimationIds 到相应的名称。
在 Roblox Studio 中,运行以下脚本。Studio 将输出结果作为单个长字符串。
local Workspace = game:GetService("Workspace")local ANIMSTRING = ""for _, character in Workspace:GetChildren() doif not character:IsA("Model") thencontinueendlocal animations = character:FindFirstChild("Animations")if not animations thencontinueendfor _, animation in animations:GetChildren() dolocal animationId = string.match(animation.AnimationId, "%d+")if animationId thenANIMSTRING ..= (animationId .. " " .. character.Name .. "_" .. string.gsub(animation.Name, " ", "_") .. "\n")endendendprint(ANIMSTRING)在您的计算机上创建一个新的文本文件。
将 Studio 的字符串输出粘贴到文本文件。
清理任何与文件内容自动添加的额外 -Edit 和 -Studio 字符串一样的差异。
将所有空格替换为斜线以限制最终审核的名称数量。
(可选)准备文本文件
Roblox 对动画上传有内部速率限制。Roblox 动画传输工具不遵守此速率限制,可能会在传输过程中导致问题并破坏最终的文本文件。例如,你可能会转移 1200 个动画,但最终只有 900 个动画没有转移,没有方法来确定哪些没有转移。
为了确保最终文件不会破碎,您可以:
- 将您的文本文件拆分为每个最多 200 个动画的多个文件
- 在每个文件上使用 Roblox 动画传输工具。为了防止任何重大速度限制问题,请在每批之间等待几分钟。
传输动画
在您的文本文件准备好之后,启动传输过程:
- 打开终端窗口。
- 运行 npx roblox-animation-transfer --inFile animations.txt --group YOUR_GROUP_ID --outFile newAnimations.txt .
- --inFile 必须指向要上传的动画的文件。该文件可以是您最初创建的大文本文件,或者如果您选择拆分较大文件,则可以是几个较小文件的第一个。
- --group 必须指向接收动画传输的群组的 GroupId 。您可以在 Roblox 网站上的群组 URL 中找到群组 ID。
- --outFile 必须指向你想要放置新动画的文件。
如果传输过程成功,在 outFile 中的动画按照在 inFile 中提供的顺序列出。如果一些动画无法传输,工具会再次尝试传输它们;如果第二次尝试成功,这些动画将被添加到列表的末尾在 outFile 。
在运行时加载动画
将动画转移到新群组所有者后,您必须交换旧动画换取新动画。
在工作室中,创建一个 Animations 模块。
创建两个子模块,一个对应用户,或原始所有者,另一个对应群组,或新所有者。
如果您选择将体验发布到另一个位置,运行以下脚本以防止体验中断。默认情况下,脚本返回用户的动画。
local module = {}local GROUP_ID = 12345678local gameContext = {["User"] = require(script:WaitForChild("Animations_User")),["Group"] = require(script:WaitForChild("Animations_Group"))}local function getAnimationMapForGameContext()if game.CreatorType == Enum.CreatorType.Group and game.CreatorId == GROUP_ID thenreturn gameContext.Groupendreturn gameContext.Userendlocal animationMap = getAnimationMapForGameContext()function module.getAnimation(animName: string)return animationMap[animName]endreturn module将生成的文本文件转换为工作室的动画地图。
- 将 animFileText 变量中的动画列表替换为你想要转换为动画地图的文本文件的内容
- 运行以下脚本以返回字符串:
local animFileText = [[4215167 Animation_Name_16171235 Animation_Name_21251267 Animation_Name_3]]local function convertFileToAnimationMap(animFileText: string)local NEW_ANIMATION_MAP = ""local lines = string.split(animFileText, "\n")for _, line in lines dolocal components = string.split(line, " ")if #components ~= 2 thencontinueendlocal animationId = components[1]local animationName = components[2]NEW_ANIMATION_MAP = string.format("%s\t[\"%s\"] = \"rbxassetid://%s\",\n", NEW_ANIMATION_MAP, animationName, animationId)endreturn string.format("return {\n%s}", NEW_ANIMATION_MAP)endprint(convertFileToAnimationMap(animFileText))创建一个新的 ModuleScript 父辈对你的 Animations 模块。
将返回的 animFileText 字符串放置在 ModuleScript 内。
通过运行以下脚本更新体验,将所有动画源于Animations模块:
local Animations = require(PATH.TO.ANIMATIONS)local warriorWalk = Instance.new("Animation")warriorWalk.AnimationId = Animations.getAnimation("Warrior_Walk")