cocos-engine icon indicating copy to clipboard operation
cocos-engine copied to clipboard

聊一聊为什么最近我提了很多关于spine的'冷门'问题, 以及对cocos的spine的一些期望.

Open finscn opened this issue 1 year ago • 4 comments

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

finscn avatar Jul 29 '24 07:07 finscn

社区大佬 羽毛的这篇文章里提到的方案 https://mp.weixin.qq.com/s/FXCxNERcTIsw-uzL-tS-Eg

到了 wasm版本的spine 里. 基本也都跑不通了. 一部分原因是 我在另一个issue里反馈的 setAttachment 无效的bug, 另一部分也是wasm导致ide内存问题.

自己在js端 创建一个 new sp.SkeletonData() , 再赋值给 spine组件后 , 各种 内存错误.

finscn avatar Jul 29 '24 10:07 finscn

你移植用的 spine 版本和 creator 支持的版本一样吗?

minggo avatar Jul 30 '24 03:07 minggo

你移植用的 spine 版本和 creator 支持的版本一样吗?

一致的. 都是 3.8.99

finscn avatar Jul 30 '24 05:07 finscn

社区大佬 羽毛的这篇文章里提到的方案 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 给官方。具体问题具体分析处理。

Canvasfull avatar Aug 19 '24 10:08 Canvasfull

这些都是要用的基本操作,最后你们都是怎么解决的

IDOKN avatar Mar 27 '25 06:03 IDOKN

@IDOKN 若遇到问题,在最新的386上有问题,烦请提供demo, 后面好跟进

bofeng-song avatar Mar 27 '25 06:03 bofeng-song

@bofeng-song 已经提供但没回复

IDOKN avatar Mar 27 '25 06:03 IDOKN

@bofeng-song 已经提供但没回复

麻烦关联的 issue过来,带具体demo的

bofeng-song avatar Mar 27 '25 07:03 bofeng-song

@bofeng-song 已经提供但没回复

麻烦关联的 issue过来,带具体demo的

目前 spine动画的api 在 web 小游戏版本 和 原生版本 行为 不一致的问题是最困扰我的. 等用了新版本看看. 如果还有问题 我再整理吧.

finscn avatar Mar 27 '25 08:03 finscn

@bofeng-song 已经提供但没回复

麻烦关联的 issue过来,带具体demo的

目前 spine动画的api 在 web 小游戏版本 和 原生版本 行为 不一致的问题是最困扰我的. 等用了新版本看看. 如果还有问题 我再整理吧.

@bofeng-song @minggo 如果能够通过设置, 让原生版本也用wasm spine 而非cpp spine 也许可以解决部分这种问题.

finscn avatar Mar 27 '25 08:03 finscn