
这是一份《杀戮空间》自定义角色制作完整指南。 本教程将帮助你创建第一个《杀戮空间》自定义角色。我制作了一些模板来提供帮助,并提供了一些相关程序的教程,还说明了在哪里可以下载制作过程中会用到的部分程序。 我制作这份指南是因为我厌倦了这些信息分散在互联网上的不同网站。如果你需要任何帮助,请留言。 在开始指南之前,我想分享一些小技巧: - 所有文件都以你的角色名称命名。 - 如果你打算发布模组,请尽量减小文件大小。 - 在进行任何绑定工作时都不要放弃。 好了,让我们开始吧!### 前置程序 在开始讲解自定义角色的制作流程前,你需要准备以下几款程序,制作角色时每一款都是必需的。我将分享的所有程序均为免费,但如果你有付费替代软件也可以使用。 所需程序如下: 1. **《杀戮空间》SDK** 用于整合、编译和发布你的模组。该工具随Steam版《杀戮空间》免费提供,可在库中的“工具”选项卡找到。 2. **《杀戮空间》** 3. **建模软件** 用于将模型准备好并导入《杀戮空间》。可选软件包括Blender(免费)和3ds Max(付费)。本指南将使用Blender,并搭配用于导入和导出.psk文件与.ase文件的插件。Blender 在 Steam 上免费提供,其插件可从网络免费获取。 Blender Blender .psk 插件[extensions.blender.org] Blender .ase 插件[extensions.blender.org] 图像编辑程序 你需要一款能够将图片导出为 .dds 格式的图像编辑程序,且需支持 DXT1、DXT3 或 DXT5 压缩设置以及生成 mipmap。有两款不错的免费软件可供选择,它们原生支持 .dds 格式,分别是 PaintDOTnet 和 GIMP。我在 Photoshop 中处理完纹理后,会使用 PaintDOTnet 进行格式转换。现代版本的 Photoshop 不支持 .dds 格式。 PaintDOTnet[www.getpaint.net] (对于 PaintDotNet,你之后可能需要一个插件。基础版 Photoshop 无需插件即可实现相关功能,而 GIMP 的情况我不太清楚。) Halftone 插件[forums.getpaint.net] PDN 插件安装方法[www.getpaint.net] GIMP[www音频编辑器 如果您打算为角色添加非官方语音,就需要一款音频编辑器。我所了解并使用过的只有Audacity,这是一款免费程序。 Audacity[www.audacityteam.org] 文本编辑器/代码程序 制作角色时,您需要文本编辑器或代码程序。如果不想使用代码程序,您可以选择系统默认的记事本(不推荐),或者稍好一些的Notepad++(仍不推荐,但比记事本更好)。如果您想使用代码程序,我强烈推荐免费的Visual Studio Code,并搭配UnrealScript扩展。它虽不完美,存在一些问题,但总体而言比文本编辑器更好。 Visual Studio Code[code.visualstudio.com] VSC UnrealScript扩展[marketplace.visualstudio.com] 记事本++[notepad-plus-plus.org] UE查看器/Umodel:你需要用它提取一个默认玩家模型,以便制作与之相似的自定义模型。该程序可以从虚幻引擎包中提取骨骼网格体。 UE查看器[www.gildor.org] 服务器特权:这是一个用于使用自定义角色的模组。可从Steam创意工坊或其他来源直接安装。之后测试你的模组时需要用到它。 Steam创意工坊 直接下载[gamebanana.com] 第一部分:获取模型 第一步也是最重要的一步,是获取你希望用于《杀戮空间》的模型。 在本指南中,请获取一个已带有骨骼的模型,因为我不会涵盖从零开始为模型绑定骨骼的内容——我也不知道该怎么做。我不会告诉你从哪里获取模型,因为获取模型的途径和方式有很多,但请确保你同时获取了模型和纹理。 获取模型后,打开Blender并删除默认添加的内容(立方体、相机和灯光)。将你的模型导入Blender,并确保模型和骨骼都已导入。如果由于某些原因你找不到带绑定的模型,这里有一份指南希望能帮到你。
本指南中我将以戈登·弗里曼为例进行操作。现在你的Blender中应该已有角色模型及其骨骼。将其保存为类似“Character_Name.blend”的名称,比如我会保存为“Gordon.blend”。

第二部分:获取《杀戮空间》模型 现在你需要做的是从《杀戮空间》中获取模型。为此,请打开UE Viewer。你会看到一个窗口,此时可以忽略其他所有内容,只需点击“浏览文件夹”按钮即可。

下一步是找到你的《杀戮空间》根文件夹并选中它。如果你不知道如何找到该文件夹,可以在库中右键点击《杀戮空间》,然后选择“管理>浏览本地文件”。通常情况下,该文件夹的路径类似于:D: Program Files (x86) Steam steamapps common KillingFloor

选择文件夹后,你会再次看到最后一个窗口,但此时路径已设置完毕。现在只需点击“确定”按钮即可。

将打开一个显示所有包的窗口。选择动画文件夹。然后找到KF_Soldier_Trip.ukx文件并点击打开按钮。

