聊一聊为什么最近我提了很多关于spine的'冷门'问题, 以及对cocos的spine的一些期望.
Use Case
聊一聊为什么最近我提了很多关于spine的'冷门'问题, 以及对cocos的spine的一些期望.
我最近突然提了很多关于 spine的issue, 估计cocos的工程师都被我搞烦了. 别人用着挺好的 为啥到我这就这么多逼事.
我来展开说一说背后的原因吧.
我最近在帮甲方做一个游戏项目的移植工作. 将他们c++写的自研引擎的项目 用cocos creator 重写. 以便登录国内各种小游戏平台.
甲方是一家有多年研发经验的国外公司, 除了手游, 还做过 3ds ns ps 等主机游戏. 所以我觉得可以排除他们 "不会用spine" 的这种情况.
相反, 他们对spine的使用非常的深入 和 高级. 我也学到了一些东西. 但是有一些场景 我在 cocos里难以实现. 很多时候 api也有, 但是执行就出错. 目前我怀疑是 js空间和 wasm空间之间 内存共享和传址一类的错误. 最常见的是 "memory access out of bounds" 和 "null function or function signature mismatch".
我举几个例子.
场景1: 克隆 Skin
运行时动态创建皮肤, 动态修改皮肤. 美术设计师, 只要做一套皮肤的 spine动画就可以, 比如名字叫作 level_1, 代表某角色 1级时的样子.
当角色升级时, 程序端 clone skine level_1 , 并重命名为 level_2, 同时修改皮肤中的某些元素, 再添加到 骨骼动画上. 伪代码如下:
const skinA = skeleton.findSkin(skinNameA);
const skinB = new Skine()
skinB.copySkin(skinA);
// 对 skinB 进行一些修改, 然后设置
skeleton.setSkin(skinB);
场景2: 移除 Attachment
我之前的帖子里提到过, 为什么要移除 Attachment . 因为 spine不支持动态的 隐藏 slot 的功能. 要隐藏slot , 需要隐藏slot下的 Attachment.
所以会用到 类似 slot.removeAttachment()一类的api.
但是 spine的设计是, 如果移除了, 就真的移除了, 没法还原.
所以甲方的做法是.
先备份 Attachment . 然后需要隐藏时调用 removeAttachment(), 需要显示时再 setAttachment() 给设置回去.
执行 setAttachment(attaObj) 时, 传入的是一个对象, 而不是 一个名字, 因为这个名字的附件之前已经被移除了,不存在了.
场景3: Skin 和 Slot 的 备份与还原
类似前面对 Attachment 处理. 就是 获得原始的 skin slot 对象, 备份起来. 然后程序根据游戏运行时的状态, 各种修改这些对象. 每次修改 都是基于备份的原始对象来的. 并且在某些时刻要还原成原始状态.
我试图通过备份 spine.SkeletonData 来实现类似的功能, 但是失败了. 也是 各种"memory access out of bounds" (见 https://github.com/cocos/cocos-engine/issues/17436#issuecomment-2255078544 )
他们这么做算不上奇技淫巧, 是很正常的程序化的思路. 大幅降低了动画设计师的工作量和spine动画本身的体积. 而且有些内容动画设计师也难以提前做好, 因为一个东西的样子 可能由运行时决定.
总之, 他们对"动态修改spine的各种对象" 的需求很多, 已经不仅仅是简单的"换装"了.
因为 cocos的spine组件 本身包含了 原始的 spine的runtime对象, 理论上, 甲方用到的这些功能 都能实现. 实际上我也确实找到了很多能一一对应的api. 但是 实际使用起来 要么没有效果, 要么报很多难以理解的错误(主要是wasm相关的).
不知道这个问题是否有解, 理论上应该能吧. wasm和js互相同步和操作对象的事情 其他的引擎也有做, 没有遇到类似的问题. (比如我一致关注的 https://github.com/jrouwe/JoltPhysics.js 这个项目的wasm版本可以很好的处理 wasm和js之间的数据传输和同步).
如果真的确实无解的话. 希望cocos能提供一个 让开发者"不使用wasm版本的spine ,只用ts版本spine"的开关. 这样很多问题我们开发者自己就能想办法解决了.
当然最好还是希望那些 spine wasm的api都能正常跑起来.
.
Problem Description
.
Proposed Solution
No response
How it works
No response
Alternatives Considered
.
Additional Information
No response
社区大佬 羽毛的这篇文章里提到的方案 https://mp.weixin.qq.com/s/FXCxNERcTIsw-uzL-tS-Eg
到了 wasm版本的spine 里. 基本也都跑不通了. 一部分原因是 我在另一个issue里反馈的 setAttachment 无效的bug, 另一部分也是wasm导致ide内存问题.
自己在js端 创建一个 new sp.SkeletonData() , 再赋值给 spine组件后 , 各种 内存错误.
你移植用的 spine 版本和 creator 支持的版本一样吗?
你移植用的 spine 版本和 creator 支持的版本一样吗?
一致的. 都是 3.8.99
社区大佬 羽毛的这篇文章里提到的方案 https://mp.weixin.qq.com/s/FXCxNERcTIsw-uzL-tS-Eg
到了 wasm版本的spine 里. 基本也都跑不通了. 一部分原因是 我在另一个issue里反馈的 setAttachment 无效的bug, 另一部分也是wasm导致ide内存问题.
自己在js端 创建一个 new sp.SkeletonData() , 再赋值给 spine组件后 , 各种 内存错误.
你可以认真的对比下官方提供的 3.x Ts 版本 和 C++ 版本的 spine api 是否一致。造成现在的问题就是官方提供的api 不一致导致。目前 wasm 版本 就是基于 C++ 的实现的。 老版本 的 H5 和 native 版本 之间就有不统一的问题存在。因为没有办法给一个统一的API。这次统一 wasm 也是为了处理这个问题。
说点实际的问题 setAttachment 和 new sp.SkeletonData() , 再赋值给 spine组件后 , 各种 内存错误. 提供 demo 给官方。具体问题具体分析处理。
这些都是要用的基本操作,最后你们都是怎么解决的
@IDOKN 若遇到问题,在最新的386上有问题,烦请提供demo, 后面好跟进
@bofeng-song 已经提供但没回复
@bofeng-song 已经提供但没回复
麻烦关联的 issue过来,带具体demo的
目前 spine动画的api 在 web 小游戏版本 和 原生版本 行为 不一致的问题是最困扰我的. 等用了新版本看看. 如果还有问题 我再整理吧.
@bofeng-song 已经提供但没回复
麻烦关联的 issue过来,带具体demo的
目前 spine动画的api 在 web 小游戏版本 和 原生版本 行为 不一致的问题是最困扰我的. 等用了新版本看看. 如果还有问题 我再整理吧.
@bofeng-song @minggo 如果能够通过设置, 让原生版本也用wasm spine 而非cpp spine 也许可以解决部分这种问题.