- Düzenlendi
Help wth Spine and Starling AssetManager
Hi there, I was able to get the Spine Starling examples working but I need to be able to use the AssetManager in Starling.
Embedding the assets inline won't work when the app has lots of assets.
I've included my 2 sample projects from FDT and test Spine project
https://dl.dropboxusercontent.com/u/9577607/FDTexports.zip
StarlingSpineSimple - works like the included Starling Examples.
StarlingSpineAssetManagerExample - loads the assets via AssetManager but I get stuck when I try to access the AssetManager while creating SkeletonJson and SkeletonData.
**FDT also shows an error with some of the Math in SkeletonJson.as (see attached png below)
Hard to tell if it's related
Here is a snippet from the StarlingSpineAssetManagerExample project:
var json : SkeletonJson = new SkeletonJson(new StarlingAtlasAttachmentLoader(sAssets.getTextureAtlas("p2-wind-atlas")));
json.scale = 0.5;
var skeletonData : SkeletonData = json.readSkeletonData(sAssets.getObject("p2-wind-json"));
var stateData : AnimationStateData = new AnimationStateData(skeletonData);
skeleton = new SkeletonAnimation(skeletonData, true, stateData);
skeleton.x = 75;
skeleton.y = 900;
addChild(skeleton);
Starling.juggler.add(skeleton);
Thanks in advance for the help.
- Patrick
Is there anyone here that can help me with this?
Thanks
Are there any Starling users here? I'm still stuck on this
Thanks
Sorry for the delayed response.
retropunk yazdıStarlingSpineAssetManagerExample - loads the assets via AssetManager but I get stuck when I try to access the AssetManager while creating SkeletonJson and SkeletonData.
Get stuck? What is the problem? I'm not familiar with Starling's AssetManager, but I'm sure we can figure it out. I imported your projects into Flash Builder but they don't show up as Flash projects. I guess you used FDT.
Kilubu uses AssetManager but I guess StarlingAssetManagerAttachmentLoader is something they wrote.
ok, I imported the examples to FlashBuilder so you can see where I am failing.
https://dl.dropboxusercontent.com/u/9577607/SpineExamplesFB.zip
SpineSimpleExample.zip works using the simple embed solution
SpineStarlingAssetManagerExample.zip uses the StarlingAssetManager to load and create textures and relative objects.
I am not understanding how to apply the loaded Starling objects to the Spine classes. I tried the AttachmentLoader, StarlingTextureLoader and StarlingAtlasAttachmentLoader but only get errors that the Starling objects doesn't exist.
Thanks for the help
- Patrick
Not sure why my FB 4.6 doesn't like your project:
HTTPS desteği olmadığı için görsel kaldırıldı. | Yine de Göster
I ported your code into spine-starling-example. It doesn't work
I get null for anything I try to get out of the asset manager. I guess this is because you call enqueue("assets")
. What is that supposed to do? AFAICT, you need to enqueue each asset so you can get it out later.
I still don't even know what goes wrong for you or what I'm supposed to be looking for. I suggest posting on the Starling forum for how to use AssetManager and other parts of the Starling API.
I only have FB 4.7 available, I only use the latest AIR SDK 14...no Flex
The AssetManager loads the ATLAS, JSON and PNG files and creates their relative objects.
You can access loaded assets like this from the AssetManager
sAssets.getTextureAtlas("p2-wind-atlas") returns the atlas loaded via AssetManager
sAssets.getObject("p2-wind-json") returns the json loaded via AssetManager
For example this works:
[Embed(source = "p2-wind-json.json", mimeType = "application/octet-stream")]
static public const SpineboyJson : Class;
[Embed(source = "p2-wind-atlas.atlas", mimeType = "application/octet-stream")]
static public const SpineboyAtlas : Class;
[Embed(source = "p2-wind-skeleton.png")]
static public const SpineboyAtlasTexture : Class;
private var skeleton : SkeletonAnimation;
public function SpineExample()
{
var attachmentLoader : AttachmentLoader;
var spineAtlas : Atlas = new Atlas(new SpineboyAtlas(), new StarlingTextureLoader(new SpineboyAtlasTexture()));
attachmentLoader = new AtlasAttachmentLoader(spineAtlas);
var json : SkeletonJson = new SkeletonJson(attachmentLoader);
var skeletonData : SkeletonData = json.readSkeletonData(new SpineboyJson());
var stateData : AnimationStateData = new AnimationStateData(skeletonData);
skeleton = new SkeletonAnimation(skeletonData, true, stateData);
addChild(skeleton);
Starling.juggler.add(skeleton);
}
but when I try to assign it like this I get an error that the texture is null
var json : SkeletonJson = new SkeletonJson(new StarlingAtlasAttachmentLoader(sAssets.getTextureAtlas("p2-wind-atlas")));
var skeletonData : SkeletonData = json.readSkeletonData(sAssets.getObject("p2-wind-json"));
var stateData : AnimationStateData = new AnimationStateData(skeletonData);
skeleton = new SkeletonAnimation(skeletonData, true, stateData);
addChild(skeleton);
Starling.juggler.add(skeleton);
I can try posting on Starling too but there dont seem to be any Spine users there...
I hope this is at least clearer
Thanks again
- Patrick
retropunk yazdıbut when I try to assign it like this I get an error that the texture is null
Then post the error. Probably sAssets.getTextureAtlas
returns null because it's not in the asset manager, but I can only guess.
ok so here is where it's at
I get this error
Exception fault: Error: Region not found in atlas: heart (region attachment: heart)
from this code:
var attachmentLoader : AttachmentLoader;
var spineAtlas : Atlas = new Atlas( sAssets.getTextureAtlas("p2-wind-atlas") , new StarlingTextureLoader( sAssets.getTexture("p2-wind-sleleton") ) );
attachmentLoader = new AtlasAttachmentLoader( spineAtlas );
var json : SkeletonJson = new SkeletonJson( attachmentLoader );
var skeletonData : SkeletonData = json.readSkeletonData( sAssets.getObject("p2-wind-json") );
var stateData : AnimationStateData = new AnimationStateData(skeletonData);
skeleton = new SkeletonAnimation(skeletonData, true, stateData);
skeleton.x = 75;
skeleton.y = 900;
addChild(skeleton);
Starling.juggler.add(skeleton);
I've attached my assets too if it helps to review those.
Thanks
Patrick
update
As re-run the code the error changes each timeError: Region not found in atlas: pedal_left (mesh attachment: pedal_left)
Error: Region not found in atlas: middle (region attachment: middle)
Exception fault: Error: Region not found in atlas: heart (region attachment: heart)
Error: Region not found in atlas: pedal middle (region attachment: pedal middle)
seems totally random
Can you inspect with the debugger or otherwise iterate what regions are in sAssets.getTextureAtlas("p2-wind-atlas")
?
I'm not sure what to look for. My experience is still very new with Spine, regions, meshes etc...
Let me try this another way.
I've stripped these projects of any IDE .project info so you can import to any other IDE
https://dl.dropboxusercontent.com/u/957 ... ngHelp.zip
In this ZIP you can see project StarlingSpineSimple. This works great.
This is based off the example in the SpineStarling github repo.
If you open the SWF you can see it works when you click the graphic it animates.
Starlings AssetManager loads all assets and then creates their appropriate references so they can be accessed by a global reference.
The trace from the AssetManager queue looks like this
[AssetManager] Adding byte array 'p2-wind-atlas'
[AssetManager] Adding object 'p2-wind-json'
[AssetManager] Adding texture 'p2-wind-skeleton'
So I set a reference sAssets = AssetManager and I can do this to return the objects from the AssetManager
sAssets.getTextureAtlas( 'p2-wind-atlas' )
sAssets.getObject( 'p2-wind-json' )
sAssets.getTexture( 'p2-wind-skeleton' )
It looks like StarlingAtlasAttachmentLoader and StarlingTextureLoader do the loading too.
Since AssetManager takes care of the loading and creation what can I do to assign the AssetManager references to the Spine objects?
I've tried a few different ways with attached project StarlingSpineAssetManager...
I posted on Starlings forum but no answer yet.
Thank you
- Patrick
Tried to get it to work again, compiles but gives:
http://i.imgur.com/ujGY9mw.png
Running the SWF from the bin folder:
http://i.imgur.com/MI3W2Qm.png
Attached is the project.
I installed FB4.6
Here are 2 FB4.6 Actionscript Mobile projects.
https://dl.dropboxusercontent.com/u/957 ... AIR3.5.zip
** Please Note these use Flex 4.6 with Air 3.5, 3.4 should work just remember to change the Main-app.xml descriptor.
Your project was set to AIR3.1, Starlings minimum version is Air 3.4 /FP 11.4 but recommends the latest SDKs and players
I use AIR 14 ASCompiler 2.0 with Stage 3D, it's incredibly fast on mobile and desktop.
Here is a Windows Flash Projector as a backup so you can at least see the animation when you click on it
https://dl.dropboxusercontent.com/u/957 ... jector.zip
This is what works right now in SpineSimple and should be exactly the same with the Starling AssetManager.
I hope this helps
Thanks again
- Patrick
Hello,
I cannot recall from memory to give u a code snippet which would work right away. But I can give u a hint:
I can see your atlas file has the extension *.atlas. So I assume this atlas was generated by Spine. The Format of this atlas file is different than the xml which Starling / Sparrow expects. So assetManager.getTextureAtlas() will not work. My guess is it will return "null".
Instead I would try "new Atlas( sAssets.getByteArray("p2-wind-atlas") , new StarlingTextureLoader( sAssets.getTexture("p2-wind-sleleton") ) );", if the Atlas class take byteArrays. Otherwise try "sAssets.getByteArray("p2-wind-atlas").readUTF()" instead.
Another way would be to pack the texture atlas with something else than Spine (e.g. TexturePacker). Than u can use assetManager.getTextureAtlas() again. This is what I do.
PS: Answered you on the Starling forum as well
Cheers
Thanks Matulk, your idea worked. I am so grateful...I hope someone else finds this useful. Its huge for me.
I repacked the texures with TexturePacker and then only loaded the json output from Spine.
var json : SkeletonJson = new SkeletonJson( new StarlingAtlasAttachmentLoader( sAssets.getTextureAtlas( "spine-texture" ) ) );
var skeletonData : SkeletonData = json.readSkeletonData( sAssets.getObject( "spine-json" ) );
var stateData : AnimationStateData = new AnimationStateData( skeletonData );
spine-texture is (xml and png) from TexturePacker
spine-json is (skeleton json) from Spine
awesome!
** btw I also updated my spine.starling.SkeletonSprite with this:
polygonBatch.add(image.texture, worldVertices, verticesLength, uvs, triangles, r, g, b, a, slot.data.additiveBlending, matrix);
to this
polygonBatch.add(image.texture.root, worldVertices, verticesLength, uvs, triangles, r, g, b, a, slot.data.additiveBlending, matrix);
See this reference:
viewtopic.php?f=7&t=3193
This reduced my Draw Calls amazingly...26 to 1 !!! WOW!
Thanks again Matulk you've really made my week!
- Patrick
this post should mark as sticky post or included in https://github.com/EsotericSoftware/spi ... /src/spine as an example.
As new Spine-Starling user, it's take me a couple days to find out how to manage Spine as Asset in Starling.
Everyone from as3 use Starling (Stage3D) for optimation, right?
i hope in the future, Spine will have "Starling" as an option when exporting atlas..
thanks matulk for pointed it out that Spine's atlas is different than the xml which Starling expects.
And thanks retropunk for sharing, you all saved my day
An asset loader example is a good idea. Maybe you have an example to post here, or send a PR?
this is example about how to use AssetManager.as
http://wiki.starling-framework.org/manu ... management
i'm still can't find clear solution about how to use Starling's AssetManager with Spine-Starling runtime.
Instead of use TexturePacker, i'd like to use the original Spine's export format. (tight for TexturePacker lol XP)
still trying..
i think it's not a good idea to ask Starling manage Spine's assets
http://forum.starling-framework.org/topic/assetmanager-for-spine
but, since atlas and Texture in Spine and Starling quite different, i think i need make a new AssetManager to manage both starling's and spine's assets.
this's some code i make by using singleton to make easier access the game's assets.
Assets.as
package
{
import flash.utils.Dictionary;
import spine.atlas.Atlas;
import spine.attachments.AtlasAttachmentLoader;
import spine.attachments.AttachmentLoader;
import spine.SkeletonData;
import spine.SkeletonJson;
import spine.starling.StarlingTextureLoader;
import starling.textures.Texture;
import starling.utils.AssetManager;
/**
* ...
* @author zain
*/
public class Assets extends AssetManager
{
private static var instance:Assets;
private static var _assets:AssetManager;
private static var mSkeletonData:Dictionary;
public function Assets(singleton:SingletonEnforcer):void {
_assets = new AssetManager();
mSkeletonData = new Dictionary();
}
/** instance checker */
private static function tryinit():void {
if ( instance == null ) instance = new Assets( new SingletonEnforcer() );
}
[i]public static function enqueue(...rawAssets):void {
tryinit();
_assets.enqueue(rawAssets);
}
public static function loadQueue(onProgress:Function):void {
tryinit();
_assets.loadQueue(onProgress);
}
public static function getTexture(name:String):Texture {
return _assets.getTexture(name);
}[/i]
//{ === region: Spine Assets ===
public static function loadSkeletonData(name:String, textureClass:Class, atlasClass:Class, jsonClass:Class ):void {
tryinit();
if (name in mSkeletonData) {
}else{
var textureLoader:StarlingTextureLoader = new StarlingTextureLoader(new textureClass());
var spineAtlas:Atlas = new Atlas(new atlasClass(), textureLoader);
var attachmentLoader:AttachmentLoader = new AtlasAttachmentLoader(spineAtlas);
var json:SkeletonJson = new SkeletonJson(attachmentLoader);
mSkeletonData[name] = json.readSkeletonData(new jsonClass());
}
}
public static function getSkeletonData(name:String):SkeletonData {
return mSkeletonData[name];
}
//} === endregion: Spine Assets ===
}
}
class SingletonEnforcer
{
//nothing
}
just focus on Spine Assets region.
i'm not use the starling's AssetManager part yet.
this is some test about the SkeletonData part and how to use my Asset's manager
skeleton = new SkeletonAnimation(Assets.getSkeletonData("april"), true);
skeleton.x = 400;
skeleton.y = 560;
skeleton.state.setAnimationByName(0, "walk", true);
skeleton2 = new SkeletonAnimation(Assets.getSkeletonData("april"), true);
skeleton2.x = 800;
skeleton2.y = 560;
skeleton2.state.setAnimationByName(0, "run", true);
addChild(skeleton);
addChild(skeleton2);
Starling.juggler.add(skeleton);
Starling.juggler.add(skeleton2);
and the managed spine's SkeletonData result show nice draw call (only 1 draw call)
i hope this useful :coffee:
Hi Zain, I have been using Spine for my animation data (JSON) and then I use TexturePacker to consolidate my assets XML + PNG/ATF spritesheets).
I use Starlings AssetManager too. It took a few tries to get it working the way I wanted but it's currently working very well.
I'm sure it would be more straight forward to use the ATLAS export from Spine but I actually prefer TexturePacker. TexturePacker gives me the control I need when dealing with TONS of assets. I can export different asset types easily depending on the platform like mutiple ATF types, which is important to my production needs.
When it comes to Starling/Spine projects there hasn't been too much noise on the forums so I'd be happy to share some code if you still need it.
- Patrick
Hi retropunk,
thanks for comeback to this thread again :happy:
as new learner in Spine-Starling, of course i (maybe us*) would like to see your resolved code after using TexturePacker for centralized AssetManager (starling.utils.AssetManager). And i'm sure the TexturePacker mentioned here is not TexturePacker from Spine, right? (just for make sure).
Yes, i knew the TexturePacker commonly used by starling's user.
Just one thing that i really want to know if i use TexturePacker is: is it still possible to use "Meshes" and "Free-form Deformation" feature from Spine in Starling's runtimes?
So, sure i really would like to see your code
i want to compare it
:very excited :rofl: :
thank before~
*) us
see your thread is viewed 2544 times[/i]
[SOLVED for Atlas (no XML) way & No Starling Scaling used]
This way works and you can use the SPINE ATLAS, no need to repack the texture in another program. I needed this and tried this 5 minute ago and it 100% works! By default the spine atlas gets loaded as a byteArray in Starling AssetManager. So just use this code:
// Important Parts:
// assets.getByteArray("spineboy") // Atlas file
// assets.getTexture("spineboy") // PNG file
// assets.getObject("spineboy") // JSON file
// MAKE SURE TO CREATE AN ASSET MANAGER FIRST AND LOAD THESE IN
var attachmentLoader:AttachmentLoader;
var spineAtlas:Atlas = new Atlas(assets.getByteArray("spineboy"), new StarlingTextureLoader(assets.getTexture("spineboy"))); // (atlas, texture)
attachmentLoader = new AtlasAttachmentLoader(spineAtlas);
var json:SkeletonJson = new SkeletonJson(attachmentLoader);
var skeletonData:SkeletonData = json.readSkeletonData(assets.getObject("spineboy")); // json file
skeleton = new SkeletonAnimation(skeletonData);
skeleton.x = 320;
skeleton.y = 420;
skeleton.skeleton.setSlotsToSetupPose();
skeleton.state.setAnimationByName(0, "walk", true);
addChild(skeleton);
Starling.juggler.add(skeleton);
NOTE: If the assetManager has a scale set to it then the spine texture (PNG) comes in at the wrong size (See XML way below).
[SOLVED: XML WAY]
If your project does use scale, I think it's actually quicker and faster (processing wise) to just use the XML option. 2 steps.
1) Create a spritesheet of your Spine images in ShoeBox or TexturePacker (the non-Spine one)
2) With the attachmentLoader, just use the Atlas (png+xml) that the Starling assetManager creates.
Example:
var attachmentLoader:AttachmentLoader;
attachmentLoader = new StarlingAtlasAttachmentLoader(assetsgetTextureAtlas("spineboy")); // The Atlas Starling's assetManager created
var json:SkeletonJson = new SkeletonJson(attachmentLoader);
var skeletonData:SkeletonData = json.readSkeletonData(assetsgetObject("spineboy")); // json file
skeleton = new SkeletonAnimation(skeletonData);
skeleton.skeleton.setSlotsToSetupPose();
skeleton.state.setAnimationByName(0, "walk", true);
addChild(skeleton);
Starling.juggler.add(skeleton);