I’m getting some strange results with timelines in my blueprint. I’m using the timeline to add rotation to a cupboard door. I started by creating a float track in the timeline with a length of 1.00 and two keyframes: Key 1 value = 0.0, 0.0 and Key 2 value = 1.0,1.0. I also checked the Use Last Keyframe flag.
I then multiplied this by a public float which I have set to -90 and feed the update into an Add Relative Rotation node.
This made the door rotate by 90 degrees every frame during the one second duration of the timeline which is really odd so I had to lower the float value to -5 to get roughly the correct result. For some reason, reversing the timeline just makes the door rotate another 90 degrees in the same direction so I had to duplicate the timeline for the closing action. No big deal, but I guess it makes sense since I’m multiplying the number by a float (I want to be able to re-use the blueprint for multiple objects so they won’t always be rotating by the same amount).
The biggest problem is that for some strange reason the timelines keep outputting a different value even though they are exact duplicates of each other which means that a very small amount of extra rotation is added to the door every time you use it (It slowly closes more and opens less with each use). I tried using a print screen node to see what the exact values its outputting are but according to the print screen its simply blending between 0 and 1.0 like it should. I even tried clamping the float track between 0 and 1 but this made no difference.
Finally, setting the key interpolation of the two keyframes to constant and then increasing the value of the last frame to 90 actually fixes the problem (it only rotates 90 degrees instead of 90 degrees per frame) but it completely negates the entire purpose of the timeline which is to smoothly transition between the values. I’m very confused.
Here is a screenshot of my event graph and a video showing the slight increase of the rotation with each use:
I’m far from an expert at Unreal, but a few things come to mind.
Your timelines output “blend”, and I’m pretty sure that value goes from 0 the first few frames, to 1 at the last frame. This would result in your problems with always multiplying by 90 not giving the expected result.
Your adding small amounts of rotation, over and over. Floats inherently have a problem called “floating point precision”. Basically it means that exact numbers don’t exist, and you will always have a tiny difference. This adds up when you add a number lots of times.
My suggested solution:
Don’t use add relative rotation every frame, but before starting calculate the end result rotation you want and save that in a local variable, and also save a copy of the rotation before you being in a local variable. Now you can blend between these two values based on “blend”. This should avoid both the problems mentioned.
The problem with my solution: You can’t have multiple of these running on the same object at the same time, as you will need to SET the rotation.
This solution is also not flawless, as it WILL have floating point errors, however as the difference calculation is only done once per time it’s run, it should be negligible unless it’s run many times.
If things only have a fixed set of allowed “end” rotations, you could store those and only need to store the rotation before it begins, guaranteeing that floating point precision won’t be a (noticeable) issue.
Thanks for the suggestions, I’ll admit its all a little over my head. I get that a float isn’t the same as an integer so it can have “leftover numbers” but in all the other tutorials out there detailing how to set up the functionality of a door, this isn’t an issue. Not to mention the issue with setting up the value to be 90 and it applying 90 degrees of rotation every frame. It shouldn’t be doing this.
The “Blend” is just what I decided to name the float track. I could have called it Zamberdeep for all it matters… it has no functionality associated with it. It does in fact go from 0 - 1 as I mentioned in my setup but I fail to see how this would cause any issues? 0.25 * 90 is 22.5 for example which would be applying 22.5 degrees of rotation to the door. It shouldn’t EVER be applying more than that and yet if, as I said, I use a value of 90 for the float, it spins a full 360 degrees at least 20 times in the span of 1 second.
Again, my code isn’t telling the game to add rotation every frame, it SUPPOSED to be telling it to simply add an increasing amount of rotation every frame for 1 second based on the math I’ve provided which it is not doing.
Hi Rudy. I started in 4.8 and thought it might be an issue with that engine version but when I migrated to 4.10 it still persisted so I posted here. I’ll try creating the same setup inside of a new project and let you know the results.
Ok, I’ll try to explain in a different way.
The floating point precision problem i mentioned is the reason -4 wont actually be -4, but could be like -3.999995. Apply small differences lots of times and it adds up.
However your main issue is that your applying increasing rotations every FRAME of the game, not every frame in the timeline! This means that if you were to render 60 frames during one second, the update will activate 60 times, the first with 0, the next with 1/60, the third with 2/60 and so on, towards the end of the second it will be giving out 1. And your adding this together, the sum will be higher then one, thereby causing you issues!
Found this tutorial showing a different way of doing it.
Hi , thanks again for trying to help. I understand the floating point issue, but everyone else is using the same method without the problem I’m experiencing so it seems like it shouldn’t be an issue. Also, if I’m multiplying it by the same amount every time, the result would only be off by a tiny amount - probably less than a single degree of rotation - so it shouldn’t be that noticeable in game. My results are off by a significant amount each time. Also, setting the key frame interpolation to constant completely eliminates the issue so that again doesn’t make sense.
I do find it strange that you can’t create an integer track in a timeline though as this would be a way to avoid the slight variation of a float.
I also understand what you mean by framerate inconsistencies, but where am I increasing the rotation every frame in my blueprint? Is that what update does? I thought its supposed to make it update as time passes in the timeline not every frame. It does seem to be updating every frame, but I didn’t think that was the proper behavior (especially when every tutorial Iv’e watched uses the same mehtod), hence my bug report.
Blending the timeline against a LERP vector is a good idea, but again I’m not sure how this is different than specifying a float. Technically it should function in the exact same way because its just inputting whole numbers into the vector space. I even tried changing my X Y and Z rotation values from floats to integers but this had no affect. I don’t think the float is the issue though.
“As time passes”, in a game time “passes” every time the game calculates a new frame. Therefor the update function is called every frame as expected. Also your adding the rotation to the added rotation, perhaps try setting the rotation instead?
Thank you !!! Apparently I remembered the wrong node from my door tutorials because you were right, SET rotation fixed the issue and when I looked at the tutorials again, they were both using Set rotation (which also made reversing the timeline work. Could you post your reply as an answer so I can mark it as correct?