想用oops?你必须知道这些事

前言

看到还有很多新手使用 oops,包括我当前公司的项目(老项目)也在使用 oops,那么给其他不了解 oops 的人避坑。

以下内容均使用最新版本 oops 测试

UI

UI 配置设计不合理

定义一个 UI 模块,你需要添加一个枚举,然后再在另一个对象中添加配置

问题:

  1. 没有静态错误检查:添加了 UIID 没添加 UIConfigData 时不会报错,只有运行时报错
    image

  2. 不必要的枚举:已经可以使用对象键作为 UI 模块类型,为什么还要添加枚举?(改进如下)

  3. UI 配置和UI 的 class 没有直接联系,只能规定命名或者先找到配置再打开预制体查看挂载的 class。意味着纯脚本编程很困难

初始化参数没有类型安全

正常的类型安全

image

不能重复创建相同的 UI

是的,如果你想要创建子弹这些重复 UI,你不能使用 oops 的 UI 管理 :+1:
image

公开的 Layer 类型不能使用

框架基础功能 BUG,当 UI 配置的 layer 为 LayerType.Game 时不能正常打开
image

接口设计错误

打开 UI 竟然有 open 和 openAsync 两个接口,而打开 UI 是异步的行为,open 接口只应该是异步函数

场景限制

oops 内的所有模块都是依靠父节点来控制各种类型的显示层级。

这意味着你不能创建多场景,像场景的 SkyBox,Fog,Shadow 这些配置都需要你写额外的代码来动态控制。

事件

event 对象为私有属性

UI 的父类为 GameComponent,其中 event 为私有属性用户只能通过 on、off、dispatchEvent 接口访问。

阉割的 event

想要使用 once 只能用 oops.message.once,而 on、once、off 都不支持使用类型取消监听。也没有 targetOff

如果你写的 event 不会比 cocos 的 EventTarget 更好,为什么要自己实现?

没有类型安全检测

即使没有 xxx 这个事件类型你也可以监听/派发且不报错
image

音频

oops 的音效只实现了一些最基础的功能。

功能缺失

  1. 不能单独控制音频的音量、进度、循环、是/否重叠播放(最基础的需求)

  2. 音乐分组只有音乐、音效且不支持动态扩展(例如我想单独控制场景声、人声分类的音频是不行的)

  3. 没有音频最大数量(AudioSource.maxAudioChannel)的安全处理
    如果播放数量超过 maxAudioChannel 值, cocos 会默认停止之前播放的音频。而最好的处理方式是中断当前想要播放的音频而不是之前的。

存储

没有类型安全

示例如下

存储键安全


存储值类型安全

而 oops 都没有

资源管理

接口设计错误

同 UI,也设计了 load 和 loadAsync 接口

旧版本的的资源管理

直接释放资源及依赖资源,如果此时另一个 UI 共用了当前关闭 UI 的资源,此时直接报错

oops 的新版本改为了使用 decRef,这是正常的做法,但是在 cocos 的3.x早期版本中存在释放资源加载释放的资源获取的资源是被销毁后的。所以想要安全的释放资源 assetManager.releaseAsset 是最好的选择(需要自行控制释放时机)

没有释放动态合图的资源

如果你开启了动态合图,那么合图的资源由 DynamicAtlasManager 控制,它也需要被释放

没有自动资源引用管理

意味着你需要自己 addRef, decRef

新手引导

oops 对其功能收费,而这是最基础的游戏功能之一。其他人如有需要可以参考 MK 中的新手引导管理器,开源/免费,且保证比其他任何的引导框架更好,欢迎挑战

结尾

还有更多内容限于时间问题不再展开(例如其中的ECS、 MVVM)。我对 oops 的评价就是看着很完善的新手玩具…

有问题欢迎反驳

2赞

这我就要说道说道你了,oops有资源管理,你可以手动释放模块,其他的魔改啊,学学我,全给他魔改了

学习了,考虑评价一下X-Forge吗

啥是oops

1赞

面向对象+s吧

唯一的资源管理是封装了 decRef :rofl: 而我的 MKFramework 是自动化管理,不需要自己魔改

论坛之前发布的游戏框架,很多新手用。但是我不看好它

框架这东西最好自己缝合一个,把别人好的都copy过来,不然要自定义的时候麻烦。

你的框架有非蛇形命名的版本吗?

哥,你的框架里下划线可不可以少点。。。我真有强迫症。。 :sweat_smile:

其他很 NB

我在考虑是否全部改成驼峰,但是会让之前的版本不兼容

1赞

个人比较喜欢遵循每个语言的官方命名规范 :joy:

官方的不一定是最好的,就像我在变量后面加的 _n, _b, _s, _ns, _tab, _map 都可以代表其类型,驼峰就得写 xxxNum, xxxStr, isXxx, xxxNumList

我一般不太会给变量加上类型的后缀之类的hhh,名字能够传达是什么类型就行,不过加上类型提示也是很好的

1赞

我比较同意这点,加后缀太繁琐。名字能够传达是什么类型就行。帖子说的一些情况的确是这样,刚开始用的时候有点不习惯甚至出现过问题。然后就自己魔改了一下适合自己项目的。不过有些点可能项目还是做少了还没暴露问题,但的确可以品味一下。个人觉得框架这东西要不是公司硬性规定,自己缝合最好。当个小偷,copy别人好的。cc我自己用oops为基础魔改,缝合了点TGX、XForge。unity公司硬性规定用的公司的

一个简单的举例:this.id,id 可以是 string 或 number。你就得鼠标放上去或跳转到声明查看,打断你的编程,而加一个类型后缀则不会打断编程。有比没有更好

这个的确是问题,但我沿用了一些公司unity框架的习惯。比较特殊的定义基本都是固定死的。比如id必须用int,name必须是string、非公开参数以下划线开头等等…想完全避免肯定不现实,毕竟每个人都有自己的想法。但一个项目或者说一个公司沿用一套准则至少能减少一些困扰

  1. 场景那个,其实还是多场景的,不过要自己改一下,我改过。
    每个场景添加root节点以及root下面的game节点、gui节点。然后给这个root节点添加一个脚本,在onLoad里面重新调用oops.gui里面的方法(好像要从oops.gui的提取一下逻辑,写成新方法),重新初始化一下game节点和gui节点。
  2. 同样,我也对它那个ecs感到很疑惑(不过我本来也不熟悉ecs,不知道该怎么划分ecs),资源管理同意楼主说的。
  3. 最后,也很迷惑为啥这么多人在用这个框架,我也觉得它比较适合新手。
  4. 好像还记得那个once监听会有内存泄漏的风险,因为用once监听的事件,是移除不了的,不知道这个后面有没有修复。

小公司其实还是蛮适合的,监听问题,他应该是修复了

说真的,窗口配置可以使用装饰器来处理,可以用脚本来动态生成配置