Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by nicloay · Jan 23, 2014 at 08:03 AM · animationcurvebeziertangent

How to convert cubic Bezier curve into AnimationCurve

I need to transfer animation from 3d party animation software (spine) in to unity. Here is how it looks in spine

alt text

according to this page

The Bézier curve array has 4 elements which define the control points: cx1, cy1, cx2, cy2. The X axis is from 0 to 1 and represents the percent of time between the two keyframes. The Y axis is from 0 to 1 and represents the percent of the difference between the keyframe’s values.

here is what I see in input data

 [ 0.135, 0.74, 0.918, 0.17 ]

and this is cooridnates for P1 = (0.135, 0.74) and P2 = (0.918, 0.17).

for all cases P0 = (0,0), P3 = (1,1)

At unity side, i need to provide outTangent for P0 and inTangent for P3 which is keyframe[0] and keframe[1] in case of curve has just 2 points.

here is my calculation (which doesn't show correct result):

i and nextI is a keyframe indexes of P0 and P3 in AnimationCurve,

tangentArray is json array contains data specified above [cx1,cy1,cx2,cy2]

parseFloat custom method, i can't use default (float)cx1 or float.parse(cx1)

     public static void setCustomTangents(AnimationCurve curve, int i, int nextI, JsonData tangentArray){
         float cx1 = parseFloat(tangentArray[0]);
         float cy1 = parseFloat(tangentArray[1]);
         float cx2 = parseFloat(tangentArray[2]);
         float cy2 = parseFloat(tangentArray[3]);
         float time  = (float)(curve.keys[nextI].time  - curve.keys[i].time);
         float value = (float)(curve.keys[nextI].value - curve.keys[i].value);

         Keyframe thisKeyframe = curve[i];
         Keyframe nextKeyframe = curve[nextI];

         float outTangent =  (cy1 * value)/ (cx1 * time);
         float inTangent = ((1 - cy2) * value)/ ((1 - cx2) * time);

         thisKeyframe.outTangent = outTangent;
         nextKeyframe.inTangent  = inTangent;

         curve.MoveKey(i,      thisKeyframe);
         curve.MoveKey(nextI, nextKeyframe);
     }

This is result in unity alt text

I've already seen some similar bezier questions like The algorithm of curve in Shuriken Particle System. But 2d day can't figure out how to solve this problem, probably because my math skills is low =).

Thanks.

unity_curve.png (28.2 kB)
spinecurve.png (15.6 kB)
Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image HappyMoo · Jan 24, 2014 at 09:31 AM 0
Share

Why are your P0/P3 not at the right positions?

avatar image nicloay · Jan 24, 2014 at 09:35 AM 0
Share

On Unity P0 and P3 is scaled depends of the time and value zoo$$anonymous$$g, because of that original curve can be stretched in the unity curve view.

3 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by SkywardRoy · Jul 25, 2020 at 02:21 PM

The answer by @Ferb was already great, but I wanted to include the option of keyframe weights to cover everything the animation curve can do.

This function builds the points needed for a line renderer to render the animation curve in Ugui. Maybe it's useful for someone else coming across this page.

 private void BuildLine () {
     lineRenderer.Points.Clear();
 
     for (var i = 0; i < animationCurve.length - 1; i++) {
         var start = animationCurve[i];
         var end = animationCurve[i + 1];
         var difference = Mathf.Abs(start.time - end.time);
 
         var startTangentLength = difference;
         var endTangentLength = difference;
         
         if (start.weightedMode == WeightedMode.Out || start.weightedMode == WeightedMode.Both)
             startTangentLength *= start.outWeight;
         else
             startTangentLength /= 3f;
         
         if (end.weightedMode == WeightedMode.In || end.weightedMode == WeightedMode.Both) 
             endTangentLength *= end.inWeight;
         else 
             endTangentLength /= 3f;
         
         var p1 = new Vector2(start.time, start.value);
         var p2 = new Vector2(end.time, end.value);
         
         var c1 = new Vector2(startTangentLength, startTangentLength * start.outTangent);
         var c2 = new Vector2(-endTangentLength, -endTangentLength * end.inTangent);
 
         lineRenderer.Points.Add(p1);
         lineRenderer.Points.Add(p1 + c1);
         lineRenderer.Points.Add(p2 + c2);
     }
 
     var last = animationCurve[animationCurve.length - 1];
     lineRenderer.Points.Add(new Vector2(last.time, last.value));
     
     lineRenderer.SetAllDirty();
 }


Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Medusa-Zenovka · Dec 20, 2020 at 12:35 PM 0
Share

