import { _decorator, Component, resources, sp } from 'cc'; import { I18nManager } from '../managers/I18nManager'; const { ccclass, property } = _decorator; /** * 本地化Spine动画组件 * 自动根据当前语言加载对应的Spine动画资源 */ @ccclass('LocalizedSpine') export class LocalizedSpine extends Component { private spineComponent: sp.Skeleton | null = null; @property({ tooltip: 'Spine资源名字' }) private spineName: string = ''; @property({ tooltip: '默认动画名称' }) private defaultAnimation: string = ''; @property({ tooltip: '是否自动播放默认动画' }) private autoPlay: boolean = true; /** * 组件加载时初始化 */ onLoad() { // 获取Spine组件 this.spineComponent = this.getComponent(sp.Skeleton); if (!this.spineComponent) { console.warn(`LocalizedSpine: No Spine component found on node ${this.node.name}`); } // 更新Spine资源 this.updateSpine(); } /** * 更新Spine动画资源 * 先尝试加载当前语言的资源,失败则加载英文默认资源 */ public updateSpine() { if (!this.spineComponent || !this.spineName) return; if (!I18nManager.instance.ready) return; // 尝试加载当前语言资源,失败则加载英文默认资源 this.loadSpine(I18nManager.instance.currentLanguage) } /** * 加载指定语言的Spine资源 * @param language 语言代码 * @returns 是否从缓存中成功加载 */ private loadSpine(language: string): boolean { const cacheKey = `${language}_${this.spineName}`; const cachedSpineData = I18nManager.instance.spineCache.get(cacheKey); // 如果缓存中有资源,直接使用 if (cachedSpineData) { this.setSpineData(cachedSpineData); return true; } // 从resources加载资源 const spinePath = `i18nSpine/${language}/${this.spineName}_${language}`; resources.load(spinePath, sp.SkeletonData, (err, spineData) => { if (!err && spineData) { // 加载成功,添加到缓存并设置Spine数据 I18nManager.instance.spineCache.set(cacheKey, spineData); this.setSpineData(spineData); } else if (language !== 'en') { // 如果不是英文且加载失败,尝试加载英文默认资源 this.loadSpine('en'); } }); return false; } /** * 设置Spine动画数据 * @param spineData Spine动画数据 */ private setSpineData(spineData: sp.SkeletonData) { this.spineComponent.skeletonData = spineData; // 如果设置了默认动画且启用自动播放,则播放默认动画 if (this.defaultAnimation && this.autoPlay) { this.spineComponent.setAnimation(0, this.defaultAnimation, true); } } /** * 设置Spine资源名称并更新 * @param name 资源名称 */ public setSpineName(name: string) { this.spineName = name; this.updateSpine(); } /** * 播放指定动画 * @param animName 动画名称 * @param loop 是否循环播放 */ public playAnimation(animName: string, loop: boolean = false) { if (this.spineComponent) { this.spineComponent.setAnimation(0, animName, loop); } } }