游戏引擎开发总结:节点编辑器实现思路

这个思路是我直接想出来的,可能并不是主流的框架;

首先,我们先要设定几个原则,这样才能不让自己的思维天马行空

1:节点的输出口的输入是一个函数指针,用std::function封装

2:节点之间的数据交流只能是通过函数指针,节点不应该感知到link对面节点的存在


节点口的种类

1:输入节点口,接收数据的节点

2:输出节点口,输出数据的节点

大部分节点既有输入节点口也是输出节点口,区别的方法是连接线的时候,哪个节点是输入数据的节点,哪个是输出数据的节点,输出节点口的节点为输出节点,相反是输入节点


首先,我们可以确定节点的一些公共函数:

1:第一个很显然是OnUpData函数

2:第二个是OnLink函数,这个函数是在当链接了一条线的时候通知输入节点,但不通知输出节点


然后就是怎么判断输出节点口和输入节点口的的数据类型是否相同

这个我刚开始的思路是用模板来解决,但考虑到序列化和复杂度以及debug的难度,我放弃了,转而选择用string去存储类型信息,这个时候,有了以下几个好处

1:拥有运行时改变接口返回类型的能力

2:函数指针本身的类型变得无关紧要[我们可以根据判断字符串来安全地进行static_cast]

那么一个输出口的定义就如下了

struct FunSign{
    void* ptr;
    std::vector<std::string> sign;
}

大概的约定有了,那么接下来就一些设计上的问题了

这边我用的是ecs系统,用标识的方法来对节点进行不同操作,这样就不用更新的时候将所有的节点都遍历一遍了,而且这种组件的思维也有助于降低程序的复杂度

那么就来谈不同的操作怎么实现了:

节点定义

所有节点都继承至一个类Access,所有的节点都没BP_Node持有,节点相对于BP_Node称之为define。

Access定义了一些必要的虚函数,,BP_Node是一个适配器,将具体节点与编辑程序隔离开,让编辑程序以统一的方式对待所有节点;

创建节点

我选择的第三方库是ImGuiNodeEditor,ecs用的是entt库

这个的话,先创建一个实体,然后获得的enttityid作为节点的NodeID,将其作为key键,BP_Node*作为value,这样的话我们就能拥有enttity->BP_Node的映射了,这样就方便我们用ecs系统来遍历了,期间我们可以对结点推荐不同的define

节点的连接

这个就比较简单,我们只需要进行必要的安全判断,然后将需要的参数,比如输出节点的指针传送给输入节点即可,这边的话主要是逻辑问题

节点的断开

同上,通知输入节点,然后更新节点;

这边有意思的是,我将输入节点定义为一个二级指针,而且我们在BP_Node中存储每个节点的输出函数的一级指针,这样的好处是,我们判定一个节点的输出节点不可用时,只需要将BP_Node中的节点改变为nullptr,那么指向该指针的输入口指针就可以判断指向的内容是否为空,以便做出正确的判断,以防未定义行为;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值