Thank you soo much! This really helped me in converting an AnimationCurve into a bezier curve!

avatar image
2

Answer by Ferb · Jan 23, 2014 at 04:30 PM

I don't really understand how Unity is doing its curves myself - or why it doesn't use plain easy-to-calculate Bezier curves. But this answer gives the following code for going from Unity Animation curves to Bezier curves - that is, getting the vectors for the two control points, c1 and c2, from the endpoints, p1 and p2, and Unity's outtangent and intangent:

 float tangLengthX = Mathf.Abs(p1.x-p2.x)*0.333333f;
 float tangLengthY = tangLengthX ;
 c1 = p1;
 c2 = p2;
 c1.x += tangLengthX ; 
 c1.y += tangLengthY * tgOut; 
 c2.x -= tangLengthX ; 
 c2.y -= tangLengthY * tgIn;


If that's correct (and I don't know whether it is - I can't find any mathematical reference on defining Bezier curves by 'tangent lines', it just seem to be something Unity's creators have dreamt up), you can solve for tgIn and tgOut, which gives:

 tangLength = Mathf.Abs(p1.x-p2.x)*0.333333f;
 tgOut = (c1.y - p1.y)/tangLength;
 tgIn = (p2.y - c2.y)/tangLength;

If that doesn't work, I can only suggest that you construct an animation curve consisting of a few dozen keyframes, as shown here. Then you can evaluate the Bezier curve properly yourself and just force the AnimationCurve to follow it the way you've evaluated it.

Actually, I'm sure that's what you'll have to do. Mathematically, there's no why you can represent cubic Bezier curves properly using just two endpoints and two tangents. To see why, go into your Spine editor (or go here) and make a curve with it's control points in the two corners as shown above, but its first control point somewhere on the bottom axis, and its second control point somewhere on the top axis. That curve has horizontal tangents. Now move those control points horizontally a bit - keep them on the top and bottom axis. The curve changes - but its endpoints and tangents stay the same. There's an infinite number of possible cubic Bezier curves with those same endpoints and tangents - but if its just taking control points and tangents then Unity will only represent a certain one of them, and it probably won't be the one you want.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image nicloay · Jan 23, 2014 at 04:38 PM 0
Share

thanks for your reply. I've seen that post. After it, probably, i do understand what is 0.33333f. Problem is that c1 and c2 is the control points of bezier curve, and x coordinates of these points are hardcoded on unity side for 1/3 of time for c1 and 2/3 of time for c2 of one keyframe. Unfortunately I have different values of x for c1 and c2 in source data, and can't directly calculate tangents for p1 and p2

just for clarification according to my first screenshot and your answers P0 = p1, P1 = c1, P2 = c2, P3 = p2.

avatar image Varaughe · Mar 18, 2014 at 11:47 PM 0
Share

unity animation curve,uses tangents ins$$anonymous$$d of control points,because it's an Hermite curve, the Bezier curve deals with control points,however each hermite has a coresponding bezier,and the coresponding bezier for unity has the control points at 1/3,so when someone's changing in the unity's curve editor the tangents,the control points allways remains at 1/3 of its neigbour ... personally I worked only with bezier, and just calculated the control points out of unity curve's tangents ....but it should be possible to just deal with hermite as well(so only the tangents,nothing about control points), Paulius Liekis explained something somewhere else(I didn't try to verify if it's correct)...and for nicolay, if you have a bezier curve with the given control points ,I'm almost sure you can't have another bezier curve with same shape but with different control points ...I mean in the unity's case,the control points' x coordinates are at 1/3 distance ,and your control points aren't ....

avatar image nicloay · May 23, 2014 at 09:42 PM 0
Share

Varaughe Thanks for reply, You right, there is algorythm to find corresponding points by bezier curve, and I've already done it. but it doesn't work for some cases. when you have control points with p1 with long x position and y with -x. something like that. p1(100000,0) p2(-100000,-10000000)

avatar image
0

Answer by Varaughe · Jul 25, 2020 at 04:55 PM

If you want to see what is the exact equation behind an AnimationCurve, you should check Runtime Curve Editor (from Unity Asset Store). A curve in that package is modeled above an AnimationCurve instance.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

23 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

What is the length of the Keyframe tangent? 0 Answers

How can I set the tangents of Keyframes in an AnimationCurve through scripting? 1 Answer

Tangents ignored while setting keyframes 1 Answer

How can I set my Animation Curve's Tangents to Flat in script? 0 Answers

Tangent for 5th order Bezier curve 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges