Jump to content

SpriterDotNet - An implementation for all C# frameworks


loodakrawa

Recommended Posts

Hello :)

I'm using this spriter plugin with Monogame and I can say that it works pretty good for me!

I have a little question and I don't know where to ask it so I'm sorry if it's not the good place: is there an easy way to get the world position of a pixel of an animation?

What I would like to do is to attach a circle collision box that follows the animation of the entity.

Currently the entity that owns the Spriter animator has a getter for position, rotation and scale that looks like that:

class MyEntity : Entity
{
    public virtual Vector2 Position()
    {
        var currentPosition = CurrentAnimator.Position;
        var spriteData = CurrentAnimator.FrameData.SpriteData[0];
        var spriteDataPosition = new Vector2(spriteData.X, -spriteData.Y);

        return currentPosition + spriteDataPosition;
    }

    public virtual float Rotation()
    {
        var spriteData = CurrentAnimator.FrameData.SpriteData[0];
        return MathHelper.ToRadians(-spriteData.Angle);
    }

    public virtual Vector2 Scale()
    {
        var spriteData = CurrentAnimator.FrameData.SpriteData[0];
        return new Vector2(spriteData.ScaleX, spriteData.ScaleY);
    }
}

And my collision circle class looks like that:

class CollisionCircle
{
    private Matrix GetMatrix()
    {
        var scale = Entity.Scale();
        var rotation = Entity.Rotation();
        var position = Entity.Position();

        return
            Matrix.CreateScale(Math.Abs(scale.X), Math.Abs(scale.Y), 1.0f) *
            Matrix.CreateRotationZ(rotation) *
            Matrix.CreateTranslation(position.X, position.Y, 0.0f);
    }

    public Vector2 GetCenter()
    {
        var entityTransformMatrix = GetMatrix();
        var localCenter = _relativePosition;
        var vertexPosition = new Vector3(localCenter.X, localCenter.Y, 0f);
        var transformedVertexPosition = Vector3.Transform(vertexPosition, entityTransformMatrix);
        var worldCenter = new Vector2(transformedVertexPosition.X, transformedVertexPosition.Y);

        return worldCenter;
    }
}

It works as expected, the collision circle follows the animation. But if I update the rotation or the scale of the `CurrentAnimator`, it's not taken into account by the collision circle. I thought that I needed to update the Position() method to transform the `CurrentAnimator.Position` according to the `CurrentAnimator.Rotation`, but it doesn't seem to work :'(

Is there a way to obtain the position that I try to compute using this library directly?

Thanks a lot in advance for your answer :)

 

Link to comment
Share on other sites

23 hours ago, Noxalus said:

Hello :)

I'm using this spriter plugin with Monogame and I can say that it works pretty good for me!

I have a little question and I don't know where to ask it so I'm sorry if it's not the good place: is there an easy way to get the world position of a pixel of an animation?

What I would like to do is to attach a circle collision box that follows the animation of the entity.

Currently the entity that owns the Spriter animator has a getter for position, rotation and scale that looks like that:

...

It works as expected, the collision circle follows the animation. But if I update the rotation or the scale of the `CurrentAnimator`, it's not taken into account by the collision circle. I thought that I needed to update the Position() method to transform the `CurrentAnimator.Position` according to the `CurrentAnimator.Rotation`, but it doesn't seem to work :'(

Is there a way to obtain the position that I try to compute using this library directly?

Thanks a lot in advance for your answer :)

 

Hi,

This is definitely the correct place to ask questions :-)

First of all - If you want to know a specific location from the animation, you should probably use action points.

