-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Import keys/curves missmatch #6
Comments
Hi, Seems it's happening automatically. Taking a look at the source, AnimationBuilder:250 is using AnimationCurve.AddKey(float, float) -- the doc for which says “Smooth tangents are automatically computed for the key.” I'm seeing if I can calculate during import to approximate linear curves. If it works, I'll offer a Pull Request. |
Animation math is not currently part of my skillset. Therefore I just set the tangents to positive infinity. If I knew more about it maybe I would fix it. That being said I'm currently focusing my efforts on extending SpriterDotNet since that tool is currently fully featured. |
Oh hey, didn't realize you'd actually reply! (browser only updated after I updated my post above!) When you say SpriterDotNet is fully featured, does that mean Spirter2UnityDX is deprecated? Can it do the same job? (I'd noticed you'd posted on the prior's thread but got the impression it didn't do all the Mecanim stuff Spriter2UnityDX does -- incorrect?) Thanks for the otherwise great too and replying, btw! |
Currently, Spriter2Unity fills a niche that SpriterDotNet does not. Namely the fact that it converts spriter projects to native Unity animations. SpriterDotNet forgoes that in favor of a more C#-based animation scheme. I am trying to extend SpriterDotNet to add some Unity functionality (like the use of an AnimatorController), but it will never generate actual animations. |
Update: The problem is due to 3 things:
With (1) enabled, the curve becomes a smoothed Cubic curve which results in lovely animations that are just not the same as the defaults in Spriter which uses Linear interpolation by default (although it’s importing as enum value Instantaneous). In my workspace, I've disabled use of (1) and fixed (2). Sadly, I have to pause work on this for now. I will try to post a path / push a repository with these changes in a week or so. Perhaps someone can complete from this start. |
I didn't know that spriterdotnet is being made by the same person than spriter2unitydx. When I had to decide between those 2, I opted for spriter2unitydx becouse it creates animation clips, but it's a shame that it's discontinued. I'm facing the same issue with an animation rotating with strange curves. How can the animator prevent this from spriter at least? |
Spriterdotnet is made by someone else. All I did was add a little animatorcontroller addon. |
If I understand correctly Spriter by default uses linear interpolation between keyframes? At the moment Spriter2UnityDX doesn't define tangent modes for key frames in curves, but this can be fixed using Unity's AnimationUtility. Using it's SetKeyLeftTangentMode and SetKeyRightTangentMode methods. We had problems with couple keys not working as they were in Spriter, mostly with rapid direction changes in animation, and I made a fix for AnimationBuilder. I just iterate the keys through in SetKeys methods and set both tangent modes to linear for each key. Probably a proper fix would need the check the Scml file for the curve type and set the AnimatioCurve tangents based on that. As this fix doesn't support other other than linear curve types from Spriter and I don't know the source code and Spriter well enough I don't want to make a pull request for this. Just wanted to give this information out there if someone was having similar problems and I'm open to help in case of creating a fix for this. |
Here's the solution I found.
Now when I import a scml file, all the curves have linear tangents on both sides. |
If you can make it neat and pretty and make sure it only happens in situations where this is desirable, just make a pull request and I'll merge it. |
If the importer could read and interpret the tangents from scml file, this would not be necessary. Since that's not the case, it's always better to have linear interpolations by default (smooth tangents make highly undesirable behaviors). |
I just mean that it fits into the code without breaking anything and creating behavior that not everyone might desire. And sure the importer could read and interpret that stuff... Just write the code that does it. |
I used the solution from @FedericoCara and works for "weird" imported animations like "skid" (Run N' Gun Platformer Pack\PlayerCharacter\gunner_player_smaller_head.scml). But others like "to_Ladder" and "block_hit" became weird. The problem is the Displayed Sprite value. Its a float number and sometimes don't corresponding to the correct Sprite. And the value of Displayed Sprite is "animating"... For example, from 0 to 2. And the "to_block" and "from_block" animation the sword goes to wrong direction (using or not this solution). I tried change to Quartenion, but I don't understand about curves. Someone knows what to do? Thanks |
I think I did (for my cases). I added an "if" to not enter when DisplayedSprite and m_IsActive: EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip); AnimationCurve animCurve; foreach (EditorCurveBinding curveBinding in curveBindings) { if (curveBinding.propertyName != "DisplayedSprite" && curveBinding.propertyName != "m_IsActive") { animCurve = AnimationUtility.GetEditorCurve(clip, curveBinding); for (int i = 0; i < animCurve.length; i++) { AnimationUtility.SetKeyLeftTangentMode(animCurve, i, AnimationUtility.TangentMode.Linear); AnimationUtility.SetKeyRightTangentMode(animCurve, i, AnimationUtility.TangentMode.Linear); } AnimationUtility.SetEditorCurve(clip, curveBinding, animCurve); } } The other problems, about the rotation ("to_block" and "to_Ladder") I think is an Unity problem. This has nothing to do with importing. |
Another change that help the "to_Ladder" animation. Yet has a strange flip but its nice now. I dont know how to use "instant" (stepped?) in Unity, but people are saying to use "constant"/math.infinite for inTangent and onTangent. I changed the SetKeys function (no Sprite parameter) to this: private void SetKeys (AnimationCurve curve, TimeLine timeLine, Func infoValue, Animation animation) { foreach (var key in timeLine.keys) { //Create a keyframe for every key on its personal TimeLine if (key.curve_type != CurveType.instant) curve.AddKey (key.time, infoValue (key.info)); else curve.AddKey(new Keyframe(key.time, infoValue(key.info), inf, inf)); } var lastIndex = (animation.looping) ? 0 : timeLine.keys.Length - 1; //Depending on the loop type, duplicate the first or last frame if (timeLine.keys[lastIndex].curve_type != CurveType.instant) curve.AddKey (animation.length, infoValue (timeLine.keys [lastIndex].info)); //At the end of the curve else curve.AddKey(new Keyframe(animation.length, infoValue(timeLine.keys[lastIndex].info), inf, inf)); } It's doing like SetKeys for Sprites when curves are "instant". The only problems now:
|
After more testing... Changes I made in SpriterPro animations to work better in Unity:
If in SpriterPro the object has the negative x-scale only to reposition according to the angle, subtract 180 from the angle value and leave the x-scale positive. Thus the sprite will not be deformed in Unity. In the case I think the animation was wrong, because it did not have to "flip" the sword:
If the animation is rotating to the wrong side, it probably would also be in the SpriterPro, which is probably using "instant" (no animation). If you change to "linear" you will see that it goes to the "wrong" side also in SpriterPro. So to solve, I add a new keyframe between the other two. I reposition the bones to the position they should have in that keyframe. I think it will not make a difference to leave "instant" or "linear" in this case. |
This change solved all my problems with z-order: (AnimationBuilder -> GetCurves) Original: if (!rv.ContainsKey (ChangedValues.PositionX) && (defaultInfo.x != info.x || defaultInfo.y != info.y)) { rv [ChangedValues.PositionX] = new AnimationCurve (); //There will be irregular behaviour if curves aren't added for all members rv [ChangedValues.PositionY] = new AnimationCurve (); //in a group, so when one is set, the others have to be set as well rv [ChangedValues.PositionZ] = new AnimationCurve (); } Changed: if (!rv.ContainsKey (ChangedValues.PositionX) && (defaultInfo.x != info.x || defaultInfo.y != info.y) || key.id == 0) { rv [ChangedValues.PositionX] = new AnimationCurve (); //There will be irregular behaviour if curves aren't added for all members rv [ChangedValues.PositionY] = new AnimationCurve (); //in a group, so when one is set, the others have to be set as well rv [ChangedValues.PositionZ] = new AnimationCurve (); } Every first keyframe of each animation will have the position of the object. Slowed the import. |
Hy, so far you made great work with your plugin and you make the work with unity and spriter much easier but the problem is if you scale a bone or sprite inside spriter2d the animation get messed up.
https://brashmonkey.com/forum/applications/core/interface/imageproxy/imageproxy.php?img=http%3A%2F%2Fi.imgur.com%2FWDWfI0U.jpg&key=c1d6736da53dff1efac3ff787d4791143741c2bb7bb3298152c1bbe962f595f5
It would be realy great if you could fix this.
Thank you!
The text was updated successfully, but these errors were encountered: