cocos / cocos-engine

Cocos simplifies game creation and distribution with Cocos Creator, a free, open-source, cross-platform game engine. Empowering millions of developers to create high-performance, engaging 2D/3D games and instant web entertainment.
https://www.cocos.com/en/creator
Other
8.23k stars 1.94k forks source link

Support for spine with shared image #17711

Open MrcSnm opened 2 weeks ago

MrcSnm commented 2 weeks ago

Use Case

Currently, I've noticed cases that I have multiple spine files, but they all share the same .atlas files (images included)

I have been trying to find where I could contribute with that feature, since it is basically supplying a different atlas text path, but I didn't find anywhere I could hook up the editor importer.

Problem Description

The problem is that currently, when cocos detects a spine json file, it attempts to load ${fileName}.atlas and its associated images.

Proposed Solution

The editor can provide in the Inspector, a space for an alternative path for an atlas file, which is loaded at both editor and runtime when assigning that skeleton data

How it works

image Provide a property with an alternate atlas load path

Alternatives Considered

I have tried building a SkeletonData by using a TextAsset and a JsonAsset. The problem is that technique doesn't load the images defined inside the TextAsset and thus, it doesn't render anything

Additional Information

No response

MrcSnm commented 2 weeks ago

If anyone is willing to send me where I could hook up and add that property, I could also submit the PR myself

bofeng-song commented 2 weeks ago

Maybe you can try this: SkeletonData asset = new SkeletonData(); asset.skeletonJson = jsonFilePath; asset.atlasText = atlasTextFilePath;

and then call asset.getRuntimeData

MrcSnm commented 2 weeks ago

@bofeng-song So, to create the SkeletonData, you're still missing some points:


    @property([Texture2D])
    texturesUsed: Texture2D[] = [];

    @property(TextAsset)
    atlasDefinition: TextAsset;

    @property(TextAsset)
    skeletonAnimationsDefinition: TextAsset;

    spine: sp.Skeleton;

    protected onLoad(): void {

        const comp = this.spine =  this.getComponent(sp.Skeleton);
        const asset = new sp.SkeletonData();
        asset.atlasText = this.atlasDefinition.text;
        asset.skeletonJson = this.skeletonAnimationsDefinition.text;
        asset.textures = this.texturesUsed
        asset.textureNames = this.texturesUsed.map((v) => v.name);
        asset._uuid = this.skeletonAnimationsDefinition.name; // Any string can be passed in, but it cannot be empty.
        comp.skeletonData = asset;
    }

With that code, you can share the same atlas. If you don't create properties for the textures, cocos won't load them and no animation would be visible.

Another thing is that the problem is you can't design at scene when you're doing like this. If you make it load on the editor, the editor assigns a "Missing Asset", causing an error at runtime.