这将打开一个窗口,你可以在其中浏览模型以及模型所使用的纹理。现在你可以选择任何模型(我认为商人除外,她使用不同的比例和骨骼),通过PgUp和PgDn键来滚动浏览模型。我建议使用“British_Soldier1”,因为它的比例正常。然后你需要点击“工具>导出当前对象”。

这将打开一个导出窗口。注意导出路径,以便稍后找到文件。只要将骨骼网格格式设置为ActorX,其他属性均可保留默认值。点击“确定”导出模型。完成后关闭UE Viewer。

第三部分:在 Blender 中合并模型 如果你尚未安装 Blender 的 .psk 插件,请先进行安装。安装过程很简单,只需拖放即可完成。

之后导入你从《杀戮空间》导出的.psk文件

导入《杀戮空间》模型后,你可能会注意到模型存在细微的比例差异,而在我遇到的情况中,这种比例差异非常巨大。此外,在某些情况下,自定义模型的旋转方向也会有所不同。

这是一个简单的修复方法:你需要选择自定义模型及其骨骼,然后输入“S”。这将进入缩放模式,你可以移动鼠标,将模型缩放到与《杀戮空间》角色相同的大小。修复旋转问题最简单的方法是点击窗口右上角相机旋转控制中的正Z轴。之后只需输入“R”,这会进入旋转模式,你可以输入旋转的度数,大多数情况下需要向右旋转,比如90度或180度。如果旋转方向错误,输入“-”可将数值从正数改为负数。

保存文件 现在需要让姿势匹配!首先,你需要进入姿势模式。点击自定义模型(注意:不是KF模型)的骨骼,然后在左上角点击“物体模式”,会出现一个下拉菜单,从中选择“姿势模式”。 进入姿势模式后,你可以点击骨骼进行旋转和移动,尽可能让你的模型与KF模型匹配(注意不要过度变形模型!)。手指部分可能比较棘手,但只要调整得看起来足够好就没问题。 在右侧的场景浏览器中,你可以根据需要隐藏或显示任意一个模型。

经过一番努力……

太……太神奇了…… 存档文件 现在到了最繁琐的部分…… 接下来要开始合并骨骼了,这肯定很麻烦。第一步是匹配顶点组名称,并创建所有不存在的顶点组。 开始此流程前 建议在开始此流程前先备份存档,以防操作失误导致无法恢复,避免大量返工。 首先,你需要将模型应用当前姿势,这样在修改顶点组名称时模型才不会丢失姿势。在对象模式下,点击你的网格模型,然后进入修改器面板。你应该能看到一个“骨架”修改器。点击下拉箭头并按“应用”。接着选择自定义模型的骨骼并删除它们。此时模型的大小和旋转会重置,但如果你重新调整大小和旋转,模型应该会回到你设置的姿势。

选择两个网格体。进入编辑模式。在右侧面板中找到“数据”选项卡,选择你想要查看顶点组的模型。你将看到顶点组,点击“选择”即可查看该组对应的模型部分。我建议在此步骤中使用线框视图,这会让操作过程更加轻松。基本上,你需要将自定义模型上骨骼部分的顶点组名称与官方模型的顶点组名称进行匹配。顶点组的顺序无关紧要,你可以根据需要添加或删除组,但要注意此操作无法撤销。

为了让你的自定义模型正常运行,你需要用到所有这些顶点组!CHR_骨盆 CHR_脊椎1 CHR_脊椎2 CHR_脊椎3(此项留空,改用CHR_胸腔) CHR_胸腔 CHR_左臂锁骨 CHR_左臂上臂 CHR_左臂前臂 CHR_左臂手掌 CHR_左臂手指1-1 CHR_左臂手指1-2 CHR_左臂手指1-3 CHR_左臂手指2-1 CHR_左臂手指2-2 CHR_左臂手指2-3 CHR_左臂手指3-1 CHR_左臂手指3-2 CHR_左臂手指3-3 CHR_左臂手指4-1 CHR_左臂手指4-2 CHR_左臂手指4-3 CHR_左臂手指5-1 CHR_左臂手指5-2 CHR_左臂手指5-3 CHR_右臂锁骨 CHR_右臂上臂 CHR_右臂前臂 CHR_右臂手掌 CHR_右臂手指1-1 CHR_右臂手指1-2 CHR_右臂手指1-3 CHR_右臂手指2-1 CHR_右臂手指2-2 CHR_右臂手指2-3 CHR_右臂手指3-1 CHR_右臂手指3-2 CHR_右臂手指3-3 CHR_右臂手指4-1 CHR_右臂手指4-2 CHR_右臂手指4-3 CHR_右臂手指5-1 CHR_右臂手指5-2 CHR_右臂手指5-3 CHR_颈部 CHR_头部 CHR_左大腿 CHR_左小腿 CHR_左脚踝 CHR_左脚趾1 CHR_右大腿 CHR_右小腿 CHR_右脚踝完成所有操作后,你需要删除官方网格体,保留骨骼,它们应该会与你的自定义模型对齐。

