Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by tiltaghe · Nov 01, 2013 at 04:42 PM · animationcurve

AnimationCurve - Provide the value to find the time?

Hi, I think the question is pretty straightforward

Is it possible to find the time of an AnimationCurve that correspond to a known value between 0 and 1 ?

Albeit there is no documented functions to do that, maybe some maths can help but I can't figure out how

Thanks

Comment
Add comment · Show 3
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 robertbu · Nov 01, 2013 at 05:08 PM 0
Share

AnimationCurves are not functions. Them may be infinite, multiple, one or none positions that match your criteria. Animation curves are made up of an array of keyframes. You would need to test for your value between each pair of $$anonymous$$eyframes. The math to plot the points has been posted several times including:

http://answers.unity3d.com/questions/464782/t-is-the-math-behind-animationcurveevaluate.html

But going the opposite way could be a struggle.

As an alternate suggestion, you could evaluate the curve at many, regular points. That is evaluate 100 even 1000 points. For any two points that bracket your value, you could either assume a line between the points and calculate the approximate 't' value, or you could so a series of evaluations between the two points to refine the projection of 't'.

Note if you were going to be doing this calculation alot, it would pay to evaluate the points once and store them in an array.

avatar image zombience · Nov 01, 2013 at 05:11 PM 0
Share

ah, i see i misunderstood the question. i gave you the opposite of what you want.

avatar image tiltaghe · Nov 01, 2013 at 06:29 PM 0
Share

Thank you for your answers. I have a better understanding of it thanks to yours robertbu.

4 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by SuperPingu · Sep 13, 2019 at 07:30 AM

Your curve need to be strictly monotonic to be able to do that. Otherwise, there could be multi times with the same value. But if it is the case and that your curve is juste piecewise line, you can reverse the curve :

 static AnimationCurve ReverseCurve(AnimationCurve c)
 {
     // TODO: check c is strictly monotonic and Piecewise linear, log error otherwise
     var rev = new AnimationCurve();
     for(int i=0;i<c.keys.Length;i++) {
         var kf=c.keys[i];
         var rkf = new Keyframe(kf.value,kf.time);
         if(kf.inTangent < 0) {
             rkf.inTangent = 1/kf.outTangent;
             rkf.outTangent = 1/kf.inTangent;
         } else {
             rkf.inTangent = 1/kf.inTangent;
             rkf.outTangent = 1/kf.outTangent;
         }
         rev.AddKey(rkf);
     }
     return rev;
 }

It will not work with non piecewise linear curve. In that case, I guess you'll have to use something like a simple bisection method or a fancier Newton's method. Here is the code for bisection method :

 static float TimeFromValue(AnimationCurve c, float value, float precision = 1e-6f)
 {
     float minTime = c.keys[0].time;
     float maxTime = c.keys[c.keys.Length-1].time;
     float best = (maxTime + minTime) / 2;
     float bestVal = c.Evaluate(best);
     int it=0;
     const int maxIt = 1000;
     float sign = Mathf.Sign(c.keys[c.keys.Length-1].value -c.keys[0].value);
     while(it < maxIt && Mathf.Abs(minTime - maxTime) > precision) {
         if((bestVal - value) * sign > 0) {
             maxTime = best;
         } else {
             minTime = best;
         }
         best = (maxTime + minTime) / 2;
         bestVal = c.Evaluate(best);
         it++;
     }
     return best;
 }
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
avatar image
1

Answer by zombience · Nov 01, 2013 at 05:06 PM

If you are using an animation curve in your script, you can just access it through the Evaluate() method.

like so:

 public AnimationCurve anim;
 public float curveIndex;
 public float curveValue;
 
 
 void Update()
 {
     curveIndex = Mathf.Clamp(curveIndex, 0, curve.Length);
     curveValue = anim.Evaluate(curveIndex);
 }


the above code will give you a value "curveValue" in the inspector that is the value of the curve at time "curveIndex".

Comment
Add comment · Show 2 · 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 robertbu · Nov 01, 2013 at 05:11 PM 0
Share

@Zombience - he wants to go the other way...given a value, get back 't' (curveIndex);

avatar image zombience · Nov 01, 2013 at 05:12 PM 0
Share

yup! i need to read more carefully :p

avatar image
1

Answer by Cod3X · Jul 10, 2015 at 08:34 AM

I had faced similar Problem, I was using the curve with 2 key frames

  • one starts at the 0th location of Graph

  • next at 20 towards y axis(Value) "20". 100,000 towards X axis(Time)

the in build API in animation curve Evaluate only based on time to value and this simple trick will help you to find the data other way around

Just loop the time and use the Evaluate until you find your desired Value.

code Example for my problem

 float time = 0;
 float value = 10.0f; 
 public AnimationCurve levelCurve;
 
 IEnumerator RequiredTime(){
 while(true){
 time +=100;
 var sceond = levelCurve.Evaluate(time);
 if(sceond > value + 1f) { 
  Debug.Log(time+" the Timerequired to next level up");  break;
  }
 }            
 yield return null;
 }
 

 

my value was 10 and i want to find the time taken to reach value 11. so that I can use it in my game as a feed back to player the time or progress required to reach next Stage or so.

this is just the sample code for the logic.

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
avatar image
0

Answer by govladi · Apr 29 at 07:18 AM

I'm also on this topic as of now I have something that works, but feel that it's not as optimal as I'd like it to be, here is my simple code so far. (btw I have only to keys and only care about the second one so its hard coded like that feel free to change it as you need)

 private int GetLevelByXP(float experience)
 {
     int level = 1;
 
     for (int i = 0; i < xpReqruirmentPerLevel.keys[1].time; i++)
     {
         if (Expirience < xpReqruirmentPerLevel.Evaluate(i))
         {
             level = i;
             break;
         }
 
     }
 
     return level;
 }
 
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

19 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

Related Questions

preventing animation from tweening 1 Answer

Undocumented property: Keyframe.tangentMode 3 Answers

Animating multiple 2D box colliders 1 Answer

What is the length of the Keyframe tangent? 0 Answers

Intersection Point Between 2 AnimationCurves 0 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