Page 1 of 1

Unity Daggerfall sprite animation pivots

Posted: Sun Feb 03, 2019 7:39 am
by Craigjw
I am developing a unity game in my spare time and I am using the artwork and animations from Daggerfall.

I have extracted a number of animations into sprite sheets, however for each sprite I have to manually set the pivot, so that the animations don't jump around between frames.

When I extract a sprite sheet and make slices, the pivots for each frame of the animation is arbitrarily set, as the images expand in the X coordinate, the pivot moves relative to the image size and when animated, the image jumps.

I'm not too familiar with the in and outs of the Daggerfall for Unity project and as such, I don't know where the engine is getting it's animation pivots from.

How can I get this information, so that I might be able to automate the process?

Re: Unity Daggerfall sprite animation pivots

Posted: Mon Feb 04, 2019 5:22 pm
by MasonFace
Before you get too carried away, if your project is commercial, you may want to read this first: https://forums.dfworkshop.net/viewtopic.php?f=8&t=1773

However, if you don't plan on profiting from your project, then I think you're fine... (I'm not a lawyer, btw)

TL;DR version: I assume they manually adjusted the pivots, but I don't know that for a fact. It could be programmed to set the pivots with reasonable accuracy, but it would take a fair amount of effort to write the script. You'd most likely be better off manually adjusting them yourself.

Long answer: The vertical location of the pivot should be easy. You should be able to create a script that will set the pivot location to the bottom: https://docs.unity3d.com/ScriptReferenc ... pivot.html

Initialize a Vector2 to hold the pivot location.
Set the pivot.y component to to 0.

This will put the pivot to the bottom of the sprite, and prevent it from jumping around when the sprite changes its vertical dimension.

The horizontal pivot is much harder since you can't really count on any such pixel being the minimum point, like the ground was for our vertical location. The best I know is to get the width of the texture and then set the horizontal pivot location to 1/2 the width. You can get the texture width using this: https://docs.unity3d.com/ScriptReferenc ... width.html

As long as the character's feet are well centered in the frame, it will approximate it well. However, in extreme cases such as when a character is swinging their sword way off to one side, the pivot will be very inaccurate and it will look like it's feet are sliding left and right.

Given some time, I could probably come up with a very heavy handed solution, but I don't think I could get it done before you could manually fix the pivots yourself. Also, there are some cases that it would fail and you'd have to manually touch them up anyway.

Basically, I would use read pixels (https://docs.unity3d.com/ScriptReferenc ... ixels.html) starting from the bottom of the texture to the top and find where it first hits a non-transparent pixel. It would assume this is a foot. Then it would continue reading that row of pixels until it hits more transparent pixels (the end of the foot), then continue to look for more non-transparent pixels (the start of the other foot). If it finds only one foot, continue working up the image until it finds both feet (maybe one foot is raised up slightly higher than the other?). Once you have the pixel location for both feet, find the center of them and set the horizontal pivot to that. Again, there are instances where this could fail (such as when the sprite character doesn't have two feet), but I think it will work for most cases.

I'm not sure how the DFU team did it, but I imagine they just manually adjusted the pivots themselves. Then again, there are some pretty clever folks working on DFU so maybe they found a trick after all.

Anyway, you should only have to run the script once for it to set the pivots, then the script can be removed so it doesn't waste CPU time setting pivots that are already done.

For other sprites like the bat or other flying MOBs, you might be better off trying to compute the approximate center of all the non-transparent pixels, sort of like a "center of mass," and setting the pivot location to that.

That's how I would do it, but there could be much better ways.

-----------------------

After typing all that, I just remember that this will be more complicated since I forgot that these "textures" are just indexed locations on a sprite atlas, so my thoughts may not work like I expected without doing a few more things first... I've already gone into much more detail than I was originally planning on. Just reply with any questions and we'll see if we can work our way through. Just bare in mind that I'm not a profession programmer, and I haven't worked much with atlases.