There are two fields available which control when the effect considers itself done. They are Effect.RunEffectUntilTime and Effect.RunEffectUntilValue.
Effect.RunEffectUntilTime takes two floats. Float #1 holds the current time, which starts at zero and counts up (unless time is running backwards, in that case it will start at the end and run to zero). Float #2 holds the time that the effect should end at (which will be the same as Effect.Duration unless you mess with the timescale). The function should return true if we should keep running or false if it’s time to stop.
Effect.RunEffectUntilValue takes three values. They are CurrentValue, StartValue, and EndValue (in that order). StartValue and EndValue are the values that were returned by Effect.RetrieveStart and Effect.RetrieveEnd. CurrentValue is the calculated value after all smoothing effects. It is the same value that was just passed into OnUpdate. This function also returns true to keep running and false to stop.
The majority of your movement effects will probably leave both of these actions as their default value of null. If you leave them null then the effect will run until time runs out. RunEffectUntilTime can be defined to make the effect quit early, or late, or according to any other time based logic you can think of. RunEffectUntilValue is usually used when you have smoothing applied and you want the effect to keep running until the end value is actually reached. If you define both of these at the same time.. well, that’s cute, but only RunEffectUntilValue will be used.
You generally want to define RunEffectUntilValue something like this:
moveEffect.RunEffectUntilValue = (curVal, startVal, endVal) => (endVal - curVal).sqrMagnitude > 16f;
The above block calculates how far we are from our destination at this moment and quits once we are within 4 units (the square root of 16 is 4). We use square magnitude because it avoids calculating the square root, so it runs faster.