UI 与 ModHub 集成
ModHub
ModHub 是深岩银河目前最广泛使用的 Mod 综合管理终端。我们当然可以制作自己的 Mod 管理终端,但直接用现成的自然更好,也更方便。
前置工作
如果按照之前的步骤在本地部署了 FSD-Template 项目,应该可以在 UE4 中找到以下文件:
这些就是 Modhub 的接口,现在不需要具体了解这些是什么东西,确保它们在这里就可以,待会需要用到。
UI 制作
这里讲的 UI 以制作 mod 设置或自定义页面为基础,实际上如果想制作带特殊 UI 的 Mod 也是类似的方法。
作为简单的例子,我们制作一个可以在 Modhub 中显示的设置 UI 界面,其中包含一个按钮,按下后在聊天栏打印一个字符串。
界面制作
我们就在上一篇教程的工程里追加吧。在 Mod 文件夹下新建一个 Widget 文件夹。所有的 UI 类资产都放在这个文件夹下。这不是必须步骤,但资产归类总归是一个好习惯。
在 Widget 文件夹下新建一个蓝图类资产,类为 Widget Blueprint。名字可以自己取一个,我这里取 _ResupplyMyPerks_SettingsUI。
打开后可以看到一个全新的界面,如下图所示。
中间是预览界面。左侧中部是 UI 的结构。我们需要做的事情非常简单,就是在视图中添加一个按钮。
在左上控件区输入 button ,拖动 button 控件到预览视图中合适的位置。
这个控件的属性会在选中它后显示在右边的属性面板中,可以手动调整。可以在结构区点击,也可以在预览视图中直接选择。
我们稍微修改下这个 button 控件的属性,首先修改它的名字以方便辨认:
名字修改后,左侧结构区里按钮的名字会同步变更。
然后修改下按钮的文本。Button 控件本身不显示文本,我们从左侧控件区搜索并拖入 text 控件到 Button 上。
然后我们选中 text ,修改其文本为 Send Message。
可能发现了,文本超出了 Button 的大小。这可以简单地通过将 button 控件 Size to Context 属性勾选上来解决。
作为一个非常简单的界面,设计制作部分到这就已经完成了。
按钮功能实现
显然,我们的按钮目前没有任何功能,需要给它赋予实际的效果。
点击右上角的 Graph 切换到事件图表。左侧变量表选中按钮,下面 Events 里,点击 On Clicked 右侧绿色加号,新建一个事件。
当按钮被点击(鼠标按下+鼠标释放)时,这个事件会被调用。
现在,如果想让此按钮按下时聊天框发送一串文本,有两种实现方式:
- 直接在 UI 蓝图(就是当前蓝图)实现具体逻辑。
- 运用委托方法,由 UI 蓝图发起委托,由其他 actor 实现具体逻辑。
一般来讲,我们想让每个资产的功能尽量独立以便理解和维护,这里我们就采用第二种办法,这里只发起委托,让我们的 Mod Actor 来实现具体的逻辑。
我们在 Event dispatchers 这里点击 加号,新建一个委托,并将其重命名为 OnButtonSendMessageClicked 。
点击顶上的 Compile 编译保存。然后拖动此委托到事件视图,我们之前新建的事件旁边,选择 Call。
连上执行节点,编译保存。
如果想给委托传参,可以选中委托后,在下面的 Inputs 里添加参数。
ModHub 接口实现:Mod Widget 部分
现在我们实现 ModHub 提供的接口,以便此 UI 可以显示在 ModHub 页面中。点击上部的 Class Settings,在左下 Details 里找到 Interfaces ,Add 一个 IHub Page Widget。
现在我们展开左侧 Interfaces ,双击GetPageInfo,修改这里的 PageName。
ModHub 支持一个 Mod 含有多个标签页,这里的文字就是标签页的标题,如下图圈出位置。
其余内容这个 Mod 不需要修改,我们编译保存就可以了。
ModHub 接口实现:Mod Actor 部分
除了需要展示的 UI 资产本身的操作以外,Mod Actor 这个实际在游戏加载时 Spawn 的对象也需要进行一点操作。打开我们的 Mod Actor (在我这里,也就是 _ResupplyMyPerks_InitBase)。
实例化 UI
找到 EventBeginPlay 事件,断开之前的连接(按住 Alt 单击连线),插入一个 Create widget 节点,将我们的 UI 实例化:
选择 _ResupplyMyPerks_SettingsUI ,并传递给一个变量,将其重命名为 SettingsUI:
然后再连到原有的节点上即可。如果和我的步骤相同,现在看起来像这样:
实现接口
添加 Ihub Mod 接口:(参照 2.3 节的操作,完全类似)
展开 Interfaces,我们实现 Get Mod Info 接口。
这里就是会显示在 ModHub 左侧的 Mod 名称,按照喜好填写即可(图中是错误示范,Mod Name 填写中文可能导致无法显示,请填写英文)。
然后实现 Get Mod Pages 接口,从Hub Pages Array拉出一条线,选择 Make Array 节点:
把我们变量表中的 Settings UI 拉过去即可。
编译保存。到这里我们实现了 UI 界面与 ModHub 的集成,即 Mod 加载时,UI 界面会显示在 ModHub 页面上,但还有件很重要的事情没有完成:UI 功能尚未实现!
实现 UI 功能
在前面,我们实现了 UI 发起委托,但目前尚未有 Actor 来回应这个委托。现在我们就在 Mod Actor 中实现这个委托。
新建一个 Function,命名为 BindUIOperations。
其功能很简单,就是给 UI 中的委托绑定实现它的 Function。参考下图连线:
如果看过上一期教程,这里应该没有问题。我们选择 Create a matching function,并将自动新建的 function 重新命名为 SendMessage。
这个 Function 实现具体的发送消息的功能。参考下图连线即可。如果想知道这些节点都是怎么选出来的,只需要记住这些功能都可以在 FSD.hpp 中找到。
最后,我们让 Mod actor初始化时执行 BindUIOperations 这个 Function 就可以。可以通过在 Event Begin Play 事件中插入这个节点实现。
需要注意的是,因为 BindUIOperations 内有 SettingsUI 的引用,需要确保其在此变量有效后再调用。
最后我们编译保存就可以了。
测试
这部分与上一篇指南是完全一致的,重新打包即可。为了避免错误,建议每次打包时先清空目标目录,删除上次打包的内容。DRG Packer 内同理,先清空 Input 文件夹再执行文件拷贝。最后进游戏测试即可。
因为我们 Mod 目录只有 InitCave 这个 Actor , UI 是不会在太空钻台加载的。我们随便开一个任务,加载进去后按 H 打开 ModHub ,就应该可以看见之前制作的界面:
点击按钮,聊天框应该正确弹出我们设置的消息。
居然是岩神 mod 大佬道明寺樱的博客,太强了
这么偏僻的地方也能找到