Search Unity

LWF - an open-source tool for bringing Flash animation to Unity and HTML5

Discussion in 'Assets and Asset Store' started by Kazuki_Sakamoto, Nov 16, 2012.

  1. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Thank you for your appreciation! You can use multiple atlases for just one LWF data. But it means this LWF data should use DrawMeshRenderer instead of CombinedMeshRenderer because the data uses two or more textures for rendering. It may need many draw-calls. If you don't mind a lot of draw-calls, you can use multiple atlases for one LWF data. If not, you should use just one texture atlas per LWF data.
     
  2. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Thank you for your reply.
    You wouldn't happen to have an example of that would you ? Im not sure how I would go about applying 2 atlases to the LWF format at all. I use the texture packer approach, so yeah, having 2 atlases for separate parts I am a bit confused as to how to implement.

    Thanks for your help
     
  3. kcfy

    kcfy

    Joined:
    Nov 29, 2013
    Posts:
    2
    I'd love to know how to do this too. For me the strengths of the LWF format are that I can format my characters in a way that makes switching between animations seamless and easy, but I'm starting to hit that 2048x2048 limit and I'd like to be able to split things like heads/hands into different atlases.
     
  4. Kazuki Sakamoto

    Kazuki Sakamoto

    Joined:
    Nov 12, 2012
    Posts:
    3
    It's easy. Just put multiple TexturePacker files on the folder.

    cat_atlas1.json
    cat_atlas1.png
    cat_atlas2.json
    cat_atlas2.png
    cat.fla
    cat.swf

    $Screen Shot 2014-04-18 at 3.36.20 PM.png

    But this lwf data needs more draw-calls.
     
  5. kcfy

    kcfy

    Joined:
    Nov 29, 2013
    Posts:
    2
    That seems to work! Textures came out white initially, but appeared properly in the scene view once I'd updated LWF code.

    I didn't realise I could pass in multiple JSON objects to the ruby LWF compiler. That was key:

    Code (csharp):
    1.  
    2. ruby swf2lwf.rb knightanims.swf knightanims.json knightweapons.json
    3.  
    I'm going to have to spend a little more time making things work with NGUI but things are looking good!

    Thanks for all the help, it's much appreciated! It's helped me out a lot.
     
  6. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
  7. leo_chan

    leo_chan

    Joined:
    Jun 11, 2014
    Posts:
    3
    Hi Sakamoto-san,

    Your work on LWF is impressive and your code is readable. Thanks for your contributions to the open source community!

    I'm working on a game where we're placing 2D sprites in a 3D Terrain. The Main Camera is a perspective camera, so I'm getting the z-fighting issues with LWF objects that others have mentioned. One way to fix this would be for me to use a SpriteRenderer
     
  8. dylanbevis

    dylanbevis

    Joined:
    Jan 23, 2014
    Posts:
    4
    This looks like a great tool, does any know if there are any limitations about what platforms supports, I couldn't find anything in the documentation, in particular I'd like to know if it is possible to target consoles with this tool?

    Also I'm assuming it's not easy to use this with Mechanim or has someone worked out a way to make that happen?

    Cheers
     
  9. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Glad to hear that!

    Hmm, i'm not sure SpriteRenderer would fix the problem, but actually i tried to write LWF.SpriteRenderer.

    https://gist.github.com/splhack/db2da47cb279f9dba229

    It seems to need fix some problems. For instance, Matrix to Quaternion conversion problem.
     
  10. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Thanks. There are no limitation for consoles, it works well even on Web Player and iOS.

    You mean you want to control animation of LWF from Mecanim? Hm, I have no idea about that.
     
  11. leo_chan

    leo_chan

    Joined:
    Jun 11, 2014
    Posts:
    3
    It turns out that most of my Z-sort problems went away if I set

    gameObject.camera.transparencySortMode = TransparencySortMode.Orthographic;

    in my Main Camera. Thanks for the SpriteRenderer first pass as well!
     
  12. leo_chan

    leo_chan

    Joined:
    Jun 11, 2014
    Posts:
    3
    Hello again Sakamoto-san,

    After an LWF is loaded and playing, I'd like to be able to replace a movie in it. This is in order to implement swappable items (say a new sword for example) with animation on the item. It would be similar to LWF.Data.ReplaceTexture() but for a movie. What is the best way to do this?

    Many thanks!
    Leo
     
  13. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Hello Leo. AttachMovie or AttachLWF will help you. If you have a lot of swappable items, you would prefer use AttachLWF, but AttachLWF would cause Z-sort problems with CombinedMeshRenderer as you know.
     
  14. yaKashif

    yaKashif

    Joined:
    Sep 1, 2013
    Posts:
    2
    Hi There
    I am just getting started with LWF.
    When I convert swf2lwf using batch_convert I get an error saying "Cant load actioncompiler, please install gem"
    Where can I find this gem?

    Is there any other method of converting swf files to lwf format?
     
    Last edited: Jul 10, 2014
  15. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
  16. yaKashif

    yaKashif

    Joined:
    Sep 1, 2013
    Posts:
    2
    Why didn't I look in the repo :-?

    Anyways, I am very grateful.
    However, I will try LWFS now. It looks good.

    Great work!
     
  17. InabaMizuki

    InabaMizuki

    Joined:
    Jul 18, 2014
    Posts:
    2
    Sorry, can you share more info about skeleton animation?

    I need make all components of character in ONE atlas file, and set it animation from .swf.

    But I just get a spritesheet file of all animation frames, or animation is created from *.bytes but components is scattered(not in one texture).

    How can I do this like you? thank for your time.
     
  18. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Install LWFS and take a look at how to use TexturePacker for creating spritesheet.
    http://discuss.cocos2d-x.org/t/lwf-for-c-with-cocos2d-x-renderer/10257/22?u=splhack

    In fact, you can use any solution for creating spritesheet if the solution generates JSON file and the format of JSON file is the exactly same as TexturePacker one.
     
  19. InabaMizuki

    InabaMizuki

    Joined:
    Jul 18, 2014
    Posts:
    2
    Thanks for your reply, it's work well now. but I have some questions below:

    First, is any way/api to get bound size in unity?

    And, can set game object's anchor point? I try to change it in swf, but always on top left in unity, any way to do this?

    Sorry about bother your time again.
     
    Last edited: Jul 20, 2014
  20. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    LWF Unity implementation doesn't directly have the feature, but it provides LWF.Movie.Inspect API. You can implement the feature using the API like CoffeeScript implementation.

    If you are using LWFObject.FitForHeight and FitForWidth API, Flash coordinate (0,0) will be at Left-Top of the screen exactly like Flash. Please take a look at https://github.com/gree/lwf/issues/75.

    LWFObject.MoveMovie or LWFObject.MoveToMovie will help you. For example, lwfObject.MoveToMovie("_root", 100, 150) will set the anchor point of LWF animation to (100, 150) in Flash coordinate from GameObject coordinate origin.
     
  21. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Hi Kazuki, I have another LWF question.
    Is it possible to attach a movie underneath a movie clip? I have a Primary MovieClip called Hero, he has a weapon sub movieclip called "Weapon"

    When I use AttachMovie it attach on top of the Weapon movie clip, but I wish to attach it behind.
    I've tried the depth settings but without success, does the depth sorting only apply to attached SWF files?
     
  22. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Attached movies and lwfs will be rendered on the target movie and the depth sorting only among attached movies or among attached lwfs. So you may need to create a movieclip called "AttachTargetForWeapon" or something underneath the "Weapon" movie clip.
     
  23. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    That makes perfect sense and it works perfectly.

    I have looked through the documentation, but I couldn't see a way to get the size of a movie clip. Is there a way to get a movie clip width and height, or bounds?
     
  24. Kazuki Sakamoto

    Kazuki Sakamoto

    Joined:
    Nov 12, 2012
    Posts:
    3
    I have added the feature for that! In terms of performance, LWF doesn't calculate the bounds of movie clips. You need to call LWF.Movie.RequestCalculateBounds or LWFObject.RequestCalculateBoundsMovie API for that. Calculating movie clips bounds should be after update state, thus you may need to set callback for getting the bounds. You can get the bounds via Movie.GetBounds API at the callback or later. Movie instances keep the bounds until calling RequestCalculateBounds.

    Code (CSharp):
    1. lwfObject.RequestCalculateBoundsMovie("character", (m) => {
    2.     var b = m.GetBounds();
    3.     Debug.Log(string.Format("{0} {1} {2} {3}", b.xMin, b.xMax, b.yMin, b.yMax));
    4. });
    5.  
     
  25. Kazuki Sakamoto

    Kazuki Sakamoto

    Joined:
    Nov 12, 2012
    Posts:
    3
    Huge updates have come!
    Supported Unity versions:
    • Unity 4.5.x
    • Unity 4.6.x
    • Unity 5.0.x
    Updates:
    • CombinedMeshRenderer now can work with LWF data using multiple textures (the former implementation can only work with LWF data using just one texture).
    • Supported sortingLayerName and sortingOrder in CombinedMeshRenderer for cooperating with Unity 2D Sprite(SpriteRenderer).
    • Added TextMeshRenderer using the new Unity TextGenerator API (that's why LWF requires Unity 4.5 or later).
    • Improved AttachLWF.
    • Added BitmapClip and Lua binding for it.
    • LWFPlayer, BitmapFontRenderer and SystemFontRenderer were now deprecated.
    Happy Hacking! (please write blog articles or something to help for the lack of documents as usual ;))
     
  26. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Great work Kazuki! Ill pull down the latest version and play.
    One of the most time consuming aspects I found was prepping the flash, so I have written a few JSFL scripts that really save me time.

    And a shell script to help automate the process. these are attached:

    Instructions and my current flash workflow from flash into Unity are here
    https://docs.google.com/document/d/1DEwpcZH5JngdB16V_Z7cDdEmtH1YWqzwT1U-fOMeoXc/edit?usp=sharing
    Its WIP so might be a little bit old, but I try to keep it uptodate

    process.sh
    you need to edit the path reference your swf2lwf and texture packer locations. Then just drop into the output directory from the Publish to LWF jsfl script. Run from terminal process.sh and it will automatically generate the texture sheet, and bytes file for unity as well as cleaning up the directory afterwards.

    Some handy JSFL scripts
    ConvertToBitmap.jsfl I actually map to a hot key, and it will convert a layer in a movie clips all to bitmaps keyframe by keyframe

    FindShapes.jsfl goes through all the movies in the librayr and lets you knwo where there are places where there are still shapes ( ie non converted to bitmap items ) makes it much faster to find the areas to fix.

    NameInstance.jsfl renames all instances of a movie clip to a new name based on its Library name. VERY handy if you have nested movie clips and dont want to find each one manually and give it an instance name.
     

    Attached Files:

    Kazuki_Sakamoto likes this.
  27. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Wow! Cool! Thank you for sharing your effort!
     
  28. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Hi Kazuki. I just downloaded the latest version, but it doesnt work for me any more, I have quite a lot of issues.

    here is how I used to create an LWF object, note I also changed the shader so that I can use the tintable shader too. THis no longer works with the latest version

    m_shader = Shader.Find( "LWF/NormalAdditional" );
    m_character = newGameObject( a_instanceName );
    m_clips = a_clips;

    stringtexturePath = a_lwfPath.Substring(0,a_lwfPath.LastIndexOf("/")+1);

    //CreateLWFObject & LoadcorrectAtlases
    m_LWFObject = m_character.gameObject.AddComponent<LWFObject>();
    m_LWFObject.UseCombinedMeshRenderer();
    m_LWFObject.Load( a_lwfPath , texturePath);
    m_LWFObject.AddMovieEventHandler(a_listenerTarget,null,onPostloadCallback,null,onEnterFrameCallback,null,null); //AddListeners
    m_character.renderer.material.shader = m_shader;
     
  29. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    You need to use "LWF/NormalAdditional" shader, right? Could you try the following code?
    Code (CSharp):
    1. m_LWFObject.Load(a_lwfPath, useAdditionalColor:true);
    (texturePath is now automatically set, in the default, the same path as the path of LWF data.)

    Or you want to use your own shader?
     
  30. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Hi Kazuki, yep that loads for me now, thanks.
    I was previously using that shader so I could tint a movie

    publicIEnumeratorHitTints( floata_duration )
    {
    floatwaitTime = 0.016f;
    floatduration = 0;

    while(duration < a_duration )
    {
    m_character.renderer.material.SetColor("_AdditionalColor", newColor(0.88f,0.88f,0.00f,0f)); yieldreturnnewWaitForSeconds(waitTime);

    duration += Time.deltaTime;

    yieldreturnnull;

    }

    //removealltints
    m_character.renderer.material.SetColor("_AdditionalColor", newColor(0f,0f,0f,0.0f));

    }

    But I can no longer access the renderer like I used too. How do I reference the renderer now?
     
  31. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    You can access the renderers of LWFObject via Unity API.

    Code (CSharp):
    1. var components = m_character.gameObject.GetComponentsInChildren<LWF.CombinedMeshRenderer.CombinedMeshComponent>();
    2. if (components != null) {
    3.     foreach (var component in components) {
    4.         // component.meshRenderer
    5.     }
    6. }
    You can also change the colorTransform of movie clips as the following.

    Code (CSharp):
    1. var colorTransform = new LWF.ColorTransform(1, 1, 1, 1, 0.88f, 0.88f, 0, 0);
    2. // Or use C# named arguments
    3. // var colorTransform = new LWF.ColorTransform(addRed:0.88f, addGreen:0.88f);
    4.  
    5. m_LWFObject.SetColorTransform(colorTransform);
    6.  
    7. // You can specify the movie clip like this
    8. // m_LWFObject.SetColorTransformMovie("weapon", colorTransform);
    9.  
     
  32. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    That looks really clean :D but I can't get the first method to work for me:

    I create a reference to the LWFObject using the code below
    Code (CSharp):
    1. m_LWFObject = m_character.gameObject.AddComponent<LWFObject>();
    Code (CSharp):
    1. m_LWFObject.SetColorTransform( newLWF.ColorTransform(1, 1, 1, 1, 0.88f,0.88f,0.00f,0 ) ); yieldreturnnewWaitForSeconds(waitTime);
    I get nothing. What used to work well was
    Code (CSharp):
    1. m_character.renderer.material.SetColor("_AdditionalColor", newColor(0.88f,0.88f,0.00f,0f)); yieldreturnnewWaitForSeconds(waitTime);    
    I might try the other technique next, its just a bit cumberson as I run through about 20 tints with yields between each of them
     
  33. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Code (CSharp):
    1. Component[] components;
    2.         components = m_character.gameObject.GetComponentsInChildren<LWF.CombinedMeshRenderer.CombinedMeshComponent>();
    3.         if (components != null)
    4.         {
    5.                 foreach (LWF.CombinedMeshRenderer.CombinedMeshComponent component in components)
    6.                 {
    7.                 component.meshRenderer.material.SetColor("_AdditionalColor", new Color(0.88f,0.88f,0.00f,0f));
    8.                 }
    9.         }
    I tried this and this didnt work either. So either my implementation, or a bug perhaps?
     
  34. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Oh, I found a problem for getting shader in CombinedMeshRenderer. I have fixed it. Could you try the latest version?

    Code (CSharp):
    1. m_LWFObject.Load(a_lwfPath, useAdditionalColor:true);
    It means the CombinedMeshRenderer uses LWF/NormalCombined shader. It doesn't have _AdditionalColor property.
     
    Last edited: Aug 27, 2014
  35. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    That fixed it.

    I tried the Movie bounds code, but didn't have much success with getting it to work.

    My Implementation (c#)


    publicvirtualvoidonPostloadCallback(LWF.Movie_movie)
    {
    //AddLayers
    Debug.Log ("onPostloadCallback");
    m_container= _movie;
    m_movie_background[0] = m_container.AttachMovie( "Background", "Background");

    m_movie_farground[0] = m_container.AttachMovie( "Farground", "Farground");

    m_movie_midground[0] = m_container.AttachMovie( "Midground", "Midground");

    m_movie_foreground[0] = m_container.AttachMovie( "Foreground", "Foreground");

    m_LWFObject.RequestCalculateBoundsMovie("Background", (m) => {
    LWF.Bounds b = m.GetBounds();
    Debug.Log ("Bounds");
    Debug.Log(string.Format("{0} {1} {2} {3}", b.xMin, b.xMax, b.yMin, b.yMax));
    });

    m_LWFObject.RequestCalculateBoundsMovie("Midground", (m) => {
    LWF.Bounds b = m.GetBounds();
    Debug.Log(string.Format("{0} {1} {2} {3}", b.xMin, b.xMax, b.yMin, b.yMax));
    });

    m_LWFObject.RequestCalculateBoundsMovie("Foreground", (m) => {
    LWF.Boundsb = m.GetBounds();
    Debug.Log(string.Format("{0} {1} {2} {3}", b.xMin, b.xMax, b.yMin, b.yMax));
    });

    m_initialised = true;
    }
     
    Last edited: Aug 27, 2014
  36. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Hmm, RequestCalculateBounds works with any movie clip. For example, you can get the whole bounds of LWF using "_root" instance name.

    Code (CSharp):
    1. m_lwfObject.RequestCalculateBoundsMovie("_root", (m) => {
    2.     var b = m.GetBounds();
    3.     Debug.Log(string.Format("{0} {1} {2} {3}", b.xMin, b.xMax, b.yMin, b.yMax));
    4. });
    How did you do that?
     
  37. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Attached is the way I am attempting to do it.
    I have an empty movie clip in the flash source file I call Container,
    and to that I attach clips from the flash library.

    I'm not sure if thats the right way or not :D, but when I didnt do that it automatically placed on the UNity scene the movie clip that was on the flash stage.
     

    Attached Files:

  38. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    And another bug I have found, is not all the movie clips are rendering now, some of the child movie clips don;t display.
     
  39. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Thank you for the report. I've fixed the problem. Could you use the latest LWF? Also I added AttachEmptyMovie API (no longer need to add an empty movie clip in Flash) and AttachMovie wrapper APIs in LWFObject.
     
  40. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Could you explain more detail how to reproduce the problem? or could you share minimum data?
     
  41. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Here is a project. The spider is missing some of his legs.
    What he should look like ( and what happens in old LWF is attached )
    Also attached is the original FLA so you can see the format
     

    Attached Files:

  42. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Thank you for sharing your project! I've fixed the spider rendering problem. I'm going to investige the shader problem.
     
  43. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    No problem. Thanks for the great work on making it really functional!
     
  44. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    You are welcome!

    Right now, there is one problem in my understanding. On CombinedMeshRenderer, the add parameters of ColorTransform doesn't affect correctly. It seems normalized (because the shader uses "normals") or lack of red color...
     
  45. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Ok, good that you have identified the problem. Is it fixable?
    I would love to upgrade to the latest LWF ( that way I can keep testing as you develop it ) but I do like the older tint effect that I used to get on my shader material only version.
     
  46. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Another question on that shader? Is it depth sorted. I have LWFS on separate game objects, with different depths, but the sorting doesnt seem to work, sometimes the LWF's are in front of each other, sometimes behind.

    Edit: Ic can fix it be manually setting the renderQueue for each LWF "type"
     
    Last edited: Aug 28, 2014
  47. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    Fixed and updated LWF! Could you try the latest one?
     
  48. Kazuki_Sakamoto

    Kazuki_Sakamoto

    Joined:
    Jul 6, 2012
    Posts:
    88
    There are several ways for rendering order.
    • Adjust Z position of LWFObject
    • Use AttachLWF as AttachMovie (In the former AttachLWF implementation, it renders independently, but now the root LWFObject renders all children at once.)
    • Adjust sortingLayerName and sortingOrder of LWFObject
    • Adjust renderQueue of LWFObject
     
  49. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Yeah it looks like its working well. Shader is working well, all the items are rendering.
    I'm using the renderqueue to set depth so all good.

    Nice work.
     
  50. blastone

    blastone

    Joined:
    Apr 7, 2009
    Posts:
    168
    Actually, now the renderQueue isnt as easy as it was before, it needs to be applied to all of the children.
    I'm trying this

    m_LWFObject.Load( a_lwfPath,renderQueueOffset:2);

    Will that work? Hehe, not much documentation :D