-
-
Notifications
You must be signed in to change notification settings - Fork 327
fix: add skin support #912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -859,6 +859,62 @@ export default class PixiStage { | |
| } | ||
| } | ||
|
|
||
| public changeSpineSkinByKey(key: string, skin: string) { | ||
| if (!skin) return; | ||
|
|
||
| const target = this.figureObjects.find((e) => e.key === key && !e.isExiting); | ||
| if (target?.sourceType !== 'spine') return; | ||
|
|
||
| const container = target.pixiContainer; | ||
| if (!container) return; | ||
| const sprite = container.children[0] as PIXI.Container; | ||
| if (sprite?.children?.[0]) { | ||
| const spineObject = sprite.children[0]; | ||
| // @ts-ignore | ||
| const skeleton = spineObject.skeleton; | ||
| // @ts-ignore | ||
| const skeletonData = skeleton?.data ?? spineObject.spineData; | ||
| const skinObject = | ||
| // @ts-ignore | ||
| skeletonData?.findSkin?.(skin) ?? | ||
| // @ts-ignore | ||
| skeletonData?.skins?.find((item: any) => item.name === skin); | ||
|
|
||
| if (!skeleton || !skinObject) { | ||
| logger.warn(`Spine skin not found: ${skin} on ${key}`); | ||
| return; | ||
| } | ||
|
|
||
| try { | ||
| // @ts-ignore | ||
| if (typeof skeleton.setSkinByName === 'function') { | ||
| // @ts-ignore | ||
| skeleton.setSkinByName(skin); | ||
| } else { | ||
| // @ts-ignore | ||
| skeleton.setSkin(skinObject); | ||
| } | ||
| } catch (error) { | ||
| // @ts-ignore | ||
| skeleton.setSkin?.(skinObject); | ||
| } | ||
|
|
||
| // @ts-ignore | ||
| if (typeof skeleton.setSlotsToSetupPose === 'function') { | ||
| // @ts-ignore | ||
| skeleton.setSlotsToSetupPose(); | ||
| } else { | ||
| // @ts-ignore | ||
| skeleton.setupPoseSlots?.(); | ||
| } | ||
|
|
||
| // @ts-ignore | ||
| spineObject.state?.apply?.(skeleton); | ||
| // @ts-ignore | ||
| skeleton.updateWorldTransform?.(); | ||
| } | ||
| } | ||
|
Comment on lines
+862
to
+916
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function contains a lot of duplicated code and multiple |
||
|
|
||
| public changeModelExpressionByKey(key: string, expression: string) { | ||
| // logger.debug(`Applying expression ${expression} to ${key}`); | ||
| const target = this.figureObjects.find((e) => e.key === key && !e.isExiting); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -111,9 +111,13 @@ export async function addSpineFigureImpl( | |
| figureSpine.pivot.set(spineCenterX, spineCenterY); | ||
| figureSpine.interactive = false; | ||
|
|
||
| // 检查状态中是否有指定的动画 | ||
| const motionFromState = webgalStore.getState().stage.live2dMotion.find((e) => e.target === key); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| let animationToPlay = ''; | ||
| if (motionFromState?.skin) { | ||
| if (!applySpineSkin(figureSpine, motionFromState.skin)) { | ||
| logger.warn(`Spine skin not found: ${motionFromState.skin} on ${key}`); | ||
| } | ||
| } | ||
|
|
||
| if ( | ||
| motionFromState && | ||
|
|
@@ -277,3 +281,40 @@ export async function addSpineBgImpl(this: PixiStage, key: string, url: string) | |
| await setup(); | ||
| } | ||
| } | ||
|
|
||
| function applySpineSkin(spineObject: any, skinName: string) { | ||
| // @ts-ignore | ||
| const skeleton = spineObject.skeleton; | ||
| // @ts-ignore | ||
| const skeletonData = skeleton?.data ?? spineObject.spineData; | ||
| const skin = | ||
| // @ts-ignore | ||
| skeletonData?.findSkin?.(skinName) ?? | ||
| // @ts-ignore | ||
| skeletonData?.skins?.find((item: any) => item.name === skinName); | ||
| if (!skeleton || !skin) { | ||
| return false; | ||
| } | ||
| try { | ||
| // @ts-ignore | ||
| if (typeof skeleton.setSkinByName === 'function') { | ||
| // @ts-ignore | ||
| skeleton.setSkinByName(skinName); | ||
| } else { | ||
| // @ts-ignore | ||
| skeleton.setSkin(skin); | ||
| } | ||
| } catch (error) { | ||
| // @ts-ignore | ||
| skeleton.setSkin?.(skin); | ||
| } | ||
| // @ts-ignore | ||
| if (typeof skeleton.setSlotsToSetupPose === 'function') { | ||
| // @ts-ignore | ||
| skeleton.setSlotsToSetupPose(); | ||
| } else { | ||
| // @ts-ignore | ||
| skeleton.setupPoseSlots?.(); | ||
| } | ||
| return true; | ||
| } | ||
|
Comment on lines
+285
to
+320
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function duplicates the skin application logic found in /**
* Applies a skin to a Spine object.
* @param spineObject The Spine object to apply the skin to.
* @param skinName The name of the skin to apply.
* @returns True if the skin was successfully applied, false otherwise.
*/
function applySpineSkin(spineObject: any, skinName: string): boolean {
if (!spineObject?.skeleton) {
logger.warn("Spine object has no skeleton.");
return false;
}
const skeleton = spineObject.skeleton;
const skeletonData = skeleton.data || spineObject.spineData;
const skin = skeletonData?.findSkin?.(skinName) || skeletonData?.skins?.find((item: any) => item.name === skinName);
if (!skin) {
logger.warn(`Spine skin not found: ${skinName}`);
return false;
}
try {
if (typeof skeleton.setSkinByName === 'function') {
skeleton.setSkinByName(skinName);
} else {
skeleton.setSkin(skin);
}
} catch (error) {
logger.error(`Failed to set skin ${skinName}:`, error);
skeleton.setSkin?.(skin);
}
if (typeof skeleton.setSlotsToSetupPose === 'function') {
skeleton.setSlotsToSetupPose();
} else {
skeleton.setupPoseSlots?.();
}
return true;
} |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
catchblock only contains a// @ts-ignorecomment and then attempts to set the skin. It would be better to log the error and potentially provide a more graceful fallback, or rethrow the error if it's unrecoverable.