现在你需要在物体模式下选择网格和骨骼,其中骨骼是主要目标(黄色轮廓)。然后右键点击,进入父级设置并选择自动权重。

现在你的角色和骨骼已经关联,但工作还未完成。如果你在骨骼上使用姿态模式,可能会发现一些错误。接下来是我所说的“网格清理”流程。你需要调整模型的权重,并将材质数量尽可能减少。现在请继续跟随我的步骤,最困难和最繁琐的部分已经完成了。从这里开始,大部分操作都会变得更加简单! ### 第四部分:网格清理 现在,如果你在某些使用自动权重的模型上调整骨骼姿态,可能会发现结果混乱得难以理解。

别担心,我们可以解决这个问题!这是由权重导致的,要修复它,我们需要使用“权重绘制”这一高级技巧。说实话,一旦你掌握了窍门,其实也没那么难。首先,为了安全起见,请再次保存你的模型。然后,选择模型本身,在模式选择下选择“权重绘制”。

你的模型会变成蓝色,并且模型某处可能会出现红色/黄色高亮。这表示所选骨骼对网格该部分的影响程度。深蓝色=无影响,亮红色=100%影响。你所选的顶点组与某根骨骼相关联。

如果我的解释不够清晰,我深表歉意,这个视频或许能帮助你更好地理解: 基本上,你需要确保每个组都与相邻的组共享一定的影响力,以确保不会出现间隙,同时还要注意调整,使移动骨骼时看起来不会过于生硬。 有些模型可能针对同一纹理设有多个材质槽。为了方便操作,你应该尝试将它们合并为一个材质槽。在编辑模式下,你可以选择所有受材质影响的部分,然后将其分配给一个新的材质槽,从而合并那些无需分开的材质。

现在你的模型已经清理完毕,但权重可能仍然不正常,查看这一点的最佳方法是在游戏中查看模型,因此现在我们将开始将角色添加到《杀戮空间》的流程。 ### 第5部分:将模型导入KF SDK 现在我们将把你的模型导入《杀戮空间》SDK。第一步是在Blender中选择你的模型,然后依次点击“文件>导出>.psk”,将其导出到某个位置,并将其命名为类似“Charactername.psk”的名称。

现在打开KF SDK。 你可以通过复制官方的KF_Soldier_Trip,删除除一个之外的所有网格物体以及非玩家动画集,自行制作动画包。或者,为节省时间,我已创建了一个模板。 在此处下载我制作的模板。
将该包添加至KillingFloor/Animations文件夹,并将文件名中的“Charactername”替换为你的角色名称。

在SDK动画浏览器中打开文件。


导入你的网格模型

从“British_Soldier_Mike”复制网格属性并粘贴到你的网格上。


将你的网格体链接到Soldier_Animations_Trip动画集,方法是将DefaultAnimation设置为MeshAnimation'KF_Soldier_Trip.Soldier_Animations_Trip'。

你可以现在就删除British_Soldier_Mike,或者等到权重调整100%完成后再删除,因为每次重新导入时,你都必须重新链接动画并复制属性。另外请注意,由于虚幻引擎2在骨骼网格导入方面存在一个bug,所以每次重新导入以更改权重时,你都需要保存包并关闭KF SDK,然后重新打开。 现在你在播放动画时可以看到你的网格体,但使用默认纹理可能很难分辨。你可以就这样查看动画,或者先获取纹理,这样更容易分辨。

第六部分:获取纹理 现在我们来处理纹理,和模型一样,纹理的获取需要你自己完成。获取纹理后,请打开你的图像编辑软件。本教程中我使用的是PaintDotNet。对于所有纹理,如果其分辨率超过1024x1024像素,建议将其缩小至该尺寸,因为超过这个分辨率只会给你的模组增加不必要的空间。完成后,将图像保存为.dds格式文件。



现在来设置导出参数,你需要修改两项内容。 压缩选项需根据纹理类型决定: - 若纹理无Alpha通道且仅用于显示颜色,选择DXT1。 - 若计划为遮罩纹理使用Alpha通道,选择DXT3。 - 若希望为高光贴图等内容使用细节丰富的Alpha通道,选择DXT5。 此外,你还需要启用“生成Mip Maps”功能。

你的纹理现已准备好导入KF SDK! 第7部分:导入纹理与制作材质 前往KF SDK中的纹理浏览器

现在前往“文件”>“导入”并选择你的纹理。在导入窗口中,使用“包”字段为你的包命名。我建议使用类似“角色名_纹理”的命名方式,但具体由你决定。然后点击“确定”即可。

导入后会自动选择你的包。通过“文件>保存”来保存你的包。现在你可以直接使用这些普通纹理,或者如果你愿意,也可以对它们进行一些着色器/材质方面的处理。我不会教你材质编辑器,但这里有UnrealEd 2材质编辑器的官方文档,你可以查看一下。 官方文档[docs.unrealengine.com] 不过,关于属性设置,我有一些建议: 我喜欢将它们设置为双面,这样即使存在接缝,也能在一定程度上隐藏起来。(这只有在你制作着色器的情况下才有效。) 我还喜欢将LODSET设置为PlayerSkin。 如果纹理是盔甲的,我会让表面类型与之匹配。额外选项:如果你希望使用法线贴图(尽管虚幻引擎2原生不支持),可以将法线贴图转换为灰度图,这样能制作出不错的细节贴图,为纹理增加更多深度。只需记住在导入时设置“细节贴图破解”标记。 纹理准备完成后,即可将其分配给模型。 第八部分:分配材质 首先,在纹理浏览器中选择你要使用的纹理。选中的纹理会以绿色高亮显示。

