+1
Pending Review

Animation curves??

Sujeto 2 years ago updated by odyssey96 2 years ago 12

Hello everybody! i bought Bolt  some weeks ago and i have recently started to use it.

I want to make my character jump based on an animation curve but i dont know how to get a float of the value over time, if anybody can help me with that it would be awesome! 

And happy new year!! HOHOHOHOHO! (sorry for awful english).

Bolt Version:
Unity Version:
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):
Pending Review

Hi Sujeto! Welcome to the community!

This is very easy in Bolt. Search for the Evaluate unit, then use the inline inspector to edit your animation curve:


The input port is your time, and the output port is the value of the curve at that time. You don't even need to connect the two control ports (arrows) at the top.

+1
Hey! thanks for the reply! I tried to use it but i only got a fraction of the value an is not in real time (dont know if it needs an update or how to use it in this situation), i need the value to be apply to a velocity for a jumping motion (force is good but i want to control the time it takes to reach a certain height) This is the basic idea y had for this i can't make it work.


+1
Hey again! i know what i ask for is not really clear, in playmaker these are the actions i use to make what i want.
For this case the second one is more relevant for me right now, but learn how to sample would be nice too... 

Hey! That's exactly what I am trying to achieve right now. Lazlo pointed only part of the solution and I am stuck now on how to make through the whole curve in one second.

Need to set time to go from 0 to 1 gradually somehow. I know it's easy for true coders out here :)) Could please someone help?

Tried to google how to do it in a regular C# way but couldn't transform the code into Bolt. 


Will post an update if I find it out myself:) 

+1

You'll have to do a little variable work to make this function, as the T input is simply referencing where on the Y axis to pull the value from your curve. So if you put in a static value, it will return a static value (that one spot on your curve).

In order to step through, you'll need to use delta time (time elapsed since last frame) to calculate how much to move through the animation with each frame. Each frame, add delta time to your total elapsed time, then store that off in a variable to use again next frame.

Here's a very simple example, where an upward curve that is 1 unit long and 2 units high is used to move an object from 0 to 2 along the Y axis in world space over the course of 1 second.


If you want the move to happen once, set the curve to clamp (click on the cog at end of your curve). Or set it to loop or ping-pong to get it to repeat endlessly.

Hope that helps!

Thanks for your reply, but I get this illogical "Variable not found" error in state machine's flow graph. 

Variable should be definitely found as Start Event happens before Update Event.

Is it a bug, or State Flow Graphs doesn't support double Lifecycle Events in single graph?

Correct me if I am wrong but looks like I was right about double Event Lifecycles being not supported in State Flow Graphs.

I successfully managed to solve this by resetting Object's variable in Transition State, everytime before reaching State Flow Graph. 

Thank you GhostAegis for your solution.

+1

You got it right, start doesn't do anything in a state flow graph. I did the same thing myself at first. You can handle it either with the On Enter State event or during the transition trigger (as you did).

Oohh that's right, forgot about On Enter State:)

+2

Not sure if this is of interest, but I made a Execute Over Time unit for this, which starts a coroutine to execute the body which can pass either the time elapsed (0f - Duration) or normalised time (0f - 1f).  Also supports a break condition so that it can skip to 1f normalised time (to interrupt the transition and ensure it finishes in the correct state).


Just doing some testing.


+1

Woah Many thanks to all of you! that was exactly what i was looking for! And Paul Cassaretto that Excecute over time unit looks Amazing! wonder if you would make it available in the future? 


Hey Sujeto,

Sorry been busy lately, create a ExecutionOverTime.cs script and try putting this in, it might help you, others can expand on it if needed

using Bolt;
using Ludiq;
using System.Collections;
using UnityEngine;
namespace Assets.Bolt
{
    [UnitTitle("Execution Over Time")]
    [UnitCategory("Control")]
    class ExecutionOverTime : WaitUnit
    {
        private float outElapsedTime;
        private float outNormalisedTime;
        [DoNotSerialize]
        public ValueInput breakCondition { get; private set; }
        [DoNotSerialize]
        [PortLabel("Unscaled")]
        public ValueInput unscaledTime { get; private set; }
        [DoNotSerialize]
        [PortLabel("Duration")]
        public ValueInput duration { get; private set; }
        [DoNotSerialize]
        [PortLabel("Elapsed Time")]
        public ValueOutput elapsedTime { get; private set; }
        [DoNotSerialize]
        [PortLabel("Normalised Time")]
        public ValueOutput normalisedTime { get; private set; }
        [DoNotSerialize]
        public ControlOutput body { get; private set; }
        protected override void Definition()
        {
            base.Definition();
            duration = ValueInput(nameof(duration), 1f);
            unscaledTime = ValueInput(nameof(unscaledTime), false);
            breakCondition = ValueInput(nameof(breakCondition), false);
            body = ControlOutput(nameof(body)).Repeating();
            elapsedTime = ValueOutput(nameof(elapsedTime), (recursion) =>  outElapsedTime);
            normalisedTime = ValueOutput(nameof(normalisedTime), (recursion) => outNormalisedTime);
            Relation(duration, enter);
            Relation(unscaledTime, enter);
            Relation(enter, body);
            Relation(enter, exit);
        }
       protected override IEnumerator Coroutine(Flow flow)
        {
            var inDuration = duration.GetValue<float>();
            var inUnscaledTime = unscaledTime.GetValue<bool>();
            // used to determine if the loop should break, set by the break condition
            var @break = false;
            outElapsedTime = 0f;
            outNormalisedTime = 0f;
            while (outElapsedTime < inDuration)
            {
                
                outElapsedTime += inUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime;
                outNormalisedTime = Mathf.Clamp(outElapsedTime / inDuration, 0f, 1f);
                // if the break condition is met, set al values as if the loop finished to allow animations etc 
                // to be set to the final position
                if (breakCondition.GetValue<bool>())
                {
                    outElapsedTime = inDuration;
                    outNormalisedTime = 1f;
                    @break = true;
                }
                
                // even if to break, one final invoke to pass the final values down to the execution branch
                // for example if animations are playing based off of these values, we need to ensure that they receive their
                // final normalised time of 1f
                flow.Invoke(body);
                //now if we were to break, break now,
                if (@break)
                    yield break;
                else
                    yield return null;
                
            }
            Exit(flow);
        }
    }
}