Jump to content

loodakrawa

Members
  • Posts

    161
  • Joined

  • Last visited

  • Days Won

    19

Posts posted by loodakrawa

  1. On 13/2/2016 at 8:48 PM, winexploder said:

    Excuse my being dense but I still don't understand it. How do I get the method to call at the right time in the animation?

    You register the methods you want with the EventTriggered event in *SpriterAnimator (as in the examples). Then the library raises the event at the right point during the animation which means you methods get called since you registered them with the event. If you look at the event signature, you'll see that it has a single string argument which represents the event name (as defined in spriter animation) - in other words, your listener method signatures must have a single string argument (again, take a look at the examples).

    If you're still unclear about this - you should probably learn more about C# events.

  2. 7 hours ago, winexploder said:

    Hi,

     

    thanks for the reply but I'm still not quite sure how that works. Just to clarify: This is supposed to work the same way as mecanim animation events, where a particular function is called at a certain frame?

    Pretty much. The C# event is raised by the library when the event in Spriter animation occurs. You just have to register one or more methods to listen to the event (as in the examples).

  3. On 8/2/2016 at 11:15 AM, Kiori said:

    @loodakrawa
    Do you know what the current runtime overhead is?

    I mean i imagine for a system running something like 20 different characters at once, with a implementation based on c# scripts, that can't be cheap.
    But who knows.

    If you have tested or have any experience let me know, I'm interested.

     

    On 8/2/2016 at 1:50 PM, Kiori said:

    I did a quick test with 30 chars, non-moving, animating, it seemed to be alright, but i'd have to check on mobile to be sure.
    I noticed that in your main script "SpriterDotNetBehaviour.cs" you use Update. As per :http://blogs.unity3d.com/2015/12/23/1k-update-calls/
    I did a few tests on how to remove/Improve "updating" everything.
    One solution i did was change it to a coroutine.
    I didn't really get a huge improvement,well kind of, its weird actually, i think the profiler just gave me inconsistent results as usual.
    I've seen coroutines offer massive performance gains before, but who knows.

    Let me know your thoughts.

    Runtime overhead compared to what?

    I've written the library to be as fast as possible (while still having readable code) and reduced memory allocations per frame to virtually zero.

    However, if you have really a lot of animations you might have an impact on the CPU. The usual technique to solve this is caching computation results - like in the SnapshotAnimationDataProvider class. This drastically reduces CPU usage but uses more memory.

    From my testing, the lib performs really well. The only  slow down I noticed is on Android (with > 30 complex animations) and the Profiler pinpointed the ApplySpriterTransform method, or more precisely, various calls to Unity's API inside the method. Unfortunately, I don't know if there's another, more efficient way of achieving the same thing in Unity.

    Regarding coroutines, I don't think it makes much sense to use them here since the overhead of calling Update is probably negligible compared to other processing. But if you get positive improvements, let me know and I'll be more than happy to update the lib.

    Cheers

  4. 11 hours ago, wighawag said:

    Thanks for the info,

    I saw the use of box in the processing method but I thought about box as collision box and thus do not plan to actually draw them. They seemed to me more useful as data to be probed hence the use of name as key. On that note, I am not sure Spriter enforce the absence of duplicated name? I ll have to check that

    Haxe is pretty cool, my version should work on c# too :)

     

     

    Box is supposed to be for collisions. It is up to the derived classes to do something with the ApplyBoxTransform method - not necessarily draw the box. For example, In the Monogame example I'm drawing the boxes because there's nothing better I can do but in the Unity examples, the box is mapped to the native Unity collider and all transforms get applied in the ApplyBoxTransform method. So in other words, that method gets called every frame for each box with the calculated spatial data for it and it's up to the actual implementation to do something meaningful with it.

  5. On 29/1/2016 at 3:20 PM, Tristan said:

    Is there some way to simulate Spriter's pixel art mode using SpriterDotNet? The plugin works so smoothly, but my pixel art animations appear to be using Spriter's smooth sampling.

    I wasn't aware of the existence of the pixel art mode. I'll investigate and try to make it working asap.

     

    On 30/1/2016 at 1:39 AM, wighawag said:

    Hi,

    @Loodakrawa 

    First of all thanks for this implementation in C#. I am porting it to Haxe and already have it passing the tests. I am now in the process of streamlining it and optimizing it. I am also polishing the api and I have got a question regarding the boxData in the FrameData. It is set as a Dictionary with objectId (Int) as keys. 

    Are we suposed to know the objectId to get the box information?

    Would it not be better to get it via name ?

    Or is there any reason why it is like this ?

     

    Another thing that was bugging me is this issue : https://github.com/loodakrawa/SpriterDotNet/issues/41

    it feels like a bug to me.

    If not could you explain why it quits early ?

     

    Thanks

     

    Hi!

    I'm using the id (id == array index in almost all the cases) because I load all the data from the .scml to arrays. I think having the string as key should be pretty much the same (I'm just not sure if all the ObjectInfos in the .scml MUST have a name set) if you have a slightly different data structure. In the end I'm passing the whole ObjectInfo in the processing method.

    I didn't have a chance to take a look at the issue you reported but at first glance it does seem like a bug. I'll investigate it asap.

    Fun fact - my first Spriter implementation was done in Haxe a while ago (although it was significantly different that this one)

    Cheers

  6. 15 hours ago, Thrasher said:

    Awesome! Thanks again. I had missed the FileEntries field. I am now able to successfully swap out all of my character customization assets.

    The one thing remaining that I'm having some difficulty with is that the swapped sprite is using the sprite pivot from the original sprite. For example, if I swap hairstyle05 for hairstyle_default (which has a centered pivot of 0.5, 0.5) then the center of hairstyle05 will be on the center of hairstyle_default regardless of the pivot point set for hairstyle05. This becomes an issue anytime the swapped sprite is a different size than the default and I want to alight a non-center point with the center of the sprite being replaced. 

    If I'm working in the Unity Editor and simply drag hairstyle05 onto the spriterenderer associated with hairstyle_default everything lines up just fine. However, when I swap these sprites using SwapSprite(hairstyle_default, hairstyle05) the new hair style is misaligned. Is there a way to have this function as it does natively in the Unity Editor? 

    Thanks,
    James

     

     

    All the positions are calculated based on the information in the .scml file. That means if you swap a sprite with another one, all the transformations still come from the original one. The replacement sprite is just drawn in place of the original one. If you need to swap sprites with ones of a different size at runtime you can probably achieve it by extending the UnitySpriterAnimator and overriding the ApplySpriterTransform method and doing all the custom logic in it.

  7. 16 hours ago, Thrasher said:

    Thanks for the reply. In order to use SwapSprite I need to first find the original sprite (i.e. GameObject.Find("Sprite 5").GetComponent<SpriteRenderer>().sprite). Is there a more efficient way to reference the existing sprite from within SpriterDotNet (by name) to avoid making a GameObject.Find call? If not, is there any guarantee that this sprite will always be "Sprite 5" assuming the base asset in Spriter Pro is never removed or changed?

    Thanks!

    There is no guarantee. These game objects are just temporary containers for the library to fill with current sprites.

    If you need a list of sprites, you can get them in the SpriterDotNetBehaviour.SpriteData field under FileEntries. Keep in mind that a file entry can have either Sprite or AudioClip reference set. Another important thing - the SpriteData is a ScriptableObject which means it is shared between ALL instances.

  8. 6 hours ago, dementedangst said:

    i would like to take advantage of the character map stacking in current dev branch of v1.3.0.,how can i go ahead and get started using it now instead of waiting for an official release.    

    I'm going to create a release in a couple of days.

    However, if you want to try it out before,  do this (assuming you're using Unity): check the dev branch from GitHub, build the SpriterDotNet.sln solution and replace the contents of the SpriterDotNet folder in your project with the contents of the SpriterDotNet.Unity\Assets\SpriterDotNet\ folder in the solution.

     

    4 hours ago, Thrasher said:

    Many thanks, Loodakrawa for the effort you have put into this project. I was able to successfully migrate our project, on Friday, and we are now happily using SpriterDotNet for our enemy animations. w00t!

    I am now working on migrating over our player character which includes a bunch of customization options such as character cosmetics, equipped weapons, equipped armor, etc. Do you or anyone else on this thread have a best practices recommendation on how I should be finding and replacing these sprites in code using SpriterDotNet? 

    Will the numbers assigned to a sprite element change if the .scml file is resaved?

    Thanks,
    James

    Glad to hear you got it working!

    The easiest way of swapping individual sprites is using the SwapSprite (and UnswapSprite) methods of the SpriterAnimator.

    What do you mean by numbers assigned to a sprite element?

  9. 8 hours ago, Maisey said:

    Hi! 

    I'm having some difficulty hunting down an IndexOutOfRangeException Error, and are looking for some guidence.

    I'm by far not a pro at C# and I've just recently started using SpriterDotNet for Unity and I've gotten it all to work. But I get this error on certain animations:

    IndexOutOfRangeException: Array index is out of range.
    (wrapper stelemref) object:stelemref (object,intptr,object)
    SpriterDotNet.SpriterProcessor.GetBoneInfos (SpriterDotNet.SpriterMainlineKey key, SpriterDotNet.SpriterAnimation animation, Single targetTime, SpriterDotNet.SpriterSpatial parentInfo) (at C:/dev/libs/SpriterDotNet/SpriterDotNet/SpriterProcessor.cs:316)
    SpriterDotNet.SpriterProcessor.UpdateFrameData (SpriterDotNet.FrameData frameData, SpriterDotNet.SpriterAnimation animation, Single targetTime, SpriterDotNet.SpriterSpatial parentInfo) (at C:/dev/libs/SpriterDotNet/SpriterDotNet/SpriterProcessor.cs:111)
    SpriterDotNet.AnimationDataProvider.DefaultAnimationDataProvider.GetFrameData (Single time, Single deltaTime, Single factor, SpriterDotNet.SpriterAnimation first, SpriterDotNet.SpriterAnimation second) (at C:/dev/libs/SpriterDotNet/SpriterDotNet/AnimationDataProvider/DefaultAnimationDataProvider.cs:19)
    SpriterDotNet.SpriterAnimator`2[TSprite,TSound].Animate (Single deltaTime) (at C:/dev/libs/SpriterDotNet/SpriterDotNet/SpriterAnimator.cs:234)
    SpriterDotNetUnity.UnitySpriterAnimator.Animate (Single deltaTime) (at Assets/SpriterDotNet/UnitySpriterAnimator.cs:44)
    SpriterDotNet.SpriterAnimator`2[TSprite,TSound].Step (Single deltaTime) (at C:/dev/libs/SpriterDotNet/SpriterDotNet/SpriterAnimator.cs:226)
    SpriterDotNetUnity.SpriterDotNetBehaviour.Awake () (at Assets/SpriterDotNet/SpriterDotNetBehaviour.cs:54)
    UnityEngine.Object:Instantiate(GameObject)
    BossManager:InstantiateBoss() (at Assets/Managers/BossManager.cs:105)
    BossManager:NextBoss() (at Assets/Managers/BossManager.cs:77)

    First of all I made a change in the SpriterDotNetBehaviour.cs and changed the Start function to Awake instead since I was getting null references when trying to listen to animator.AnimationFinished in the Start function of other scripts. So far I have not encounered any problems with this change (I still get the IndexOutOfRangeException when reversing this). Do you know of any further risks for having this in Awake instead of Start?

    If anyone could point me in the right direction that would be awesome! :-)

    Peace!

    EDIT: I've seen others having trouble with negative widths. I have negative scaling (no negative widths) occuring, but I've tried to remove this aswell to no success . :'( 

    Hi.

    I think this is due to a bug I fixed after the version 1.2. I plan to make the next release in the next couple of days and that should take care of the exception you're getting. In the meantime, you can try checking out the dev branch from GitHub and trying with that.

    I guess the Awake method should also be fine. I know I placed the init logic in Start and not Awake for some reason but I can't remember why. I'll take a look and move it there if possible since this causes problems for a number of people.

  10. 5 hours ago, Wledig said:

    Hi, I hope this is the right topic.

    Last year, in March, I made some changes to Spriter2Unity (not Dengar's implementation, but bonus2113's) to make it work with 2DToolkit. However, a few months later, I decided to put my project on hold. I've just resumed (yeah, I'm a lazy guy, I'm usually super motivated for two months and then BAM - it's gone) and I would like to know if somebody is already working on a 2DTK plugin for your implementation? If not, and if I can understand how your implementation works (I haven't looked at it yet), I may try to do it myself. That would help me dust off my poor programming skills.

    A lot has happened since I left and I'm happy to see the Spriter Team has successfully released its Reference Implementation.

    Keep up the good work guys!

    Hi,

    As far as I know, no one is working on that ATM so feel free to do it if you feel like it. I suggest you take a look at the examples and github documentation and you should get a good understanding of how it works. Also, please read CONTRIBUTING.md before starting any work. If you have any questions, feel free to ask me here (or in the Unity plugin thread).

    Cheers

  11. On 12/1/2016 at 10:35 AM, AndyGFX said:

    Hi, 

    yes I tried included example for unity where is set next map from animator entity, but when I use for example 'no_weapon' on my animated character, then all sprites are invisible on character in scene. In Spriter editor when is changed available map to active, then is defined sprites are removed from actor in scene. Works this in code in same logic?

    Second problem is, how can I set multiple maps items on character similar as is set in Sprites editor, when I want hide armor and weapon (drag and drop to column Active).

    In doc missing information what is master map list and where is actual and how works map item  fields. I tried debug array from animator entity, I see all defined maps in character maps list in entity instance, but animator.characterMap is null and when is set to map from entity characterMaps , then doesn't works.

    Maybe a few methods like SetMapActive(name) and SetMapInactive(name) would by nice to have and transparent from user point of view.

     

    Best regards,

    AndyGFX

    I didn't understand your first question - could you rephrase it somehow?

    As for the other issue - I didn't realise Character Maps can stack so I raised an issue and I'll try to fix it asap.

  12. 2 hours ago, AndyGFX said:

    Hi,

    where can I find API doc?

    Currently I looking for a more informations how I can manage characterMap (activate/deactivate parts from map list) from script in runtime.

     

    Andy.

    Hi,

    The documentation is here and here (Unity Specific)  There's a property on SpriterAnimator called CharacterMap which you can set to activate a certain character map. Take a look at the Unity example and/or Monogame example.

    Cheers

  13. 11 hours ago, Dengar said:

    So this seems to have gone by me completely unnoticed. How does this tool compare to my Spriter2Unity?

    It doesn't use MecAnim? I wonder if this is preferable over Spriter2Unity or whether the two tools are so different that different people might prefer one over the other.

    Does it suffer from any of the stupid bugs and issues that Spriter2Unity suffers from?

    Hi.

    In short, the goal of SpriterDotNet is to calculate all transforms in a framework independent way and then just map the transforms to sprites in a concrete framework. Presently, it supports all Spriter features and has no unresolved bugs. Also, it is officially supported by Brashmonkey.

    It doesn't use Mecanim because AFAIK that makes it impossible to use certain Spriter features (different curves, etc). The downside is not having support for the graphic animation state management tools, IK, etc. On the other hand, it offers full control at all times (e.g. modify the animation at runtime).

    I guess the library choice really boils down to whether you need Mecanim support or not.

    If you have any more questions, feel free to ask here or PM me.

    Cheers

  14. On 7/1/2016 at 1:30 PM, illidari said:

    Solved the problem. It seems this function covers all scenarios:

            private string FormatPath(SpriterFile file, string spriterName)
            {
                return String.Format("{0}/{1}", spriterName, file.Name);
            }

     

    I tried your solution and couldn't make it work. Then I remembered why I did it like that: Monogame content loading requires file name without extension. But if this works for you, I suppose you use a different version or have it configured in a different way. Which version do you use?

  15. 20 hours ago, illidari said:

    Solved the problem. It seems this function covers all scenarios:

            private string FormatPath(SpriterFile file, string spriterName)
            {
                return String.Format("{0}/{1}", spriterName, file.Name);
            }

    If you trace the old code, you will see it stripping the folder names from the file name ...and then adding it back on with the folder variable...it works on the example because it changes "folder/file" down to "file" and concatenates "folder/" with "file"

    It broke my program because "folder/subfolder/file" is broken down into "file" and concatenates "folder/" with "file"

    If you just stick with the file name that already knows the folder, you don't need to do any of this or even send the folder variable into the function.

    <spriter_data scml_version="1.0" generator="BrashMonkey Spriter" generator_version="r5" pixel_mode="1">
        <folder id="0" name="male">
            <file id="0" name="male/head/head_front.png" width="68" height="72" pivot_x="0.5" pivot_y="0.5"/>
            <file id="1" name="male/hair_front/hair_base_0.png" width="128" height="116" pivot_x="0.5" pivot_y="0.5"/>
            <file id="2" name="male/torso/chest_front_0.png" width="52" height="64" pivot_x="0.5" pivot_y="0.5"/>
            <file id="3" name="male/torso/pelvis_front_0.png" width="52" height="28" pivot_x="0.5" pivot_y="0.5"/>
            <file id="4" name="male/left_leg/leg_front_0.png" width="32" height="40" pivot_x="0.5" pivot_y="0.5"/>
            <file id="5" name="male/left_leg/leg_front_1.png" width="32" height="40" pivot_x="0.5" pivot_y="0.5"/>
     

     

     

    You are absolutely right. I don't remember why I did it this way - probably just had a brain fart and didn't realise that the whole path is in the file name. I'll fix this with the next commit. Thanks!

  16. On 2/1/2016 at 2:15 PM, illidari said:

    I'm trying to add the RPG Heroes Pack to the program by referencing Male_128.scml

     

     

            private TSprite GetSwappedSprite(TSprite original)
            {
                if (swappedSprites.ContainsKey(original)) return swappedSprites[original];
                return original;
            }

    An unhandled exception of type 'System.ArgumentNullException' occurred in mscorlib.dll

    Additional information: Value cannot be null.

    original is null

     

    A first chance exception of type 'Microsoft.Xna.Framework.Content.ContentLoadException' occurred in MonoGame.Framework.dll
    Missing Asset: RPG_pack_128/male/headgear_front_11   (wrong...should be /male/headgear/headgear_front_11)
    A first chance exception of type 'Microsoft.Xna.Framework.Content.ContentLoadException' occurred in MonoGame.Framework.dll
    Missing Asset: RPG_pack_128/male/helmet_side_11
    A first chance exception of type 'Microsoft.Xna.Framework.Content.ContentLoadException' occurred in MonoGame.Framework.dll
    Missing Asset: RPG_pack_128/male/headgear_back_11
     

     

    It looks like it is failing to handle a folder in a folder.

    SpriterGame.cs is just an example, not a complete solution. This might be caused by a variety of things (how you added the .scml and images to the project, how you registered them in the Content, etc) so I suggest debugging the LoadContent -> RegisterTextures -> FormatPath methods. This should give you a pretty clear idea about what's going on.

  17. On 30/12/2015 at 10:10 AM, AndyGFX said:

    Last time always :(

    In Spriter2UnityDX is changed TextureImporter to TextureImporterType.Sprite for prevent this issue. Is it possible add same feature to Unity SpriterDotNet?

     

    Best regards,

    Andy.

     

    I researched a bit and I don't feel comfortable with this library changing the import settings. You can achieve the same effect by changing the project from 3D to 2D. In 2D mode, all images should be imported as Sprites. As an alternative, you can use this script if you want to enforce a certain way of importing images.

    Cheers

  18. 10 hours ago, WormLice said:

    I tried the GetFrameData method but it doesn't seen to be doing anything at all.
    I'm probably using it wrong, but I'm clueless what is wrong.
    Here's my current code:

    
    if (BodyAnimator.CurrentAnimation.Name.Equals("Attack.W0"))
    {
        Vector2 mousePosition = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
        BodyAnimator.DataProvider.GetFrameData(BodyAnimator.Time, Time.deltaTime, 0.0f, BodyAnimator.CurrentAnimation).SpriteData[5].Angle = Mathf.Acos(mousePosition.x / mousePosition.magnitude);
    }

    SpriteData[5] is the number that my sprite is located when I'm running the program playing my target animation.
    The idea is setting the angle to the mouse position so the sprite always face the mouse.

    If you want to do something like this I suggest extending the DefaultAnimationDataProvider, setting it on the Animator.DataProvider and overriding the GetFrameData method and modifying the data before returning it.

  19. On 21/12/2015 at 10:23 AM, WormLice said:

    A method that plays an animation and make sure the animation is finished playing N times before starting a new one (after calling Play/Transtion again).

    I wasn't very clear, sorry. I meant creating them based on the Sprite image width/height, as an option when importing the scml. That would save a lot of time creating boxes in Spriter.

    Adding some snippets to README.md would be a nice idea.

    It would be useful to change animations dynamically.

    An idea I had recently:
    - Ability to play different animations simultaneously (eg. arm.Play("A0"); body.Play("A1");)

    Just realised I haven't answered yet to this:

    You should be able to achieve that behaviour by using the AnimationFinished event. It gets triggered when a non-looping animation finishes and a looping one loops.

    About boxes - I'll add the option to the importer to generate boxes for every sprite. Cool suggestion!

    I will expand the documentation along with the development but for some things it's much easier to just provide code examples than to actually describe it.

    Changing animations dynamically - I just added support for changing the data source for the animator. Take a look here + the two implementations.

    It is possible to play multiple animations simultaneously but not on such a granular level - only entire animations.

     

    4 minutes ago, WormLice said:

    I'm calling the Transtion method. What I meant is that after quickly switching through them the animation seems plays faster.

    The transition method doesn't reset the current animation on purpose but transitions to the next one from the current time. Otherwise, if you try transitioning from the middle of an animation and it resets immediately it's not smooth - it just "jumps" to the starting point.
    Let me get this straight - are you saying that after a couple of quick transitions the animation just speeds up? Even after you stop transitioning?

  20. 4 hours ago, WormLice said:

    Found a potential issue. The animations seem to not be starting from the beginning after switching to another animation while the current is playing and switching back to the last animation.

    EDIT: Setting Progress to 0.0f before staring a new Animation worked.

    That's exactly what I'm doing when playing a new animation:
    https://github.com/loodakrawa/SpriterDotNet/blob/master/SpriterDotNet/SpriterAnimator.cs#L150

    Did you mean while transitioning (blending from one to the other)?

×
×
  • Create New...