At the moment, the point transforms are not being converted into MonoGame coordinates (since I didn't know of a use case for this) but your question made me realise there should at least be a generic method that converts transforms from Spriter to MonoGame. I'll implement that asap.

If you need such a functionality in the meantime, you can take a look at the MonogameDebugAnimator. It is piggybacking on the functionality of transforming sprite coordinates to draw action points. If you run the example project and go to the 4th spriter animation ("GreyGuyPlus/player_006") you'll be able to see that in action.

Cheers

Link to comment
Share on other sites

  • 2 weeks later...

Thanks a lot for your answer loodkrawa, that was really helpful for me!

I take this opportunity to ask a new one. I'm new in the animation world, and it's the first time that I try to animate something, so I'm sorry if my question is kind of dumb, but I need to know.

The character that I want to animate is a bell. In one of its animation, I would like that the clapper goes down until it hits the bottom of the screen:

xmas-bell-1.gif

Then, I would like to play another animation, keeping the position of the clapper where it was in the previous animation (so it depends on the distance of the bottom of the screen):

xmas-bell-2.gif

In this new animation, I would like that each time the clapper hits a wall, it goes to the inverse direction, like if there was physics.

Is this possible to do that? If yes, what is the best way to do it?

Thanks you so much for your help!

Link to comment
Share on other sites

 

On 24/11/2016 at 10:10 AM, Noxalus said:

Thanks a lot for your answer loodkrawa, that was really helpful for me!

I take this opportunity to ask a new one. I'm new in the animation world, and it's the first time that I try to animate something, so I'm sorry if my question is kind of dumb, but I need to know.

The character that I want to animate is a bell. In one of its animation, I would like that the clapper goes down until it hits the bottom of the screen:

xmas-bell-1.gif

Then, I would like to play another animation, keeping the position of the clapper where it was in the previous animation (so it depends on the distance of the bottom of the screen):

xmas-bell-2.gif

In this new animation, I would like that each time the clapper hits a wall, it goes to the inverse direction, like if there was physics.

Is this possible to do that? If yes, what is the best way to do it?

Thanks you so much for your help!

 

What you're trying to achieve sounds rather complicated. I can think only of one way of doing this. I haven't done anything similar so this is just a though experiment which will hopefully point you to the right direction.

I'd make the clapper as a separate entity and have a point or collision box on it. The animation would be just the vertical elongation and I'd make it as long as the max possible (screen height?). Then you animate it and detect collisions for that point/collsion box and when it collides stop the animation.

The real problem is how to connect the two animations (bell and clapper). Adding it as a sub-entity  doesn't really help because you need to control it independently. So I guess the only option is to add 2 points to the bell animation - one on top of the bell where the "rope" is anchored and another one somewhere below to indicate the direction of the clapper. That way you can get an angle and set the clapper position accordingly.

And for hitting a wall - detect the clapper point collision with the wall and just reverse the bell animation.

Hope this helps.

Cheers

 

Link to comment
Share on other sites

  • 2 weeks later...

I'm super new to all of this, I came from Unreal's blueprint system and Just moved over to Unity (better support for 2d) I just need to know how on earth do I get the animation I made in spriter to display in the game with a script. I can drag it up in the hierarchy easy enough and see it but when I try to instantiate it in a script I can't get it to show no matter what. Is there anyway we can get a video or a code snippet to show how to do this? (super noob here) 

Link to comment
Share on other sites

15 hours ago, Ashly Berry said:

I'm super new to all of this, I came from Unreal's blueprint system and Just moved over to Unity (better support for 2d) I just need to know how on earth do I get the animation I made in spriter to display in the game with a script. I can drag it up in the hierarchy easy enough and see it but when I try to instantiate it in a script I can't get it to show no matter what. Is there anyway we can get a video or a code snippet to show how to do this? (super noob here) 

How exactly are you trying to instantiate it? Code please

Link to comment
Share on other sites

    void Start () {
        GameObject p = Instantiate(player) as GameObject;
        p.transform.parent = transform;
        

    }

    // Update is called once per frame
    void Update()
    {
        if (animator == null)
        {
            animator = FindObjectOfType<SpriterDotNetBehaviour>().Animator;
            animator.EventTriggered += e => Debug.Log("Event Triggered. Source: " + animator.CurrentAnimation.Name + ". Value: " + e);
        }

public GameObject p;

I did some more digging and it's getting me a nullreferenceException and I already reset the order of my scripts but no dice 

Link to comment
Share on other sites

  • 2 weeks later...
On 06/12/2016 at 7:13 PM, Ashly Berry said:

    void Start () {
        GameObject p = Instantiate(player) as GameObject;
        p.transform.parent = transform;
        

    }

    // Update is called once per frame
    void Update()
    {
        if (animator == null)
        {
            animator = FindObjectOfType<SpriterDotNetBehaviour>().Animator;
            animator.EventTriggered += e => Debug.Log("Event Triggered. Source: " + animator.CurrentAnimation.Name + ". Value: " + e);
        }

public GameObject p;

I did some more digging and it's getting me a nullreferenceException and I already reset the order of my scripts but no dice 

Sorry,  thought I answered you - and today I realised I didn't.

It's a bit hard to figure out what the problem is with just a chunk of code, but my guess is:

animator = FindObjectOfType<SpriterDotNetBehaviour>().Animator;

This finds a SpriterDotNetBehaviour - or to be exact, the first loaded one which is probably not the one you want. I can't really say from your code but I assume the animator is supposed to be on your player object. So just try accessing it like so:

p.GetComponent<SpriterDotNetBehaviour>()

This will at least give you the correct reference to SDNBehaviour.

Hope that helps

Link to comment
Share on other sites

  • 1 month later...

Hi,

I am developing a plugin for Unity, and I want it to be compatible with spriter objects.
I found your plugin which works great, really great effort.

In my plugin I need to fadein/fadeout spriter objects. To do this I can set the alpha of the color of SpriteRenderer component directly, but that would mess up with alpha animation if it exists. So my suggestion is to add a public Color parameter to SpriterDotNetBehaviour, then multiply that SpriterDotNetBehaviour's color including alpha to the color of the UnityAnimator at the line below.

UnityAnimator.cs

renderer.color = new Color(c.r, c.g, c.b, info.Alpha);

The plugin I am creating is Visual Novel for Dialogue System for Unity

Thanks for advance.

Link to comment
Share on other sites

Hello, 

I have imported a spriter object created using Spriter Pro in an empty Unity scene containing only your plugin in the librairy. It created a prefab but when I import it in the scene it is invisible. And I get an error message saying "Missing Asset" for every part of my character. WHen I look at the detail of this error I see:

Quote

Missing Asset: Assets/Tests_Spriter/Character/Arm_L.png
UnityEngine.Debug:Log(Object)
SpriterDotNetUnity.DefaultContentLoader:Load(String) (at Assets/SpriterDotNet/DefaultContentLoader.cs:19)
SpriterDotNetUnity.<LoadAssets>c__Iterator0:MoveNext() (at Assets/SpriterDotNet/SpriterImporter.cs:239)
System.Linq.Enumerable:ToArray(IEnumerable`1)
SpriterDotNetUnity.SpriterImporter:CreateSpriterData(Spriter, String, String) (at Assets/SpriterDotNet/SpriterImporter.cs:89)
SpriterDotNetUnity.SpriterImporter:CreateSpriter(String) (at Assets/SpriterDotNet/SpriterImporter.cs:52)
SpriterDotNetUnity.SpriterImporter:OnPostprocessAllAssets(String[], String[], String[], String[]) (at Assets/SpriterDotNet/SpriterImporter.cs:36)
UnityEditor.AssetPostprocessingInternal:PostprocessAllAssets(String[], String[], String[], String[], String[])

Did I forget to do something before ?

Link to comment
Share on other sites

13 minutes ago, Lother said:

Hello, 

I have imported a spriter object created using Spriter Pro in an empty Unity scene containing only your plugin in the librairy. It created a prefab but when I import it in the scene it is invisible. And I get an error message saying "Missing Asset" for every part of my character. WHen I look at the detail of this error I see:

Did I forget to do something before ?

Perhaps your images are imported as textures. Try to choose all of your images and change the import settings to sprite, then reimport the folder that contains spriter files.

Link to comment
Share on other sites

On 21/01/2017 at 6:13 PM, Stranger Games said:

Hi,

I am developing a plugin for Unity, and I want it to be compatible with spriter objects.
I found your plugin which works great, really great effort.

In my plugin I need to fadein/fadeout spriter objects. To do this I can set the alpha of the color of SpriteRenderer component directly, but that would mess up with alpha animation if it exists. So my suggestion is to add a public Color parameter to SpriterDotNetBehaviour, then multiply that SpriterDotNetBehaviour's color including alpha to the color of the UnityAnimator at the line below.

UnityAnimator.cs


renderer.color = new Color(c.r, c.g, c.b, info.Alpha);

The plugin I am creating is Visual Novel for Dialogue System for Unity

Thanks for advance.

Hi,

The plugin looks very nice - good work!

At the moment I'm really busy so I don't have the time to update SpriterDotNet for Unity. But if you've done it already, please submit a pull request - I'll be more than happy to merge it. (https://github.com/loodakrawa/SpriterDotNet/blob/develop/CONTRIBUTING.md)

Cheers

Link to comment
Share on other sites

  • 3 weeks later...

Visual Novel for Dialogue System for Unity is released. It is the only visual novel asset with builtin support to Spriter animation.

Keep in mind that it requires Dialogue System for Unity to function correctly.

 

On 1/27/2017 at 0:05 AM, loodakrawa said:

Hi,

The plugin looks very nice - good work!

At the moment I'm really busy so I don't have the time to update SpriterDotNet for Unity. But if you've done it already, please submit a pull request - I'll be more than happy to merge it. (https://github.com/loodakrawa/SpriterDotNet/blob/develop/CONTRIBUTING.md)

Cheers

I didn't have time to do it, but I will do it and do a pull request as soon as I have time. Your plugin is great, and I will be happy to contribute to it.

Link to comment
Share on other sites

Edit: I just realized this should be in the "SpriterDotNet.Unity" topic, so I reposted it there. My apologizes.

---

Hello,

First, I'd like to say thank you for this awesome library!

I am creating characters with the RPG Heroes art pack. What I would like to do is have an equipment-less and clothes-less character prefab with full paperdolling and customization support. I would like to dynamically layer the equipment and clothes onto the character while also respecting their origin points during animation. I would also like to dynamically swap out certain textures, such as the skin tones, eyes, ears, hair, ect, while also respecting the origin points during animation.

I read this entire topic to find some info on my problem, and it seems like a few people had the same question, but I wasn't able to figure out a proper solution from the discussions. If you watch the trailer on the RPG Heroes pack @ 1:10, you will notice that it show's support for dynamically changing animations and "changing wardrobe pieces on the fly", with Construct 2 engine. How would I go about that with this Library?

I am new to Spriter, but I think the best course of action is to not re-invent what Spriter already supports, and just dynamically add and remove active character maps that are currently in the "scml" file.

Also, is there support for dynamically changing the color palettes?

Thank you for your time!

 

 

Link to comment
Share on other sites

  • 1 month later...

Hello! Thanks a lot for setting this up! 

We have integrated this into our engine (custom C# .net) and I just had a few questions to make sure we were getting the correct results. Reading through here cleared up some of it but some I was less sure about.

The big thing is making changes to existing animations. I have sprites within the animated spriter object that I would like to effect, like make a turret point to the player, or hide a piece of armor after it has taken so much damage, etc. It seems that I'm able to affect these, in our case for example I can say a thing like

mSprite.FrameData.SpriteData[0].Alpha = 0.0f;

to make the selected sprite disappear, but it doesn't actually go into effect until the next frame. So what I end up seeing is the sprite's properties being "reset" on every keyframe, the sprite reappears, then disappears. After the animation has been completed once, everything looks the way it should. But the really strange thing is that if I reload the stage and the object, the sprite is now invisible from the very beginning, as if I have permanently overwritten what the key frame data was.

Ideally I want a system where I can do something like take a turret and aim it at the player, but then return it to the position that the current animation would point it at later. Is there anything built into the system that would allow something like that? Obviously there's workarounds for this and I think we could probably modify the tool but we wanted to be sure we weren't just doing it wrong first. :)

Also just to confirm:

It sounds like switching a sprite's "slot" to another sprite is similarly not supported?

Referencing specific sprites or parts in the rig (as in my example above) needs to be done via index integer, not by name, correct?

Thanks again! I don't want to sound down on the implementation because it really is cool--seeing these animations come alive in our game is incredible and I'm really grateful for all the time you've put into this.

Link to comment
Share on other sites

6 hours ago, gsilverfish said:

...

Hi,

I'm glad u use this as part of something custom built :-D

Anyway, for the things you want to do - there is a couple of ways of doing this.
Make a sprite invisible:

  • there's a Swap method which you can use to swap the sprite for a transparent one.
  • you can implement your custom IFrameDataProvider and keep the transparency info in it and apply it on the appropriate SpriteObjects (the objects have the animation, entity, folder and file id so you can use that to identify them)
  • you can implement yout custom Animator and kee the transparency info in it and apply it in the ApplyPointTransform method

To make it point to a certain location:

  • have a 360 rotation for the whole thing image and don't call Step on it but just set the Progress on the Animator to get to the exact point in the animation (== rotation) you want
  • pause the animation and just rotate the whole thing
  • if you need the whole thing animated with just one sprite pointed to the player - do something similar to what I described for swapping - keep the overriden position data in you own IFrameDataProvider or Animator

Let me know if I missed something. Also, please let me know how you go with this and how did you end up fixing it because that might be something good to add to the library.

Also, what do you use for rendering?

Cheers

Link to comment
Share on other sites

Just now, loodakrawa said:

Well, that method is for swapping individual sprites with the ones you want - so it's up to the caller to have the desired sprites.

I understand that, but let's say I want to swap the head sprite out with the foot sprite. How do I reference the Animator's sprites to tell it which ones to swap?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...