开发流派,到底哪种才是正途?

其实还是框架设计的问题和资源管理的问题,如果处理得当,换版本效率也会高不少

那么问题来了,滚动框结构不应该是很清晰明显的吗,为什么还会出现20多个预制体去绑定一个组件?我觉得这个更多可能是设计上的问题,ECS的原则就是,每个组件尽可能的只干简单的事儿

我说的是复用滚动框,当你觉得20多个预制体不会绑定一个组件,那就说明你的游戏很小,只要是通用功能就是会绑定到多个预制体上。除了复用滚动框还有很多通用组件,就例如你如果要实现一个能渐变颜色的文本,那这个组件基本所有需要颜色渐变的文本都要绑上,这是需要要求的,不是ECS设计原则上的事。在怎么简单的事,都会有通用的地方,只要通用就会有多个地方绑定。

强烈支持B

我选A
说B的小伙伴,问你个问题,你们的节点路径是自动生成配置的?
如果有这样一个需求呢,有同一个功能在5个子游戏里,但是层级,父子结构都不一样,该怎么处理?
如果是A的话就很好解决了,写一个自动关联节点uuid的代码,自动绑定

用B就加几行代码的事情,既然你能自动关联uuid,为啥B用代码还写不了了,
而且关键一点,用B,可以很纯粹的看代码就知道哪里需要修改,哪里需要维护,用A,还要仔细去找一下界面逻辑,绑定逻辑,理清楚各个节点的作用,况且A本质上也是要回归代码层,很难说用编辑器实现所有的内容

你可以说下怎么写,B的方案用来写这个,代码逻辑就会很混乱,加了一堆不必要的代码,而A框架中所有的节点都是动态绑定,直接兼容。其次用A才能更好的维护,哪个界面有问题,直接打开对应界面,全都是可视化。你可以看下大家没有用A的根本原因就是uuid绑定问题,那么只需要解决如何绑定uuid就可以了,那样B的优点A都兼容

我是一直觉得A比B好用,我现在自己写的一个装载器,自动拖拽绑定组件,不能理解为什么有人说拖拽不好用,就直接放弃A,这种的解决方案有很多,没必要强行B

不否认你说的这情况用A可以很快实现, 但是我问一下, 这个功能, 如果遇到其中某个子游戏,需要修改下对应的逻辑,就会重新再做,所以实际上,用A的风险还是很大,

用B的写法, 无非就是加载的时候,加几个自动addComponent的办法,自动绑定的脚本就完全可以实现,这个脚本可以自动导出,甚至不需要写, 如果发生更改,也只动到自己这个,不会动到其他,

这就跟组合和继承的区别一样,我觉得组合(B,只是通过代码持有)还是比较优于继承(A,嵌入编辑器,可能被反复套娃)

举个例子,我碰到过一个项目,里面写的一堆的继承,保守估计用到的类,有20层以上, 当我一层一层往上看,发现底层有一个字段的含义有问题,需要修改,这时候去查这个字段的用处都非常困难,更何况去修改它的逻辑,这时候就很头大,很容易出现顾头不顾尾,改了这边坏了那边的情况

A 方案

需要在编辑器重复修改A的情况下只存在于

  1. 这是公共代码,才会被引用多次,而公共代码不会被频繁修改

  2. 只有修改编辑器的 property 才会去动编辑器

B 方案

  1. 修改公共代码仍需要手动修改每一处,对应 A.2(如果这里能统一修改那么说明 A 也可以统一修改)

  2. 每个脚本都需要多写添加组件/组件赋值 代码

如果 A/B 同时需要修改公共组件代码

这里以需要重新赋值 property 的情况说明

A 需要

  1. 挨个打开预制体赋值

B 需要

  1. 手动修改每一处(比A快,如果这里能统一修改那么说明 A 也可以统一修改)

那么加上 B 的使用代价,判断为

B:组件添加/赋值手写代码(慢) + 手动修改每一处(快)
对比
A:组件添加/赋值拖动赋值(快) + 挨个打开预制体赋值(慢)

