112 lines
3.4 KiB
TypeScript
112 lines
3.4 KiB
TypeScript
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);
|
||
}
|
||
}
|
||
} |