kizumi_header_banner_img

不自由であることを誇れるだろうか

文章导读

蓝图开发规范


avatar
Misaya2314 2024年7月26日 9

这个文档重点在于项目的蓝图结构规范,以提升性能,减少耦合,提高代码的可维护性和灵活性。

蓝图父子类

当有明显父子关系的蓝图类,或者是同一种蓝图类但从功能上看有父子关系的时候必须设定子类继承。

由于ue中不能创建抽象类,所以父类可以直接创建一个不带模型的普通蓝图类(不清楚是否有性能优化的方案)

以下为一个示例:

这是一个门的父类蓝图,即项目中所有门的父类,这意味这这个蓝图中的逻辑必须是所有门共有的(除非重载)。示例中是一个简单的开关门逻辑。

当我需要一个创建一个有额外逻辑的门时,例如这个门无法随意打开,则可以创建一个子类蓝图并且编写额外的逻辑。

*创建子类蓝图的方法:

注意不要在类设置里设置父类蓝图

如上图所示,这是门的一个子类蓝图,在继承父类蓝图后重载父类方法后添加了门无法随意开关的逻辑。

例外:如果功能之间的差异不算大的话最好还是设置公开变量实现实例之间的差异,根据实际情况权衡。

蓝图通信

蓝图通信就是比如一个蓝图想要调用另一个蓝图里的事件等等

直接引用

直接引用的方法有castto节点,get actor of class节点等。这些节点都属于强引用,引用后可以获得目标蓝图里的所有信息。但是在某些情况下有性能问题,因此需要谨慎使用。

CAST TO节点

对于cast to节点,仅当目标蓝图是游戏中肯定会加载在内存中,包括实例已经存在于场景中的蓝图类时,可以使用cast to节点。

例如角色蓝图就是在运行后始终在内存中的,当我们在一个蓝图类里需要获得玩家控制器就可以随意cast to。

但是与之相反的是在角色蓝图中尽量不要castto场景里不存在的物体。这会导致这个蓝图无论是否要用到都会一直存在于内存中。

get actor of class节点(禁止)

对于get actor of class节点,当试图与场景中已经存在的蓝图通信时,以下这种做法是错误的。

Get actor of class并不算是一种直接引用,直接引用通常意味着你已经有了该实例的引用,并且可以直接对其进行操作。例如,如果你在蓝图中有一个变量指向某个特定的实例,那么这个变量就是一个直接引用。

Get Actor of Class 则是一种查找并获取实例的方法,它在运行时通过类名查找当前场景中的一个实例并返回其引用。这种方法的特点是:

  1. 每次调用 Get Actor of Class 都会执行查找操作,这可能会有一定的性能开销,尤其是在大场景中。
  2. 如果场景中有多个该类的实例,Get Actor of Class 通常只返回找到的第一个实例,这在某些情况下可能并不是你期望的行为。
  3. 它是动态的,在运行时根据当前场景状态获取实例。

因此get actor of class节点有性能缺陷,禁止在试图与场景中已经存在的蓝图通信时使用。

当我们试图与场景中已经存在的蓝图实例通信时的正确方法如下:

变量引用

开发过程中最常见的情况就是与场景中已经存在的蓝图实例通信,目前已知最性能的方法为变量引用。

假设我需要在当前蓝图中引用场景中的另一个蓝图door_child,首先在当前蓝图新增一个变量,类型为door_child(对象引用),随后设为public

之后就可以调用引用对象里的事件了

最后一步,需要在当前蓝图实例(不是蓝图类)里设置这个引用变量的默认值

如果有必要的话可以进行一次isInvalid的判断,确保引用对象是否可用

这样当前蓝图中只会存储一个引用door_child的指针,达到最高效的性能

创建实例后引用

当与场景里不存在的蓝图通信时,创建实例后引用可能是已知最高效的方法

最后别忘了销毁actor

蓝图接口通信

一般蓝图接口通信用于不同物体面对同一个事件引用时有不同的逻辑。典型例子为物体互动功能。

原先角色蓝图中需要castto所有可互动物体的蓝图,以此调用其内部事件。现在将所有可互动物体的蓝图实现统一的接口BPI_Interaction 2后,可以直接引用接口中签名的统一事件Interact,这样所有实现了该接口的蓝图都可以与角色蓝图通信。

蓝图接口通信也可以用于蓝图于不存在于当前场景下的蓝图通信。需要注意的是,蓝图接口通信难以后续维护管理,使用后要做好注释。另外,因为目标蓝图不存在于场景,事件节点的目标引脚依然需要将目标蓝图实例化后连接。这样做看似和直接引用中的创建实例后引用多此一举,但在某些情况下使用接口可以带来以下好处:

  1. 解耦:接口使得调用方和实现方之间的依赖关系最小化。调用方只需要知道接口,不需要知道具体实现。这种解耦有助于代码的模块化和可维护性。
  2. 灵活性:接口允许不同的类实现相同的方法。你可以在运行时决定使用哪个具体的实现,而不需要修改调用方的代码。这在需要动态更换实现或扩展功能时非常有用。

具体细节看用一个视频彻底说清UE4/UE5中的蓝图通信_(中)_蓝图接口_哔哩哔哩_bilibili

事件分发器

当需要实现一个事件同时引用其他数个蓝图中的事件时,例如当玩家走进触发盒后,灯光关闭,播放bgm等等,就可以使用事件分发器。

相关细节以及具体使用方法:UE甜筒#用一个视频彻底说清UE4/UE5中的蓝图通信_(下)_事件分发器_与蓝图接口的区别_哔哩哔哩_bilibili

蓝图函数库

所有的通用的函数方法(指无需写在类里的、不会引用任何场景里的actor的)写在蓝图函数库中,路径位于content/BP/general_function。

这类似于所有蓝图的一个父类,所有的蓝图都可以直接引用里面的函数。

例如对话功能便已经写成蓝图函数库中的一个方法,它接受两个输入,没有输出,且没有任何对场景actor的引用。

 

感谢您的支持


评论(0)

查看评论列表

暂无评论


发表评论