现在前往动画浏览器。选择你的网格体。在属性面板中选择“网格体>蒙皮>材质”。点击一个材质槽,然后按下“使用”按钮。对所有材质槽重复此操作。

在开始设置模组前,还有最后一件必须完成的事! 第九部分:制作肖像 现在我们需要再次使用建模软件来制作角色肖像。为此,我已创建了一个模板,供你添加自己的角色。 如果你没有Blender,这是一个基础的Blender设置说明:只需将相机对准角色,设置为256x512的分辨率,在角色左前方放置一盏略微泛白的强红光,在角色左后方放置一盏强白光。 Blender模板[drive.google.com] 使用方法很简单:将你的角色模型添加到场景中,调整其大小以匹配已有的模型,然后删除我的网格。在材质选项卡中设置材质。如果你不知道如何操作,这里有一个教程。 Blender基础材质教程[all3dp.现在只需前往“渲染”>“渲染图像”。

一秒后,带有光照效果的模型图片应该会显示出来。如果你满意这个效果,可以保存该图片。

现在我们将对这张图片进行风格化处理,使其更贴合默认图片的风格。 第10部分:人像风格化与导入 在这一步,请打开你的图像编辑软件。如果你有Photoshop,建议按照官方资料中的步骤进行风格化处理,因为这是最简便的操作平台。 官方人物纹理创建页面[wiki.tripwireinteractive.com] 接下来我将展示如何在PaintDotNet中进行操作。你需要准备工作中提到的插件。在PaintDotNet中打开你的渲染图,依次点击“调整”>“黑白”。然后点击“效果”>“风格化”>“TR半色调”。此时会弹出一个窗口,保持所有默认设置,但需反转点与背景颜色,调整后效果应大致如下。

将此另存为单独的图片。在另一个文件中打开你的原始渲染图,并将刚才制作的黑白图片作为图层添加到其上方。将图层属性设置为40%不透明度和正片叠底混合模式,你应该会得到类似这样的效果。

将其保存为 DXT1 格式的 .dds 文件,并导入至 KF SDK。在属性中为其指定 LODSET_Interface。 现在让我们来设置这个模组文件。 第 11 部分:制作模组包与角色文件 首先,我们要制作模组包。为此,你需要进入《杀戮空间》的根目录,创建一个用于存放角色模组的文件夹。对于角色模组而言,该文件夹的命名必须与游戏中角色的名称完全一致,并在末尾加上“Mod”。例如,我的文件夹命名为 GordonfreemanMod。名称中的“Mod”部分至关重要,若缺少此部分,模组将无法正常运行。在该文件夹内,创建一个名为“Classes”的文件夹。
现在打开你的代码或文本编辑器。如果你安装了Visual Studio Code,请确保已安装相关扩展,然后依次点击“文件>打开文件夹”,并选择《杀戮空间》的根目录。如果弹出提示,请信任该文件夹。进入你创建的“classes”文件夹,新建一个名为“Charactername.uc”的文件。我会创建“GordonFreeman.uc”。 粘贴以下内容并根据需要进行修改。注释会告诉你每一行需要做什么。暂时保持“Species”和“VoiceClass”不变。 如果你使用的是Visual Studio Code,可能会注意到引用包的行下方有红线,你可以忽略这些。 带下划线的内容将被替换 class Charactername extends PlayerRecordClass; //将“character name”替换为你的.uc文件名。 #exec obj load file="Charactername_Soldier_Trip."ukx" // 使用这些行加载所有所需的动画或纹理文件。使用你的包的文件名并包含扩展名 #exec obj load file="Charactername_Textures.utx" simulated static function xUtil.PlayerRecord FillPlayerRecord() { local xUtil.PlayerRecord PRE; PRE.Species = Class'PoliceSpecies'; // 物种,暂时忽略。 PRE.MeshName = string(Mesh'Meshnamehere'); // 动画包中的网格名称。 PRE.BodySkinName = string(TextureType'TexturePackage.TextureName'); // 身体皮肤名称 材质 #0 可直接从动画浏览器复制。 PRE.FaceSkinName = string(TextureType'TexturePackage.TextureName'); // 面部皮肤名称 材质 #1 可直接从动画浏览器复制。 PRE.Portrait = Texture'Charactername_Textures.PortraitTexture'; // 肖像纹理 PRE.TextName = "此处为描述文本"; // 描述文本。 PRE.VoiceClassName = string(Class'KFMod.KFVoicePackTwo'); // 语音包暂不处理 PRE.Sex = "M"; // M = 男性,F = 女性 PRE.Menu = "SP"; // 无需修改。 PRE.Skeleton = string(Mesh'British_Soldier1'); // 在KF中未使用 PRE.Ragdoll = "British_Soldier1"; // 应仅为此值。 return PRE; } 修改后的代码应大致如下。

Now you could go on to compiling your mod and publishing it if you wanted. But if you want to change more stuff (Voice lines, pain sounds, view arms, gibs) I will show each of these. But if you wish to just compile now go on to Part 16. Part 12-1: Making Other UnrealScript Files There are 5 more files you will need to make for the rest of the stuff you can make. We will start with making these and modifying the templates as we can so far. When you make these reference the ones that they require in each other through the files. Go back and do it for main file too. Species class CharacternameSpecies extends SoldierSpecies; //make class name your characters name followed by species. defaultproperties { SleeveTexture=Texture'KF_Weapons_Trip_T.hands.hands_1stP_riot_D' //This will be view model arm texture we will go over this later DetachedArmClass = class'SeveredArmPolice' //make this the name of your arm gib class when you make it DetachedLegClass = class'SeveredLegPolice' //make this the name of your leg gib class when you make it MaleVoice="CharacternameMod.CharacternameVoicePack" //make this of the name of your voice pack when you make it MaleSoundGroup="CharacternameMod.CharacternameSoundGroup" //make this of the name of your sound group when you make it } VoicePack class CharacternameVoicePack extends KFVoicePack; //Replace Character name. Ignore rest of file for now. defaultproperties { SupportSound(0)=Sound'' //Medic SupportSound(1)=Sound'' //Help SupportSound(2)=Sound'' //NeedMoney SupportSound(3)=Sound'' //DropWeapon AcknowledgmentSound(0)=Sound'' //Yes AcknowledgmentSound(1)=Sound'' //No AcknowledgmentSound(2)=Sound'' //Thanks AcknowledgmentSound(3)=Sound'' //Sorry AlertSound(0)=Sound'' //LookOut AlertSound(1)=Sound'' //Run AlertSound(2)=Sound'' //WaitForMe AlertSound(3)=Sound''//WeldTheDoors AlertSound(4)=Sound'' //HoleUp AlertSound(5)=Sound''//FollowMe DirectionSound(0)=Sound'' //GetToTheTrader DirectionSound(1)=Sound'' //GoUpstairs DirectionSound(2)=Sound'' //HeadDownstairs DirectionSound(3)=Sound'' //GetInside DirectionSound(4)=Sound'' //GoOutside InsultSound(0)=Sound'' //InsultSpecimen InsultSound(1)=Sound'' //InsultPlayers AutomaticSound(0)=Sound'' //AutoWelding AutomaticSound(1)=Sound'' //AutoUnwelding AutomaticSound(2)=Sound'' //AutoReloading AutomaticSound(3)=Sound'' //AutoNoAmmo AutomaticSound(4)=Sound'' //AutoDropCash AutomaticSound(5)=Sound'' //AutoHealing AutomaticSound(6)=Sound'' //AutoDying AutomaticSound(7)=Sound'' //AutoFunBloatPuking AutomaticSound(8)=Sound'' //AutoFunPatriarchInvis AutomaticSound(9)=Sound'' //AutoFunPatriachChainGun AutomaticSound(10)=Sound'' //AutoFunPatriarchRockets AutomaticSound(11)=Sound'' //AutoFunGrabbedByClot AutomaticSound(12)=Sound'' //AutoFunSpotFP AutomaticSound(13)=Sound'' //AutoFunSpotGore AutomaticSound(14)=Sound'' //AutoFunSpotScrake AutomaticSound(15)=Sound'' //AutoFunSpotSiren AutomaticSound(16)=Sound'' //AutoFunSirenScreaming AutomaticSound(17)=Sound'' //AutoFunStalkerSpotted AutomaticSound(18)=Sound'' //AutoFunCrawlerSpottd AutomaticSound(19)=Sound'' //AutoFunKilledStalkerwithMelee AutomaticSound(20)=Sound'' //AutoFunZedBurned AutomaticSound(21)=Sound'' //AutoFunSelectDBshotgun AutomaticSound(22)=Sound'' //AutoFunSelectDualHandcannons AutomaticSound(23)=Sound'' //AutoFunSelectLAW AutomaticSound(24)=Sound''//AutoFunSelectAxe } Sound Group class CharacternameSoundGroup extends KFMaleSoundGroup; //Replace with your characters name. Ignore rest of file for now. defaultproperties { BreathingSound=Sound'KFPlayerSound.Malebreath' //Doesnt Always Replace //DeathSounds DeathSounds(0)=Sound'' DeathSounds(1)=Sound'' DeathSounds(2)=Sound'' DeathSounds(3)=Sound'' DeathSounds(4)=Sound'' //PainSounds PainSounds(0)=Sound'' PainSounds(1)=Sound'' PainSounds(2)=Sound'' PainSounds(3)=Sound'' PainSounds(4)=Sound'' PainSounds(5)=Sound'' } Arm Gib class SeveredArmCharacterName extends SeveredArm; //Replace character name ignore everything else for now. defaultproperties { StaticMesh=StaticMesh'kf_gore_trip_sm.limbs.british_riot_police_arm_resource' } Leg Gib class SeveredLegCharacterName extends SeveredLeg; //Replace character name ignore everything else for now. defaultproperties { StaticMesh=StaticMesh'kf_gore_trip_sm.limbs.british_riot_police_leg_resource' } Part 12-2: Making Other UnrealScript Files You should now have 6 .uc files and have them referencing each other. Here are all of my files right now.
class GordonFreeman extends PlayerRecordClass; #exec obj load file="Gordon_Soldier_Trip.ukx" // Load up all needed animations or texture files using these lines. #exec obj load file="Gordon_Textures.utx" simulated static function xUtil.PlayerRecord FillPlayerRecord() { local xUtil.PlayerRecord PRE; PRE.Species = Class'GordonfreemanMod.GordonFreemanSpecies'; // Species (can be used to replace sounds or misc stuff) PRE.MeshName = string(Mesh'Gordon'); // Name of the mesh. PRE.BodySkinName = string(Shader'Gordon_Textures.SkeletalMesh.GordonBodyMat'); // Body skin name (Material #0) PRE.FaceSkinName = string(Shader'Gordon_Textures.SkeletalMesh.GordonFaceMat'); // Face skin name (Material #1) PRE.Portrait = Texture'Gordon_Textures.Portrait.Gordon_Portrait'; // Portrait texture PRE.TextName = "A native of Seattle, Washington, Freeman is a 27 year old theoretical physicist. That isnt his only talent though, in dire situations such as resonance cascades, alien empire takeovers and zed outbreaks he can help in a not so scientific, but more ballistic way. He also has a natural leader energy to him and can help lead people to victory."; // Description text. PRE.VoiceClassName = string(Class'GordonfreemanMod.GordonFreemanVoicePack'); // Voice pack PRE.Sex = "M"; // M = Male, F = Female PRE.Menu = "SP"; // Not needed to modify. PRE.Skeleton = string(Mesh'British_Soldier1'); // Unused in KF PRE.Ragdoll = "British_Soldier1"; // Should be this only. return PRE; } class GordonFreemanSoundGroup extends KFMaleSoundGroup; defaultproperties { BreathingSound=Sound'KFPlayerSound.Malebreath' //Doesnt Always Replace //DeathSounds DeathSounds(0)=Sound'' DeathSounds(1)=Sound'' DeathSounds(2)=Sound'' DeathSounds(3)=Sound'' DeathSounds(4)=Sound'' //PainSounds PainSounds(0)=Sound'' PainSounds(1)=Sound'' PainSounds(2)=Sound'' PainSounds(3)=Sound'' PainSounds(4)=Sound'' PainSounds(5)=Sound'' } class GordonFreemanSpecies extends SoldierSpecies; defaultproperties { SleeveTexture=Texture'KF_Weapons_Trip_T.hands.hands_1stP_riot_D' DetachedArmClass = class'SeveredArmPolice' DetachedLegClass = class'SeveredLegPolice' MaleVoice="GordonfreemanMod.GordonFreemanVoicePack" MaleSoundGroup="GordonfreemanMod.GordonFreemanSoundGroup" } class GordonFreemanVoicePack extends KFVoicePack; defaultproperties { SupportSound(0)=Sound'' //Medic SupportSound(1)=Sound'' //Help SupportSound(2)=Sound'' //NeedMoney SupportSound(3)=Sound'' //DropWeapon AcknowledgmentSound(0)=Sound'' //Yes AcknowledgmentSound(1)=Sound'' //No AcknowledgmentSound(2)=Sound'' //Thanks AcknowledgmentSound(3)=Sound'' //Sorry AlertSound(0)=Sound'' //LookOut AlertSound(1)=Sound'' //Run AlertSound(2)=Sound'' //WaitForMe AlertSound(3)=Sound''//WeldTheDoors AlertSound(4)=Sound'' //HoleUp AlertSound(5)=Sound''//FollowMe DirectionSound(0)=Sound'' //GetToTheTrader DirectionSound(1)=Sound'' //GoUpstairs DirectionSound(2)=Sound'' //HeadDownstairs DirectionSound(3)=Sound'' //GetInside DirectionSound(4)=Sound'' //GoOutside InsultSound(0)=Sound'' //InsultSpecimen InsultSound(1)=Sound'' //InsultPlayers AutomaticSound(0)=Sound'' //AutoWelding AutomaticSound(1)=Sound'' //AutoUnwelding AutomaticSound(2)=Sound'' //AutoReloading AutomaticSound(3)=Sound'' //AutoNoAmmo AutomaticSound(4)=Sound'' //AutoDropCash AutomaticSound(5)=Sound'' //AutoHealing AutomaticSound(6)=Sound'' //AutoDying AutomaticSound(7)=Sound'' //AutoFunBloatPuking AutomaticSound(8)=Sound'' //AutoFunPatriarchInvis AutomaticSound(9)=Sound'' //AutoFunPatriachChainGun AutomaticSound(10)=Sound'' //AutoFunPatriarchRockets ... goes on not enough space on the section. class SeveredArmGordon extends SeveredArm; //Replace character name ignore everything else for now. defaultproperties { StaticMesh=StaticMesh'kf_gore_trip_sm.limbs.british_riot_police_arm_resource' } class SeveredLegGordon extends SeveredLeg; //Replace character name ignore everything else for now. defaultproperties { StaticMesh=StaticMesh'kf_gore_trip_sm.limbs.british_riot_police_leg_resource' } Now that you have all of your other .uc files lets start on making this other content for your character. Part 13: Making Hand Textures Unlike everything else so far you cant simply port something from another game for the hand texture. All hand models are attached to weapon animations so the hand textures are a specific UV map that you either have to draw on/edit or just find another default one that lines up well enough for your characters. All arm textures are in the various texture packages for weapons. There is sort of a template inside of KF_Weapons_Trip_T. You can export the texture from the editor.

当你制作或选择纹理时,将其添加到你的纹理包中,并在“物种文件”里将其添加至“SleeveTexture”。它可以是任何类型的材质,只需确保在引用前填写正确的类型即可。 这些纹理很难做到美观,所以如果你只想使用默认纹理,这是可以理解的。

第14部分:添加自定义音效 你将负责音频素材的获取。语音台词以及受伤和死亡音效的处理流程大致相同。语音台词需放在语音包.uc文件中,而受伤和死亡音效则存放在声音组.uc文件里。开始准备音频时,先将其导入Audacity。 需要注意的是,该游戏的音频混音效果非常差!为了让语音清晰可闻,音频几乎需要一直处于峰值状态,这可能导致音量不均衡的语音台词难以平衡。但也不能过度削波,否则听起来会很糟糕。这就是默认语音台词的效果。

我主要就是调整“Amplify”效果,你可以在这里找到它,这部分步骤我就留给你了。

同时,修剪开头和结尾的所有空白区域以节省文件大小。 将音频设为单声道,如果已经是单声道则无需操作,否则执行“轨道>将立体声混缩为单声道”。 完成上述操作并准备导出时,点击“文件>导出音频”,将文件命名为便于你记住对应台词的名称,并选择WAV(Microsoft)格式。我使用的是单声道、22050 Hz采样率以及无符号8位PCM编码,然后进行导出。

当你准备好所有音频后,打开KF SDK。 你需要打开声音浏览器,然后执行“文件>导入”操作。

选择您拥有的任意文件并打开,这将打开导入窗口。

为你的角色语音/音效创建一个包。例如可以命名为“角色名Audio”或“角色名Voice”。对于分组,这是为了便于组织,我强烈建议将其用于语音文件,文件名保持不变即可。 点击确定后,它应该会出现在声音浏览器中。如果导入失败,请确保文件路径中没有空格,引擎在这方面可能比较挑剔。 当你准备好所有文件后,需要为你的语音创建声音组。每个语音都需要一个声音组。操作步骤:依次点击“文件>新建声音组”,并为其命名以明确其用途。这些声音组会显示在列表顶部,名称旁带有 * 标记。右键点击它,然后打开属性。你只需关注声音列表,为每个语音添加对应数量的条目,方法是选择声音文件并在列表上点击“使用”。 完成所有声音添加后,最后一步是将它们分配到你的语音包或声音组中。你只需在代码中放入声音组的引用,格式为Sound'refgoeshere'。 这是我完成后的语音类。

音频现在应该正常了。 第十五部分:制作碎块 我要介绍的最后一个可选内容是自定义碎块,制作起来非常简单。首先打开UE Viewer,按照之前的步骤打开《杀戮空间》文件夹。这次你需要打开静态网格物体文件夹,然后打开kf_gore_trip_sm。

为任意DLC/成就角色寻找手臂或腿部碎块模型。它们将更容易作为基础使用,因为它们使用多种材质。 我将使用这个模型。

按Ctrl-X导出。 现在在Blender中打开此模型,并导入你的角色模型。

删除角色的骨骼,仅保留基础模型。 现在选择你导出的碎块模型,进入编辑模式并选中模型的所有顶点。右键点击,选择“分离”>“按材质分离”。

这将把腿部拆分为两个网格体:腿部和血液。删除腿部网格体,只保留血液网格体。现在,你需要进入角色的编辑模式,删除除一条手臂或一条腿之外的所有部分。 按C键可以进入编辑模式的画笔工具,右键点击可退出该模式。 完成上述操作后,你可以调整肢体姿势,使其嵌入到碎块模型中,最终效果应该类似这样。

如果腿部有多个材质槽,请选择腿部,确保仅使用身体部位正在使用的材质。然后选择两个模型并按Ctrl-J将它们合并。 现在将此模型导出为ASE文件,其扩展名已在上方链接中提供。 对接下来需要处理的手臂或腿部重复上述步骤。 导出完成后,打开KF SDK。 打开静态网格浏览器,执行“文件>导入”操作,找到你的模型。

在创建包的导入菜单中,为你的角色新建一个包。名称可以类似“角色名Statics”。分组保持空白。命名保持类似“角色名arm”“角色名leg”等即可。 现在我们只需处理模型下方窗口中的材质属性。你可能运气好,碎块部分的材质会自行导入,但如果没有,请将其设为Texture'kf_fx_trip_t.Gore.KF_Gore_Limbs_diff',并将另一个槽位设为你的角色材质。 你应该会得到类似这样的结果。

下一步你需要为代码添加引用。 每个Gib类都将有一个静态网格引用,只需用该网格的路径填写即可。例如,这是我现在的手臂Gib类: class SeveredArmGordon extends SeveredArm; //替换角色名称,暂时忽略其他所有内容。 defaultproperties { StaticMesh=StaticMesh'GordonFreemanStatics.GordonArm' } 这就是Gibs所需的全部内容。 第16部分:编译角色 为此,第一步我们需要编辑位于KillingFloor/System目录下的KillingFloor.ini文件。只需用文本编辑器打开它,并在[Editor.EditorEngine]部分找到所有EditPackages=行。这些行用于处理编辑器(以及编译器)可以访问哪些.u包。添加一行EditPackages=YourPackageName。因此,我需要设置EditPackages=GordonFreemanMod。 需要注意的重要事项是,完成模组编译后,请记得从.ini文件中删除这一行。如果在卸载游戏模组时,这一行仍留在.ini文件中,将会导致编辑器无法打开。 接下来,我们要创建一个.bat文件来运行编译器。操作方法是:新建一个文本文件,将扩展名从.txt改为.bat。将其命名为类似ucc.bat的名称,并放置在KillingFloor/System文件夹中。如果未将其放在System文件夹内,程序将无法正常运行。 在.bat文件中粘贴以下内容: ucc make ::运行UCC程序以编译脚本 pause ::暂停以便查看编译是否成功 del steam_appid.删除一个自动生成并阻止在线游玩的文件。完成这两项操作后,你应该可以直接运行.bat文件(就像双击.exe文件一样)。运行程序时会打开一个命令提示符窗口,窗口中会开始列出如下内容: ----------------------------Core - Release---------------------------- ---------------------------Engine - Release--------------------------- ----------------------------Fire - Release---------------------------- ---------------------------Editor - Release--------------------------- --------------------------UnrealEd - Release-------------------------- 这是程序在检查所有编辑包。对于默认包,它应该只会显示“Release”,因为程序不会重新编译仍位于系统文件夹中的包。之后,程序最终会开始编译你的角色。请留意窗口,查看是否编译失败。如果失败,窗口会显示错误信息,你也可以打开ucc文件查看。末尾的日志会提供更详细的分类信息,其中会显示编译失败的.uc文件以及具体行数,因此排查起来相当直观。 如果编译成功,你会得到一个ModPackageName.u文件,以我为例则是GordonFreemanMod.u。 若你修改了代码并希望重新编译,只需确保删除旧的.u文件,然后重新按照这些步骤操作即可。 如果你想了解更多关于编译的信息,可以访问以下链接。该维基页面的文本格式有些混乱,但你可以全选(Ctrl+A)并复制粘贴(Ctrl+C、Ctrl+V)到文本文件中阅读:BeyondUnreal Wiki[wiki.beyondunreal.com] 接下来我将向你展示如何测试此模组。 第17部分:测试 现在你已经完成编译,让我们进行测试。此时你需要服务器特权(Server Perks)。如果你已安装该组件,应该会有一个名为ServerPerks的文件。在你的《杀戮空间》/System文件夹中找到该ini文件。如果没有,可能是ServerPerksDefault.ini,你可以将其重命名为ServerPerks.ini。打开此ini文件,在末尾添加一行:CustomCharacters=角色名Mod.角色名。例如,我的设置是CustomCharacters=GordonFreemanMod.GordonFreeman。 现在打开《杀戮空间》,进入单人游戏或主机菜单,前往“变异器”选项卡,选择“服务器 veterency 处理程序”并启用它。启动游戏后,你的角色应该会出现在角色列表中。

如果无法运行,请检查.ini文件的拼写。 现在,如果你已经成功运行并对此感到满意,那就开始发布这个模组吧。 第十八部分:发布 我不会讨论创意工坊上传的内容,Holy Username Batman撰写的这份指南对创意工坊上传有很好的说明: https://steamcommunity.com/sharedfiles/filedetails/?id=2115290403 不过,我会提供一些提示: 1. 提供一个直接下载的替代方案(我使用GameBanana,但也有其他选择,如ModDB、Gamemaps、Google Drive、Dropbox等)。 2. 说明需要添加到ServerPerks.ini中的内容,例如在某处添加“CustomCharacters=GordonFreemanMod.GordonFreeman”。 3. 列出下载内容中包含的所有文件。 4. 确保在下载包中打包你为模组创建的所有包。例如,这是我的模组的创意工坊页面: https://steamcommunity.com/sharedfiles/filedetails/?id=3475684066 总结 创建角色可能既繁琐又有趣,如果你有任何问题,随时可以提问!
2026-02-14 07:00:11 发布在
Killing Floor
说点好听的...
收藏
0
0