我个人认为 A 仍然最有性价比,因为你们忽略了累计代价(每个组件脚本多写的代码),而公共代码改动也不会很频繁。两相抵消下来就知道了

其实A也同样可以使用组合,额外写一个脚本,挂载在上面而不是改逻辑,和B的方案一样,只不过一个是addcomponent 而另一个是直接挂在上面

嗯,但是这种组合,相比于代码,并不直观,因为隐藏在编辑器内,特别是一个节点绑定了很多脚本,同时每一个脚本很多property,这时候会很难受,比如你写的,你熟悉不要紧,我并不熟悉你的部署,当我去看这块的时候,是不是要考虑组件A和组件B之间有没有关系,有没有互相持有,持有了做什么,更改属性会不会去动到,因为这个逻辑是隐藏在编辑器内的, 我需要在代码和编辑器来回横跳,理清楚逻辑才能修改出我需要的, 但是如果是B,看代码就行, 写的再烂的代码, 也比这来回横跳舒服的多

补充一点,我其实A和B都用过,先用的A,那时候就我自己一个人做的项目,是挺舒服,之后做了一个比较大的,3个人协作,那时候改bug真的要命,每个人有都有自己的风格,各种组件的property套娃,看半天都一头雾水,你试试一个scene文件有3M以上,然后几乎包括了所有的界面,弹窗,预制体,就是一个乱七八糟的线团,

后面就自己做一个绑定脚本的工具,一个预制体,自动绑定一个脚本,而且整个预制体不需要任何拖拽操作,一键导出auto_xxx脚本,然后再加一个xxx脚本做业务逻辑,持有auto_xxx

喜欢用A的,不反对,但我是经过A的毒打,教训,果断支持B,

B也存在不少问题,如果代码不规范,乱继承,乱持有,各种骚操作,可是这些,可以做一定程度的规范,虽然无法避免,但是相比于隐藏在编辑器里面的组件逻辑,代码肯定会比编辑器直观的多

:+1:这个说的非常好,也说出了我的心声,奈何我表达能力不足 :rofl:。还是那个观点,小项目用A随便搞,大项目用B维护性绝对好很多

只能说是因为使用不规范导致的,如果用我上面推荐的方式就不会出现套娃的情况,每个 模块组件提供静态的 open 函数(代替了 new) 用来加载预制

我刚进目前的公司也是类似这种情况,但是是通过资源路径加载,然后又不准用 MVVM,我就改进了下

嗯, 是可以通过工具进行避免,可是做这个说真的,不如直接用B实在,因为游戏是程序,必须要回归到代码本身,我何必在编辑器里面搞一套,代码里面搞一套,单单这点,就是在套娃

这是你觉得每个组件脚本多写的代码会慢吧,用B的大多数都会想办法去使用各种工具,自动导出这些代码,根本不需要拖动操作,一键导出代码,跟你手动拖动哪一个快

修改每一处没毛病,因为代码是有执行逻辑的,代码看过去如果基本一致,写一个正则表达式全局替换不就好了, 甚至可以自己去写vscode插件优化编码,或者其他IDE的也可以啊,

说到IDE,我补充一点,用B可以很纯粹的在IDE里面遨游,都不太需要管编辑器,最多看下界面节点,

image

总是审核,感觉号被控了

可以实现, 我不方便发,可以大概跟你讲一下思路

方案1: 每一个预制体,根节点(一般是根节点), 添加一个ReflectorComponent, 这个组件就一个属性, cc.Node[], 只往里面加入这个界面需要使用的node就行, 导出的时候,会根据这个list,导出这些node的所有component, 放在auto_xxx里面, 用的时候就是this.auto_ui.testComponent …

方案2: 不用这个ReflectorComponent,直接导出所有节点, 这个性能上的消耗其实可以忽略不计,但是也有点影响代码冗余度, 觉得不舒服的可以用方案1

你这个说的完全不相关阿,我之前说的是 使用代码添加组件,给组件属性赋值,你这里说的啥,组件节点引用?

???
已经很清晰了
我就给预制体加一个自动脚本,一个业务脚本, 自动脚本里面包括了组件属性赋值