@eva/spine-base 2.0.1-beta.37 → 2.0.1-beta.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -62,6 +62,7 @@ var _EVA_IIFE_spineBase = function (exports, eva_js, pluginRenderer) {
|
|
|
62
62
|
this.animationName = '';
|
|
63
63
|
this.autoPlay = true;
|
|
64
64
|
this.keepResource = false;
|
|
65
|
+
this._slotGameObjects = new Map();
|
|
65
66
|
this.waitExecuteInfos = [];
|
|
66
67
|
}
|
|
67
68
|
set armature(val) {
|
|
@@ -171,6 +172,45 @@ var _EVA_IIFE_spineBase = function (exports, eva_js, pluginRenderer) {
|
|
|
171
172
|
}
|
|
172
173
|
return this.armature.skeleton.findBone(boneName);
|
|
173
174
|
}
|
|
175
|
+
addSlotObject(slot, gameObject, options) {
|
|
176
|
+
if (!this.armature) {
|
|
177
|
+
console.warn('Spine armature is not ready, cannot addSlotObject');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (!this._containerManager) {
|
|
181
|
+
console.warn('ContainerManager is not available');
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const container = this._containerManager.getContainer(gameObject.id);
|
|
185
|
+
if (!container) {
|
|
186
|
+
console.warn('GameObject does not have a render container');
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
this.armature.addSlotObject(slot, container, options);
|
|
190
|
+
this._slotGameObjects.set(gameObject, slot);
|
|
191
|
+
}
|
|
192
|
+
removeSlotObject(gameObject) {
|
|
193
|
+
if (!this.armature) return;
|
|
194
|
+
if (!this._containerManager) return;
|
|
195
|
+
const container = this._containerManager.getContainer(gameObject.id);
|
|
196
|
+
if (container) {
|
|
197
|
+
this.armature.removeSlotObject(container);
|
|
198
|
+
}
|
|
199
|
+
this._slotGameObjects.delete(gameObject);
|
|
200
|
+
}
|
|
201
|
+
_destroySlotGameObjects() {
|
|
202
|
+
var _a;
|
|
203
|
+
for (const [gameObject] of this._slotGameObjects) {
|
|
204
|
+
if (!gameObject.destroyed) {
|
|
205
|
+
const container = (_a = this._containerManager) === null || _a === void 0 ? void 0 : _a.getContainer(gameObject.id);
|
|
206
|
+
if (container && this.armature) {
|
|
207
|
+
this.armature.removeSlotObject(container);
|
|
208
|
+
}
|
|
209
|
+
gameObject.destroy();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
this._slotGameObjects.clear();
|
|
213
|
+
}
|
|
174
214
|
}
|
|
175
215
|
Spine.componentName = 'Spine';
|
|
176
216
|
__decorate([type('string')], Spine.prototype, "resource", void 0);
|
|
@@ -292,7 +332,7 @@ var _EVA_IIFE_spineBase = function (exports, eva_js, pluginRenderer) {
|
|
|
292
332
|
});
|
|
293
333
|
}
|
|
294
334
|
add(changed, count) {
|
|
295
|
-
var _a, _b;
|
|
335
|
+
var _a, _b, _c;
|
|
296
336
|
return __awaiter(this, void 0, void 0, function* () {
|
|
297
337
|
const component = changed.component;
|
|
298
338
|
clearTimeout(component.addHandler);
|
|
@@ -336,6 +376,7 @@ var _EVA_IIFE_spineBase = function (exports, eva_js, pluginRenderer) {
|
|
|
336
376
|
}
|
|
337
377
|
container.addChildAt(armature, 0);
|
|
338
378
|
armature.update();
|
|
379
|
+
component._containerManager = (_c = this.renderSystem) === null || _c === void 0 ? void 0 : _c.containerManager;
|
|
339
380
|
component.armature = armature;
|
|
340
381
|
component.emit('loaded', {
|
|
341
382
|
resource: component.resource
|
|
@@ -387,6 +428,7 @@ var _EVA_IIFE_spineBase = function (exports, eva_js, pluginRenderer) {
|
|
|
387
428
|
container.removeChild(armature);
|
|
388
429
|
}
|
|
389
430
|
if (component.armature) {
|
|
431
|
+
component._destroySlotGameObjects();
|
|
390
432
|
component.armature.destroy({
|
|
391
433
|
children: true
|
|
392
434
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var
|
|
1
|
+
function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var a=arguments[t];for(var n in a)({}).hasOwnProperty.call(a,n)&&(e[n]=a[n])}return e},_extends.apply(null,arguments)}globalThis.EVA=globalThis.EVA||{},globalThis.EVA.plugin=globalThis.EVA.plugin||{};var _EVA_IIFE_spineBase=function(e,t,a){"use strict";function n(e,t,a,n){var r,i=arguments.length,o=i<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,a):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,a,n);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(o=(i<3?r(o):i>3?r(t,a,o):r(t,a))||o);return i>3&&o&&Object.defineProperty(t,a,o),o}function r(e,t,a,n){return new(a||(a=Promise))((function(r,i){function o(e){try{c(n.next(e))}catch(e){i(e)}}function s(e){try{c(n.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?r(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(o,s)}c((n=n.apply(e,t||[])).next())}))}function i(e){return function(t,a){var n=function(e,t){return e.constructor.IDEProps||(e.constructor.IDEProps={}),e.constructor.IDEProps[t]||(e.constructor.IDEProps[t]={}),e.constructor.IDEProps[t]}(t,a);n.key=a,n.type=e}}class o extends t.Component{constructor(){super(...arguments),this.resource="",this.scale=1,this.animationName="",this.autoPlay=!0,this.keepResource=!1,this._slotGameObjects=new Map,this.waitExecuteInfos=[]}set armature(e){if(this._armature=e,e){this.autoPlay&&this.play(this.animationName);for(const e of this.waitExecuteInfos)if(e.playType){const{name:t,loop:a,track:n}=e;this.play(t,a,n)}else this.stop(e.track);this.waitExecuteInfos=[]}}get armature(){return this._armature}init(e){e&&_extends(this,e)}onDestroy(){this.destroied=!0}play(e,t,a){try{const n=null!=t?t:this.autoPlay;e&&(this.animationName=e),this.armature?(void 0===a&&(a=0),this.armature.state.setAnimation(a,this.animationName,n)):this.waitExecuteInfos.push({playType:!0,name:e,loop:n,track:a})}catch(e){console.log(e)}}stop(e){this.armature?(void 0===e&&(e=0),this.armature.state.setEmptyAnimation(e,0)):this.waitExecuteInfos.push({playType:!1,track:e})}addAnimation(e,t,a,n){try{this.armature&&(void 0===n&&(n=0),this.armature.state.addAnimation(n,e,a,t))}catch(e){console.log(e)}}setMix(e,t,a){this.armature&&this.armature.state.data.setMix(e,t,a)}getAnim(e=0){try{if(this.armature)return this.armature.state.tracks[e].animation.name}catch(e){console.log(e)}}setDefaultMix(e){this.armature&&(this.armature.state.data.defaultMix=e)}setAttachment(e,t){this.armature&&this.armature.skeleton.setAttachment(e,t)}getBone(e){if(this.armature)return this.armature.skeleton.findBone(e)}addSlotObject(e,t,a){if(!this.armature)return void console.warn("Spine armature is not ready, cannot addSlotObject");if(!this._containerManager)return void console.warn("ContainerManager is not available");const n=this._containerManager.getContainer(t.id);n?(this.armature.addSlotObject(e,n,a),this._slotGameObjects.set(t,e)):console.warn("GameObject does not have a render container")}removeSlotObject(e){if(!this.armature)return;if(!this._containerManager)return;const t=this._containerManager.getContainer(e.id);t&&this.armature.removeSlotObject(t),this._slotGameObjects.delete(e)}_destroySlotGameObjects(){var e;for(const[t]of this._slotGameObjects)if(!t.destroyed){const a=null===(e=this._containerManager)||void 0===e?void 0:e.getContainer(t.id);a&&this.armature&&this.armature.removeSlotObject(a),t.destroy()}this._slotGameObjects.clear()}}o.componentName="Spine",n([i("string")],o.prototype,"resource",void 0),n([i("number")],o.prototype,"scale",void 0),n([i("string")],o.prototype,"animationName",void 0),n([i("boolean")],o.prototype,"autoPlay",void 0),n([i("boolean")],o.prototype,"keepResource",void 0);let s={};function c(e,t,a){return r(this,void 0,void 0,(function*(){let n=s[e.name];if(!n)if(e.complete)n=function(e,t,a,n){const r=t.ske,i=t.atlas,o=new n.AtlasAttachmentLoader(i),c=r instanceof Uint8Array?new n.SkeletonBinary(o):new n.SkeletonJson(o);c.scale=a||1;const u={spineData:c.readSkeletonData(r),ref:0,imageSrc:t.image.label};return s[e]=u,u}(e.name,e.data,t,a);else if(!n)return;return n.ref++,n.spineData}))}let u=class extends a.Renderer{constructor(){super(...arguments),this.armatures={}}init({pixiSpine:e}){this.renderSystem=this.game.getSystem(a.RendererSystem),this.renderSystem.rendererManager.register(this),this.pixiSpine=e,this.game.canvas.addEventListener("webglcontextrestored",(()=>{const e=this.game.gameObjects;let a=[];for(let n in this.armatures){const r=+n;for(let n=0;n<e.length;++n){let i=e[n];if(i.id===r){let e=i.getComponent(o);e&&(this.remove({type:t.OBSERVER_TYPE.REMOVE,gameObject:i,component:e,componentName:o.componentName}),a.push({type:t.OBSERVER_TYPE.ADD,gameObject:i,component:e,componentName:o.componentName}));break}}}setTimeout((()=>{a.forEach((e=>{this.add(e)}))}),1e3)}),!1)}update(e){for(let t in this.armatures)this.armatures[t].update(.001*e.deltaTime);super.update()}componentChanged(e){return r(this,void 0,void 0,(function*(){if("Spine"===e.componentName)if(e.type===t.OBSERVER_TYPE.ADD)this.add(e);else if(e.type===t.OBSERVER_TYPE.CHANGE){if("resource"===e.prop.prop[0])this.change(e)}else e.type===t.OBSERVER_TYPE.REMOVE&&this.remove(e)}))}add(e,a){var n,i,o;return r(this,void 0,void 0,(function*(){const r=e.component;clearTimeout(r.addHandler);const s=e.gameObject.id,u=this.increaseAsyncId(s),m=yield t.resource.getResource(r.resource);if(!this.validateAsyncId(s,u))return;const d=yield c(m,r.scale,this.pixiSpine);if(!this.validateAsyncId(s,u))return;if(!d)return void(r.addHandler=setTimeout((()=>{r.destroied||(void 0===a&&(a=20),--a>0?this.add(e,a):console.log("retry exceed max times",r.resource))}),1e3));this.remove(e);const l=null===(i=null===(n=this.renderSystem)||void 0===n?void 0:n.containerManager)||void 0===i?void 0:i.getContainer(e.gameObject.id);if(!l)return;r.lastResource=r.resource;const h=new this.pixiSpine.Spine({skeletonData:d,autoUpdate:!1});if(this.armatures[e.gameObject.id]=h,e.gameObject&&e.gameObject.transform){const t=e.gameObject.transform;h.x=t.size.width*t.origin.x,h.y=t.size.height*t.origin.y}l.addChildAt(h,0),h.update(),r._containerManager=null===(o=this.renderSystem)||void 0===o?void 0:o.containerManager,r.armature=h,r.emit("loaded",{resource:r.resource}),h.state.addListener({start:(e,t)=>{r.emit("start",{track:e,name:e.animation.name})},complete:(e,t)=>{r.emit("complete",{track:e,name:e.animation.name})},interrupt:(e,t)=>{r.emit("interrupt",{track:e,name:e.animation.name})},end:(e,t)=>{r.emit("end",{track:e,name:e.animation.name})},event:(e,t)=>{r.emit("event",e,t)}})}))}change(e){this.remove(e),this.add(e)}remove(e){var a,n,i,o,c,u;return r(this,void 0,void 0,(function*(){this.increaseAsyncId(e.gameObject.id);const m=e.component;clearTimeout(m.addHandler);const d=this.armatures[e.gameObject.id],l=null===(n=null===(a=this.renderSystem)||void 0===a?void 0:a.containerManager)||void 0===n?void 0:n.getContainer(e.gameObject.id);if(l&&d&&l.removeChild(d),m.armature&&(m._destroySlotGameObjects(),m.armature.destroy({children:!0}),!m.keepResource)){const e=yield t.resource.getResource(m.lastResource);(null===(o=null===(i=e.data)||void 0===i?void 0:i.image)||void 0===o?void 0:o.src)||null===(u=null===(c=e.data)||void 0===c?void 0:c.image)||void 0===u||u.label,function(e){const a=e.name,n=s[a];n&&(n.ref--,setTimeout((()=>r(this,void 0,void 0,(function*(){n.ref<=0&&(t.resource.destroy(a),delete s[a])}))),100))}(e)}m.armature=null,delete this.armatures[e.gameObject.id],e.type,t.OBSERVER_TYPE.CHANGE}))}};u.systemName="SpineSystem",u=n([t.decorators.componentObserver({Spine:["resource"]})],u);var m=u;return t.resource.registerResourceType("SPINE"),e.Spine=o,e.SpineSystem=m,Object.defineProperty(e,"__esModule",{value:!0}),e}({},EVA,EVA.plugin.renderer);globalThis.EVA.plugin.spineBase=globalThis.EVA.plugin.spineBase||_EVA_IIFE_spineBase;
|
package/dist/spine-base.cjs.js
CHANGED
|
@@ -104,6 +104,8 @@ class Spine extends eva_js.Component {
|
|
|
104
104
|
this.autoPlay = true;
|
|
105
105
|
/** 是否保留资源(销毁时不释放) */
|
|
106
106
|
this.keepResource = false;
|
|
107
|
+
/** 挂载到插槽的 GameObject 映射(GameObject -> slot 标识) */
|
|
108
|
+
this._slotGameObjects = new Map();
|
|
107
109
|
/** 等待执行的动画操作队列 */
|
|
108
110
|
this.waitExecuteInfos = [];
|
|
109
111
|
}
|
|
@@ -308,6 +310,67 @@ class Spine extends eva_js.Component {
|
|
|
308
310
|
}
|
|
309
311
|
return this.armature.skeleton.findBone(boneName);
|
|
310
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* 将一个 GameObject 挂载到 Spine 的指定插槽上
|
|
315
|
+
*
|
|
316
|
+
* 挂载后 GameObject 会跟随骨骼运动。当 Spine 组件销毁时,
|
|
317
|
+
* 挂载的 GameObject 也会被自动销毁。
|
|
318
|
+
*
|
|
319
|
+
* @param slot - 插槽名称或索引
|
|
320
|
+
* @param gameObject - 要挂载的 GameObject
|
|
321
|
+
* @param options - 可选配置
|
|
322
|
+
* @param options.followAttachmentTimeline - 是否跟随插槽的附件时间线
|
|
323
|
+
*/
|
|
324
|
+
addSlotObject(slot, gameObject, options) {
|
|
325
|
+
if (!this.armature) {
|
|
326
|
+
console.warn('Spine armature is not ready, cannot addSlotObject');
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (!this._containerManager) {
|
|
330
|
+
console.warn('ContainerManager is not available');
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const container = this._containerManager.getContainer(gameObject.id);
|
|
334
|
+
if (!container) {
|
|
335
|
+
console.warn('GameObject does not have a render container');
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
this.armature.addSlotObject(slot, container, options);
|
|
339
|
+
this._slotGameObjects.set(gameObject, slot);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* 从插槽上移除挂载的 GameObject
|
|
343
|
+
*
|
|
344
|
+
* @param gameObject - 要移除的 GameObject
|
|
345
|
+
*/
|
|
346
|
+
removeSlotObject(gameObject) {
|
|
347
|
+
if (!this.armature)
|
|
348
|
+
return;
|
|
349
|
+
if (!this._containerManager)
|
|
350
|
+
return;
|
|
351
|
+
const container = this._containerManager.getContainer(gameObject.id);
|
|
352
|
+
if (container) {
|
|
353
|
+
this.armature.removeSlotObject(container);
|
|
354
|
+
}
|
|
355
|
+
this._slotGameObjects.delete(gameObject);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* 销毁所有挂载到插槽的 GameObject(内部使用)
|
|
359
|
+
*/
|
|
360
|
+
_destroySlotGameObjects() {
|
|
361
|
+
var _a;
|
|
362
|
+
for (const [gameObject] of this._slotGameObjects) {
|
|
363
|
+
if (!gameObject.destroyed) {
|
|
364
|
+
// 先从 spine 插槽移除,避免 destroy 时重复操作
|
|
365
|
+
const container = (_a = this._containerManager) === null || _a === void 0 ? void 0 : _a.getContainer(gameObject.id);
|
|
366
|
+
if (container && this.armature) {
|
|
367
|
+
this.armature.removeSlotObject(container);
|
|
368
|
+
}
|
|
369
|
+
gameObject.destroy();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
this._slotGameObjects.clear();
|
|
373
|
+
}
|
|
311
374
|
}
|
|
312
375
|
/** 组件名称 */
|
|
313
376
|
Spine.componentName = 'Spine';
|
|
@@ -469,7 +532,7 @@ let SpineSystem = class SpineSystem extends pluginRenderer.Renderer {
|
|
|
469
532
|
});
|
|
470
533
|
}
|
|
471
534
|
add(changed, count) {
|
|
472
|
-
var _a, _b;
|
|
535
|
+
var _a, _b, _c;
|
|
473
536
|
return __awaiter(this, void 0, void 0, function* () {
|
|
474
537
|
const component = changed.component;
|
|
475
538
|
clearTimeout(component.addHandler);
|
|
@@ -520,6 +583,7 @@ let SpineSystem = class SpineSystem extends pluginRenderer.Renderer {
|
|
|
520
583
|
container.addChildAt(armature, 0);
|
|
521
584
|
/** 保证第一帧显示正常 */
|
|
522
585
|
armature.update();
|
|
586
|
+
component._containerManager = (_c = this.renderSystem) === null || _c === void 0 ? void 0 : _c.containerManager;
|
|
523
587
|
component.armature = armature;
|
|
524
588
|
// @ts-ignore
|
|
525
589
|
component.emit('loaded', { resource: component.resource });
|
|
@@ -563,6 +627,8 @@ let SpineSystem = class SpineSystem extends pluginRenderer.Renderer {
|
|
|
563
627
|
container.removeChild(armature);
|
|
564
628
|
}
|
|
565
629
|
if (component.armature) {
|
|
630
|
+
// 销毁所有挂载到插槽的 GameObject
|
|
631
|
+
component._destroySlotGameObjects();
|
|
566
632
|
component.armature.destroy({ children: true });
|
|
567
633
|
if (!component.keepResource) {
|
|
568
634
|
const res = yield eva_js.resource.getResource(component.lastResource);
|
|
@@ -13,4 +13,4 @@ MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
|
13
13
|
See the Apache Version 2.0 License for specific language governing permissions
|
|
14
14
|
and limitations under the License.
|
|
15
15
|
***************************************************************************** */
|
|
16
|
-
function
|
|
16
|
+
function r(e,t,a,r){var i,n=arguments.length,o=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,a):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,a,r);else for(var s=e.length-1;s>=0;s--)(i=e[s])&&(o=(n<3?i(o):n>3?i(t,a,o):i(t,a))||o);return n>3&&o&&Object.defineProperty(t,a,o),o}function i(e,t,a,r){return new(a||(a=Promise))((function(i,n){function o(e){try{c(r.next(e))}catch(e){n(e)}}function s(e){try{c(r.throw(e))}catch(e){n(e)}}function c(e){e.done?i(e.value):new a((function(t){t(e.value)})).then(o,s)}c((r=r.apply(e,t||[])).next())}))}class n extends e.Component{constructor(){super(...arguments),this.resource="",this.scale=1,this.animationName="",this.autoPlay=!0,this.keepResource=!1,this._slotGameObjects=new Map,this.waitExecuteInfos=[]}set armature(e){if(this._armature=e,e){this.autoPlay&&this.play(this.animationName);for(const e of this.waitExecuteInfos)if(e.playType){const{name:t,loop:a,track:r}=e;this.play(t,a,r)}else this.stop(e.track);this.waitExecuteInfos=[]}}get armature(){return this._armature}init(e){e&&Object.assign(this,e)}onDestroy(){this.destroied=!0}play(e,t,a){try{const r=null!=t?t:this.autoPlay;e&&(this.animationName=e),this.armature?(void 0===a&&(a=0),this.armature.state.setAnimation(a,this.animationName,r)):this.waitExecuteInfos.push({playType:!0,name:e,loop:r,track:a})}catch(e){console.log(e)}}stop(e){this.armature?(void 0===e&&(e=0),this.armature.state.setEmptyAnimation(e,0)):this.waitExecuteInfos.push({playType:!1,track:e})}addAnimation(e,t,a,r){try{this.armature&&(void 0===r&&(r=0),this.armature.state.addAnimation(r,e,a,t))}catch(e){console.log(e)}}setMix(e,t,a){this.armature&&this.armature.state.data.setMix(e,t,a)}getAnim(e=0){try{if(this.armature)return this.armature.state.tracks[e].animation.name}catch(e){console.log(e)}}setDefaultMix(e){this.armature&&(this.armature.state.data.defaultMix=e)}setAttachment(e,t){this.armature&&this.armature.skeleton.setAttachment(e,t)}getBone(e){if(this.armature)return this.armature.skeleton.findBone(e)}addSlotObject(e,t,a){if(!this.armature)return void console.warn("Spine armature is not ready, cannot addSlotObject");if(!this._containerManager)return void console.warn("ContainerManager is not available");const r=this._containerManager.getContainer(t.id);r?(this.armature.addSlotObject(e,r,a),this._slotGameObjects.set(t,e)):console.warn("GameObject does not have a render container")}removeSlotObject(e){if(!this.armature)return;if(!this._containerManager)return;const t=this._containerManager.getContainer(e.id);t&&this.armature.removeSlotObject(t),this._slotGameObjects.delete(e)}_destroySlotGameObjects(){var e;for(const[t]of this._slotGameObjects)if(!t.destroyed){const a=null===(e=this._containerManager)||void 0===e?void 0:e.getContainer(t.id);a&&this.armature&&this.armature.removeSlotObject(a),t.destroy()}this._slotGameObjects.clear()}}n.componentName="Spine",r([a.type("string")],n.prototype,"resource",void 0),r([a.type("number")],n.prototype,"scale",void 0),r([a.type("string")],n.prototype,"animationName",void 0),r([a.type("boolean")],n.prototype,"autoPlay",void 0),r([a.type("boolean")],n.prototype,"keepResource",void 0);let o={};function s(e,t,a){return i(this,void 0,void 0,(function*(){let r=o[e.name];if(!r)if(e.complete)r=function(e,t,a,r){const i=t.ske,n=t.atlas,s=new r.AtlasAttachmentLoader(n),c=i instanceof Uint8Array?new r.SkeletonBinary(s):new r.SkeletonJson(s);c.scale=a||1;const m={spineData:c.readSkeletonData(i),ref:0,imageSrc:t.image.label};return o[e]=m,m}(e.name,e.data,t,a);else if(!r)return;return r.ref++,r.spineData}))}let c=class extends t.Renderer{constructor(){super(...arguments),this.armatures={}}init({pixiSpine:a}){this.renderSystem=this.game.getSystem(t.RendererSystem),this.renderSystem.rendererManager.register(this),this.pixiSpine=a,this.game.canvas.addEventListener("webglcontextrestored",(()=>{const t=this.game.gameObjects;let a=[];for(let r in this.armatures){const i=+r;for(let r=0;r<t.length;++r){let o=t[r];if(o.id===i){let t=o.getComponent(n);t&&(this.remove({type:e.OBSERVER_TYPE.REMOVE,gameObject:o,component:t,componentName:n.componentName}),a.push({type:e.OBSERVER_TYPE.ADD,gameObject:o,component:t,componentName:n.componentName}));break}}}setTimeout((()=>{a.forEach((e=>{this.add(e)}))}),1e3)}),!1)}update(e){for(let t in this.armatures)this.armatures[t].update(.001*e.deltaTime);super.update()}componentChanged(t){return i(this,void 0,void 0,(function*(){if("Spine"===t.componentName)if(t.type===e.OBSERVER_TYPE.ADD)this.add(t);else if(t.type===e.OBSERVER_TYPE.CHANGE){if("resource"===t.prop.prop[0])this.change(t)}else t.type===e.OBSERVER_TYPE.REMOVE&&this.remove(t)}))}add(t,a){var r,n,o;return i(this,void 0,void 0,(function*(){const i=t.component;clearTimeout(i.addHandler);const c=t.gameObject.id,m=this.increaseAsyncId(c),d=yield e.resource.getResource(i.resource);if(!this.validateAsyncId(c,m))return;const u=yield s(d,i.scale,this.pixiSpine);if(!this.validateAsyncId(c,m))return;if(!u)return void(i.addHandler=setTimeout((()=>{i.destroied||(void 0===a&&(a=20),--a>0?this.add(t,a):console.log("retry exceed max times",i.resource))}),1e3));this.remove(t);const l=null===(n=null===(r=this.renderSystem)||void 0===r?void 0:r.containerManager)||void 0===n?void 0:n.getContainer(t.gameObject.id);if(!l)return;i.lastResource=i.resource;const h=new this.pixiSpine.Spine({skeletonData:u,autoUpdate:!1});if(this.armatures[t.gameObject.id]=h,t.gameObject&&t.gameObject.transform){const e=t.gameObject.transform;h.x=e.size.width*e.origin.x,h.y=e.size.height*e.origin.y}l.addChildAt(h,0),h.update(),i._containerManager=null===(o=this.renderSystem)||void 0===o?void 0:o.containerManager,i.armature=h,i.emit("loaded",{resource:i.resource}),h.state.addListener({start:(e,t)=>{i.emit("start",{track:e,name:e.animation.name})},complete:(e,t)=>{i.emit("complete",{track:e,name:e.animation.name})},interrupt:(e,t)=>{i.emit("interrupt",{track:e,name:e.animation.name})},end:(e,t)=>{i.emit("end",{track:e,name:e.animation.name})},event:(e,t)=>{i.emit("event",e,t)}})}))}change(e){this.remove(e),this.add(e)}remove(t){var a,r,n,s,c,m;return i(this,void 0,void 0,(function*(){this.increaseAsyncId(t.gameObject.id);const d=t.component;clearTimeout(d.addHandler);const u=this.armatures[t.gameObject.id],l=null===(r=null===(a=this.renderSystem)||void 0===a?void 0:a.containerManager)||void 0===r?void 0:r.getContainer(t.gameObject.id);if(l&&u&&l.removeChild(u),d.armature&&(d._destroySlotGameObjects(),d.armature.destroy({children:!0}),!d.keepResource)){const t=yield e.resource.getResource(d.lastResource);(null===(s=null===(n=t.data)||void 0===n?void 0:n.image)||void 0===s?void 0:s.src)||null===(m=null===(c=t.data)||void 0===c?void 0:c.image)||void 0===m||m.label,function(t){const a=t.name,r=o[a];r&&(r.ref--,setTimeout((()=>i(this,void 0,void 0,(function*(){r.ref<=0&&(e.resource.destroy(a),delete o[a])}))),100))}(t)}d.armature=null,delete this.armatures[t.gameObject.id],t.type,e.OBSERVER_TYPE.CHANGE}))}};c.systemName="SpineSystem",c=r([e.decorators.componentObserver({Spine:["resource"]})],c);var m=c;e.resource.registerResourceType("SPINE"),exports.Spine=n,exports.SpineSystem=m;
|
package/dist/spine-base.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Component } from '@eva/eva.js';
|
|
|
3
3
|
import { ComponentChanged } from '@eva/eva.js';
|
|
4
4
|
import { Container } from 'pixi.js';
|
|
5
5
|
import { ContainerManager } from '@eva/plugin-renderer';
|
|
6
|
+
import { GameObject } from '@eva/eva.js';
|
|
6
7
|
import { Renderer } from '@eva/plugin-renderer';
|
|
7
8
|
import { RendererManager } from '@eva/plugin-renderer';
|
|
8
9
|
import { RendererSystem } from '@eva/plugin-renderer';
|
|
@@ -77,6 +78,10 @@ export declare class Spine extends Component<SpineParams> {
|
|
|
77
78
|
keepResource: boolean;
|
|
78
79
|
/** Spine 骨架实例(内部使用) */
|
|
79
80
|
private _armature;
|
|
81
|
+
/** 容器管理器引用(由 SpineSystem 设置) */
|
|
82
|
+
_containerManager: any;
|
|
83
|
+
/** 挂载到插槽的 GameObject 映射(GameObject -> slot 标识) */
|
|
84
|
+
private _slotGameObjects;
|
|
80
85
|
/** 等待执行的动画操作队列 */
|
|
81
86
|
private waitExecuteInfos;
|
|
82
87
|
/**
|
|
@@ -175,6 +180,30 @@ export declare class Spine extends Component<SpineParams> {
|
|
|
175
180
|
* @returns 骨骼对象,如果未找到则返回 undefined
|
|
176
181
|
*/
|
|
177
182
|
getBone(boneName: string): any;
|
|
183
|
+
/**
|
|
184
|
+
* 将一个 GameObject 挂载到 Spine 的指定插槽上
|
|
185
|
+
*
|
|
186
|
+
* 挂载后 GameObject 会跟随骨骼运动。当 Spine 组件销毁时,
|
|
187
|
+
* 挂载的 GameObject 也会被自动销毁。
|
|
188
|
+
*
|
|
189
|
+
* @param slot - 插槽名称或索引
|
|
190
|
+
* @param gameObject - 要挂载的 GameObject
|
|
191
|
+
* @param options - 可选配置
|
|
192
|
+
* @param options.followAttachmentTimeline - 是否跟随插槽的附件时间线
|
|
193
|
+
*/
|
|
194
|
+
addSlotObject(slot: number | string, gameObject: GameObject, options?: {
|
|
195
|
+
followAttachmentTimeline?: boolean;
|
|
196
|
+
}): void;
|
|
197
|
+
/**
|
|
198
|
+
* 从插槽上移除挂载的 GameObject
|
|
199
|
+
*
|
|
200
|
+
* @param gameObject - 要移除的 GameObject
|
|
201
|
+
*/
|
|
202
|
+
removeSlotObject(gameObject: GameObject): void;
|
|
203
|
+
/**
|
|
204
|
+
* 销毁所有挂载到插槽的 GameObject(内部使用)
|
|
205
|
+
*/
|
|
206
|
+
_destroySlotGameObjects(): void;
|
|
178
207
|
}
|
|
179
208
|
|
|
180
209
|
export declare interface SpineParams {
|
package/dist/spine-base.esm.js
CHANGED
|
@@ -100,6 +100,8 @@ class Spine extends Component {
|
|
|
100
100
|
this.autoPlay = true;
|
|
101
101
|
/** 是否保留资源(销毁时不释放) */
|
|
102
102
|
this.keepResource = false;
|
|
103
|
+
/** 挂载到插槽的 GameObject 映射(GameObject -> slot 标识) */
|
|
104
|
+
this._slotGameObjects = new Map();
|
|
103
105
|
/** 等待执行的动画操作队列 */
|
|
104
106
|
this.waitExecuteInfos = [];
|
|
105
107
|
}
|
|
@@ -304,6 +306,67 @@ class Spine extends Component {
|
|
|
304
306
|
}
|
|
305
307
|
return this.armature.skeleton.findBone(boneName);
|
|
306
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* 将一个 GameObject 挂载到 Spine 的指定插槽上
|
|
311
|
+
*
|
|
312
|
+
* 挂载后 GameObject 会跟随骨骼运动。当 Spine 组件销毁时,
|
|
313
|
+
* 挂载的 GameObject 也会被自动销毁。
|
|
314
|
+
*
|
|
315
|
+
* @param slot - 插槽名称或索引
|
|
316
|
+
* @param gameObject - 要挂载的 GameObject
|
|
317
|
+
* @param options - 可选配置
|
|
318
|
+
* @param options.followAttachmentTimeline - 是否跟随插槽的附件时间线
|
|
319
|
+
*/
|
|
320
|
+
addSlotObject(slot, gameObject, options) {
|
|
321
|
+
if (!this.armature) {
|
|
322
|
+
console.warn('Spine armature is not ready, cannot addSlotObject');
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (!this._containerManager) {
|
|
326
|
+
console.warn('ContainerManager is not available');
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const container = this._containerManager.getContainer(gameObject.id);
|
|
330
|
+
if (!container) {
|
|
331
|
+
console.warn('GameObject does not have a render container');
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
this.armature.addSlotObject(slot, container, options);
|
|
335
|
+
this._slotGameObjects.set(gameObject, slot);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* 从插槽上移除挂载的 GameObject
|
|
339
|
+
*
|
|
340
|
+
* @param gameObject - 要移除的 GameObject
|
|
341
|
+
*/
|
|
342
|
+
removeSlotObject(gameObject) {
|
|
343
|
+
if (!this.armature)
|
|
344
|
+
return;
|
|
345
|
+
if (!this._containerManager)
|
|
346
|
+
return;
|
|
347
|
+
const container = this._containerManager.getContainer(gameObject.id);
|
|
348
|
+
if (container) {
|
|
349
|
+
this.armature.removeSlotObject(container);
|
|
350
|
+
}
|
|
351
|
+
this._slotGameObjects.delete(gameObject);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* 销毁所有挂载到插槽的 GameObject(内部使用)
|
|
355
|
+
*/
|
|
356
|
+
_destroySlotGameObjects() {
|
|
357
|
+
var _a;
|
|
358
|
+
for (const [gameObject] of this._slotGameObjects) {
|
|
359
|
+
if (!gameObject.destroyed) {
|
|
360
|
+
// 先从 spine 插槽移除,避免 destroy 时重复操作
|
|
361
|
+
const container = (_a = this._containerManager) === null || _a === void 0 ? void 0 : _a.getContainer(gameObject.id);
|
|
362
|
+
if (container && this.armature) {
|
|
363
|
+
this.armature.removeSlotObject(container);
|
|
364
|
+
}
|
|
365
|
+
gameObject.destroy();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
this._slotGameObjects.clear();
|
|
369
|
+
}
|
|
307
370
|
}
|
|
308
371
|
/** 组件名称 */
|
|
309
372
|
Spine.componentName = 'Spine';
|
|
@@ -465,7 +528,7 @@ let SpineSystem = class SpineSystem extends Renderer {
|
|
|
465
528
|
});
|
|
466
529
|
}
|
|
467
530
|
add(changed, count) {
|
|
468
|
-
var _a, _b;
|
|
531
|
+
var _a, _b, _c;
|
|
469
532
|
return __awaiter(this, void 0, void 0, function* () {
|
|
470
533
|
const component = changed.component;
|
|
471
534
|
clearTimeout(component.addHandler);
|
|
@@ -516,6 +579,7 @@ let SpineSystem = class SpineSystem extends Renderer {
|
|
|
516
579
|
container.addChildAt(armature, 0);
|
|
517
580
|
/** 保证第一帧显示正常 */
|
|
518
581
|
armature.update();
|
|
582
|
+
component._containerManager = (_c = this.renderSystem) === null || _c === void 0 ? void 0 : _c.containerManager;
|
|
519
583
|
component.armature = armature;
|
|
520
584
|
// @ts-ignore
|
|
521
585
|
component.emit('loaded', { resource: component.resource });
|
|
@@ -559,6 +623,8 @@ let SpineSystem = class SpineSystem extends Renderer {
|
|
|
559
623
|
container.removeChild(armature);
|
|
560
624
|
}
|
|
561
625
|
if (component.armature) {
|
|
626
|
+
// 销毁所有挂载到插槽的 GameObject
|
|
627
|
+
component._destroySlotGameObjects();
|
|
562
628
|
component.armature.destroy({ children: true });
|
|
563
629
|
if (!component.keepResource) {
|
|
564
630
|
const res = yield resource.getResource(component.lastResource);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eva/spine-base",
|
|
3
|
-
"version": "2.0.1-beta.
|
|
3
|
+
"version": "2.0.1-beta.39",
|
|
4
4
|
"description": "@eva/spine-base",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/spine-base.esm.js",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"homepage": "https://eva.js.org",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@eva/eva.js": "2.0.1-beta.
|
|
22
|
-
"@eva/plugin-renderer": "2.0.1-beta.
|
|
21
|
+
"@eva/eva.js": "2.0.1-beta.39",
|
|
22
|
+
"@eva/plugin-renderer": "2.0.1-beta.39",
|
|
23
23
|
"@eva/inspector-decorator": "^0.0.5",
|
|
24
24
|
"pixi.js": "^8.17.0"
|
|
25
25
|
}
|