开放动画替换器——Open Animation Replacer
转自:https://www.nexusmods.com/skyrimspecialedition/mods/92109一个 SKSE 框架插件,可根据可配置的条件替换动画。带有游戏内编辑器。具有向后兼容性且功能更多。可被其他 SKSE 插件扩展。支持特别版 / 周年纪念版 / 虚拟现实版。开源。
介绍:
当动态动画替换器(Dynamic Animation Replacer)未针对《上古卷轴 5:天际》的最新版本进行更新,且没人知道它是否还会更新时,我就开始着手开发这个插件了。在我开始开发后不久,DAR 突然收到了一次更新,而那时我在自己这个作为 DAR 替代品的插件上已经取得了重大进展。我决定继续开发,专注于添加新功能并确保其可扩展性。
动画师们对动画替换器有不少 DAR 不支持的需求。而且 DAR 是闭源的,所以当原作者不再更新时,其他人无法对其进行更新,这一点已经在它长时间未针对《上古卷轴 5:天际》的最新补丁进行更新时得到了证明,当时人们因为无法使用一些很棒的动画替换器,甚至不得不降低游戏版本。这种情况很可能会再次发生 ——《上古卷轴 5:天际》在 Steam 的私人开发分支上一直有定期更新 —— 这意味着可能又会有一个(大的?)补丁发布,届时可能需要更新 SKSE 插件。闭源还意味着其他人无法为该插件做贡献。费利斯基(DAR 的作者)已经表示他们没时间再做模组了,所以在可预见的未来,我们确实无法期待 DAR 会有新功能。动态动画替换是一个极其强大的概念,它让很多很棒的模组得以实现,我认为它值得进一步迭代和开发。
这个插件不是对动态动画替换器的逆向工程修改版。除了与游戏代码本身交互且只能以一种方式实现的部分外,它不包含任何 DAR 的代码。它是我自己的成果,主要基于我自己对游戏的研究。
在这个插件开发的后期,当我已经基本完成核心部分并专注于游戏内编辑器时,有人对 DAR 进行了逆向工程,并将其发布在了 GitHub 上(后来甚至移植到了 CommonLibSSE)。你可以将其源代码与我自己的进行比较,就会发现完全不同。
开放动画替换器有一个 SKSE 插件应用程序接口(API),允许其他插件添加新条件,从而让其他作者能够扩展其可能性,而不必完全依赖原作者。非常欢迎在 GitHub 上通过拉取请求为插件本身添加新功能。
虽然这个插件旨在成为 DAR 的继任者,具备完全的向后兼容性和新功能,但如果你之前还没有下载并认可 DAR,请考虑一下这么做。最初的创意是费利斯基的。
我对这些新的可能性感到非常兴奋,期待着有模组能够利用它们!
功能:
基于可配置条件的动态动画替换。
与基于动态动画替换器的模组完全向后兼容。
新增了许多条件,并对现有条件进行了改进(例如,支持关键字 EditorIDs)。
支持成对动画。
支持非角色动画。
在动画循环和重复播放时能正确替换动画。
过滤掉会导致动画数量限制的重复替换动画,且不影响结果。
提供动画变体,便于随机或按顺序变化。
提供模组范围内的条件预设,可用于子模组,以尽量减少不必要的条件重复。
替换器子模组可以有额外设置,例如:
在动画播放过程中持续检查所需条件,当情况发生变化时立即进行替换,并在新旧动画之间实现适当的融合。
在动画循环时保留随机条件的结果,这对移动模组很有用,这样动画就不会每走几步就被替换。
在整个子模组内共享随机结果,使整个动画集一起随机化。
设置动画被中断和替换时的自定义融合时间。
忽略原版游戏中一些动画剪辑上启用的 “无触发” 动画剪辑标志,该标志通常会导致标注的动画事件被忽略。
设置所需的项目名称(例如,使特定子模组仅为默认男性或默认女性等加载)。
设置包含动画的文件夹名称,这样多个子模组可以包含相同的动画而无需重复。
带有游戏内编辑器,可在游戏中检查和编辑替换器模组的条件、优先级和其他功能,并能立即查看和测试更改效果。
在游戏内编辑器中预览任何替换动画。
提供动画日志用户界面,有助于识别最近播放的动画。
提供动画事件日志用户界面,对行为模组制作者的实时调试很有用。
动画可在主菜单中开始预加载。
显示一个小进度条,展示动画预加载进度。
将每个项目的动画数量限制提高到 32767。
增加 Havok 堆大小,以便在有大量动画时提高稳定性。
为其他 SKSE 插件提供应用程序接口,以便添加新的自定义条件。
所有操作都通过 SKSE 完成,可随时安装或卸载。
实验性特征包括:
・将每个项目的动画数量限制提高到 65534。
技术说明(供感兴趣的人参考):一个 Havok 行为动画剪辑有一个 16 位有符号整数变量(int16),它表示在剪辑被激活时应读取的巨大动画绑定数组中的条目索引。int16 值的最大范围是 -32768 到 32767。然而,几乎整个可能值的负半轴都未被使用。只有 -1 被用作特殊值,比如在动画剪辑未初始化等情况下。这个实验性设置会修补我在游戏代码中能找到的所有将该值视为有符号整数的地方,并更改指令,使其被视为无符号整数(uint16)。无符号整数的值可以从 0 到 65535。之前为 -1 的值仍然被保留,因此动画数量最多可达 65534 个。该设置被视为实验性的,因为我可能遗漏了一些需要修补的地方,而且一开始实际上很少有人会达到 32000 的限制。只有在确实需要或出于好奇时才启用它,不过如果你实际上未超过限制,可能也不会看到任何潜在问题。
・禁用动画预加载。
该设置已被证明存在一些小问题。我仍在寻找其他解决方案,一般来说,我不推荐使用这个设置。
结构:
替换器模组的结构试图保持条理清晰。自 2.0.0 版本起,替换器模组在 Data\Meshes 文件夹内的任何位置都能被识别。确定放置替换器模组的正确方法的一个简单思路是,将其视为用 OpenAnimationReplacer\MyMod\MySubmod\ 这一模块阻断了原始动画路径。
这意味着,对于一个要替换原本位于 Data\Meshes\actors\character\animations\male\mt_idle.hkx 的动画的替换器模组,替换器模组可以按照以下任意示例的方式放置:
Data\Meshes\OpenAnimationReplacer\MyMod\MySubmod\actors\character\animations\male\mt_idle.hkx
Data\Meshes\actors\OpenAnimationReplacer\MyMod\MySubmod\character\animations\male\mt_idle.hkx
Data\Meshes\actors\character\OpenAnimationReplacer\MyMod\MySubmod\animations\male\mt_idle.hkx
等等。
这种结构基于替换器模组包含多个子模组的概念。
每个替换器模组包含一个或多个子模组,以及一个配置.json 文件,目前该文件仅包含模组名称和描述。每个子模组包含替换动画和一个配置.json 文件,该文件包含其中所含动画的所有信息,如子模组名称、描述、优先级、条件和其他特征。
这种替换器→子模组的结构之所以存在,主要是因为大多数动画替换器模组往往都是这样工作的 —— 它们包含多个文件夹,每个文件夹都有不同的条件和动画。现在它们所有的子文件夹都可以整理到一个文件夹中,使结构更加清晰。
OpenAnimationReplacer
├── 替换器模组 1
│├── 子模组 A
││├── [动画文件]
││└── config.json<- 替换器模组配置文件
│├── 子模组 B
││├── [动画文件]
││└── config.json
│└── config.json <- 替换器模组配置文件
└── 替换器模组 2
├── 子模组 C
│├── [动画文件]
│└── config.json
└── config.json
一个树形图,试图展示所需的结构。
与 DAR 不同,这里的优先级不是由文件夹名称定义的。它们可以随意命名!(不过请避免使用非英文字符 / 符号,因为它们可能无法正确读取 —— 欢迎在 GitHub 上由了解 Unicode 字符串和文件路径处理的人发起拉取请求,我放弃了)。
你不必在文本编辑器中手动编辑.json 文件。虽然可以这么做,但游戏内编辑器可以让你完成所有操作,而且使用起来更简单、更安全。手动编辑配置文件时很容易不小心出错。
至于向后兼容性,放置在 DynamicAnimationReplacer 文件夹中的每个模组在加载到游戏中时也会被读取并转换为新结构。由于它们缺少新功能,这些新功能在默认情况下都是关闭的,所以除了像在动画循环或重复播放时重新生成随机条件结果这样的改进外,它们的行为应该与以前完全一样。在 DAR 中没有替换器模组→子模组的概念,所以在编辑器中,所有 DAR 模组都被视为一个名为 Legacy 的大型替换器模组的子模组。它们的名字就是它们的文件夹名字。这是我根据有限信息所能做到的最好处理了。
你甚至可以在游戏中编辑它们并保存用户配置。不过,我鼓励替换器模组作者提供 OAR 版本。如果不是为了新功能,至少也是为了更整洁的组织结构。
请记住,在游戏运行时,你无法实际添加或删除模组中的动画文件,也无法添加 / 删除模组本身,这些操作只有在重启游戏后才会生效。不过,你可以在编辑器中禁用动画或子模组。
自 1.2.0 版本起,一个替换动画可以有多个变体。这是制作随机动画的一种更便捷的方式。以前,要实现多个随机变体,需要创建多个具有相同条件集(包括一个随机条件)的子模组。有了变体,你只需要创建一个没有任何随机条件的子模组。
要为子模组中的一个动画添加变体,在通常放置该动画的位置创建一个子文件夹。将子文件夹命名为 “variants”(例如,对于 “mt_idle.hkx”,文件夹应命名为 “_variants_mt_idle”,并放置在相同位置)。将你想要随机化的该动画的所有变体放入该文件夹中。文件名不重要。不过,我建议使用简短的文件名(甚至 1.hkx、2.hkx 等),以避免长路径可能带来的问题。(也就是说,不是 “submodFolder/male/mt_idle.hkx”,而是 “submodFolder/male/_variants_mt_idle/1.hkx” 等)。
就是这样。当该替换动画应该播放时,插件会识别这些动画并进行随机化处理。
变体随机化会遵循 “在循环 / 重复播放时保留随机结果” 和 “共享随机结果” 等子模组设置,就像随机条件一样。
你可以在游戏内编辑器中,在子模组的替换动画部分,为每个变体配置用于随机化的权重。例如:为一个变体设置权重为 2,会使其播放的可能性是权重为 1 的变体的两倍。
为了让大家更清楚、更容易理解:不要把这想得太复杂。这只是在条件评估之后的一个可选步骤。唯一的区别在于,不是选择并播放一个单一的替换动画,而是从可能的变体中选择一个动画。
自 2.2.0 版本起,变体还有一个额外模式:顺序模式。在这种模式下,它们不是随机选择播放,而是按顺序播放。在这种模式下,一个变体还可以被标记为 “播放一次”,这意味着在这个顺序播放过程中,即使循环回来,它也不会再次播放。在替换动画(或整个动画剪辑)闲置一小段时间后,序列中的下一个变体的索引以及 “播放一次” 的历史记录会重置。
游戏内编辑器:
默认通过按下 Shift + O 可访问的游戏内用户界面,可让你检查和编辑所有已安装的替换器模组。
编辑器一开始可能看起来有点吓人,但我尽量让它对用户很友好。有很多方便使用的功能,比如通过右键点击来复制 / 粘贴条件,或者整个条件集,还可以通过拖放来重新排列条件。
你可以在控制台中选择一个角色,或者在编辑器的左上角输入他们的 FormID。这样就会将其选为当前评估目标。当一个目标被选中时,每个条件都会显示一个图标,表明其要求当前是否得到满足。在某些情况下,相关条件还会提供一个额外字段,显示正在检查的当前值。这有助于轻松识别当前状态,并了解是否需要进行任何必要的更改。
编辑器允许你在三种模式之间切换:检查模式、用户模式和作者模式。
在检查模式下,编辑功能被禁用,提供只读视图。
在作者模式下,更改会直接保存到 config.json 文件中。该文件是主要的配置文件,用于与替换器模组本身一起分发。
用户模式和作者模式,正如其名称所示,分别是为模组用户和模组作者设计的。主要区别在于点击保存按钮时保存的配置文件不同。
在用户模式下,会创建一个 user.json 文件,它会覆盖 config.json 文件中的所有内容,除了子模组的名称和描述。这种模式允许用户对替换器模组进行个性化调整,比如改变优先级、修改条件或禁用动画,而不影响原始文件。用户配置文件可以安全删除,之后会使用原始的 config.json 文件。
还有一个额外的标签,它提供了每个动画的所有替换项的列表,按优先级排序。这个标签是为了便于检查而设计的,不允许直接编辑,因为一个子模组内的所有替换动画共享相同的配置,而且在这个视图中,同一个子模组内不同动画之间的关系并不清晰。
不要忘记设置菜单。里面有一些实验性特征,虽然不能百分之百确定它们毫无瑕疵,但根据我的经验,它们运行良好。
编辑器会显示一个警告,如果多个子模组共享相同的优先级,并且当一个子模组有一个需要另一个插件或更新版本的条件时,会显示一个错误。你可以通过点击编辑器底部的错误栏来阅读详细信息。
动画日志:
你是否曾想知道刚刚播放的是哪个动画?它来自哪里?我正是为了这个目的添加了动画日志。
通过点击主用户界面内的按钮来启用它。你可以关闭用户界面,在玩游戏时动画日志会留在屏幕上。
你可以在设置菜单中自定义要记录的动画。一些事件,比如用鼠标缓慢转动时的动画重复播放,往往会很频繁地出现。
你可以在设置中也启用将日志记录到 SKSE 日志文件中,如果你之后想分析它的话。
自 2.1.0 版本起,还有一个动画事件日志。这主要对行为模组制作者有用,它会列出在被跟踪参考上发生的所有动画事件。
条件:
DAR 的所有条件都已实现。确保与基于 DAR 的模组完全向后兼容是整个插件开发过程中的一个关键优先事项。某些条件已经合并,有些条件有可以启用的额外功能。有多个新条件可供使用。
所有用于与某物进行比较的数值可以是静态值、对全局变量的引用、角色属性值或行为图变量。
可以通过输入它们的 EditorID 来指定关键字(例如,WeaponKatana)。在多个关键字共享相同 EditorID 的情况下,它们都会匹配。
具有子条件列表(或、与)的条件可以无限嵌套。
请注意,当你在用户界面中将鼠标悬停在条件及其组件上时,它们都有工具提示描述。
自 2.2.0 版本起,有一个名为 PRESETS 的新功能。可以在替换器模组中定义多个预设,然后可以在一个名为 PRESET 的特殊条件中选择它们。
预设是应替换器模组作者的要求添加的,作为一种简化配置创建并减少重复的方法。替换器模组中的子模组经常除了一些差异(比如不同的武器类型)外,完全共享相同的条件。预设正是为了帮助解决这种情况 —— 只需创建一次那个条件块,然后在子模组中重复使用它。
请记住,预设不会被复制到子模组配置中。唯一保存的是预设名称。预设的实际内容保存在替换器模组配置中。
前置及安装:
SKSE
SKSE 插件地址库
如果你不使用跳过动画预加载的实验性设置,需安装动画队列修复补丁。
成对动画改进补丁,以便成对动画内部的注释能正确工作。
使用你选择的模组管理器进行安装。
兼容:
应该与任何非古老版本的《上古卷轴 5:天际》兼容,包括 1.5.97、1.6 + 和 VR 版本。
与动态动画替换器本身不兼容。
与为动态动画替换器创建的任何动画替换器模组完全向后兼容。它可以正常工作。
包含 MergeMapper 支持。
这个模组已经由多人私下测试了相当长一段时间。然而,有可能还是有一些问题遗漏了,特别是因为在开发过程中一些内部结构已经多次重构。在报告任何 bugs 时,请清楚地描述它们,最好能提供重现问题的方法。如果出现崩溃情况,请提供崩溃日志。对于 SKSE 插件来说,崩溃日志实际上非常有用。
常见问题:
传奇版版本?
很抱歉,没有传奇版版本。特别版的引擎要稳定得多,而且像 CommonLibSSE 这样的框架允许更轻松地实现高级插件。真的是时候向前看了。不过,如果你愿意接受挑战,欢迎尝试将这个模组移植到传奇版。我宁愿把时间花在其他事情上,也不想支持这个游戏的一个差得多且在这一点上已经荒谬地过时的版本。
是否与 兼容?
是的。
我能在游戏过程中安装 / 卸载这个吗?
是的。这个插件对游戏没有持久影响,可以随时安装 / 卸载。
设置重置了!
不要删除由插件创建的.ini 文件(如果你使用 Mod Organizer 2,它默认会出现在覆盖文件夹中)。
我觉得这个模组导致我的游戏崩溃了!
请发布一个.NET Script Framework / Crash Logger 崩溃日志。当崩溃确实是由像这样的
下载地址:
**** Hidden Message *****
感谢分享 感谢分享666666 66666666666666
感谢分享!!!
61651616165
666666666666666666666666666666
感谢分享
感谢分享
6666666666666666666666
1331135135135315
66666666666666
牛66666666666666 崩溃日志。当崩溃确实是由像
少时诵诗书所所所所所所 他请问人情味人情味人情味v
666666666666666666
66666666666666666666666666666
ddddddddddd
感谢分享
2222222222222222222
6666666666666
6666666666666666
感谢感谢
5655556656565
666666644444444440000000
和国际化好几个好几个就换个环境
asdfdasdfa
牛66666666666666 same problem. thx