UPDATE:
Spoof the pro software engineer released a new version of RLerp!
He mentioned how it is especially useful in games where the critters can move in 6 axis of freedom.
I added this code to my version of Spoof's interpolator below.
~~~
Dear Community,
In this thread I am providing you with an implementation of Spoof's interpolator which allows for interpolations based on game world seconds rather than deltatime.
Precision: This means you can completely control the interpolation and it will not be affected by drops in game frame rate.
Additionally, many of the Unrealscript functions use Alpha, a value between 0 and 1, instead of deltatime, which is inconvenient in pawn/actor classes.
Versatility: Spoof's interpolator resolves this issue.
Lastly, I was encountering some visual flicker using RLerp and RInterpTo, the UnrealScript interpolators.
I modified Spoof's interpolator to get rid of this flicker issue!
My contribution: This was a visual improvement for my game beyond even the unrealscript functions.
Fully functional code sample provided below.
~~~
Interpolators
IF you are not familiar with Interpolators for unrealscript, they are awesome!
They enable you to rotate or move an object over a period of time from one value to another.
this is great for smooth rotation and moving of pawns for example.
They can also be used for blending materials to cause a smooth transition over time.
Here is a list of all the interpolators build into unrealscript already:
http://wiki.beyondunreal.com/UE3:Obj...nterpEaseInOut
~~~
How to Use UnrealScript Interpolators
Here's a sample usage in tick() of an actor (a pawn for example):
Tick runs every frame, so it is running A LOT.
So the above code that sets the actor's rotation is running very fast, with the result of a smooth appearance of motion.
Tick() is always told the following by unrealscript:
deltatime = the time interval in seconds between ticks.
Keep in mind that deltaTime can always be changing, as the resources being used by the computer to render the game change, as well as in-game changes to the scene that cause lower frame rate.
So RInterpTo in the code above says "Set this actor's rotation to some rotation between its current and the PlayerCamera rotation, here is the current time between ticks and here is the desired speed."
If there is a drop in frame rate, deltatime will be larger, as the whole game is running slower so each tick() function call is spaced out further.
This means that the results of RInterpTo in-game are affected by changes in the frame rate of the game; so you cannot exactly know what position the rotating actor will be in at any given time, since its position is not based on game world seconds, but is based on the change in time between ticks
So what if you want to exactly determine how long you want one of these interpolations to last?
And what if you don't want drops in frame rate, which affect delta time in Tick(), to influence how long the interpolation takes?
What if you want to be able to exactly say "at game time 15.7 seconds, the actor will be facing the player camera after having completed a linear interpolation over 3 game seconds to that rotation"
Well!
Now we come to Spoof's awesome interpolator!
I found this forum post by Spoof and decided to fully implement what he was suggesting.
He wrote code that allows for an interpolator based on Game Seconds, rather than relying on just delta time, or an alpha value between 0 and 1.
This means that using his interpolator you can say "I want this interpolation to last 2 seconds and I want the actor at this position at world time 11 seconds"
Spoof: "A completely alternative method, and one I prefer, is to use time to control Alpha directly, using fixed values of A and B. This requires a little extra setup, but is completely deterministic, and automatically supports both delta time and time dilation effects."
~~~
My Implementation of the Spoof Interpolator
This is my version of what Spoof wrote above, that allows for what he is saying, completely "deterministic" linear interpolation where you can exactly know in advance how many game seconds a liner interpolation will take, so after a smooth in-game linear rotation you can know/determine exactly what rotation an actor should have at say game time 12.3 seconds.
My Contribution, No More Flicker:
Even using RLerp I was getting some flicker on my actor that I was rotating, I was using a spawnable static mesh as my actor.
I modified my implementation of Spoof's interpolator to remove the flicker I was experiencing with it as well, the exact same behavior as RLerp, until I made my modification.
~~~
Fully Functional Code to Rotate Actor to Face Camera
For this fully functional code example, whatever actor class you put this code in, each instance of the actor will always rotate to face the player camera over time.
To clarify, you are not putting this in Actor.uc (as per a comment below).
You are putting this code in your custom class that extends some class that extends Actor, like Pawn for example.
Note the global vars below
These are needed because you cannot use SetTimer on a function that has parameters.
http://wiki.beyondunreal.com/UE3:Act...(UDK)#SetTimer
The reason I am using SetTimer is because tick() is for the Actor, and we may not always need to have the Spoof Interpolator running.
So I chose to implement Spoof's code as a timer within the actor class.
The line
Is extreeemely important, otherwise the global vars are changed every tick so the duration is irrelevant.
Note that the "Self." is not required but I use it for clarity.
How to Make This Code Work
This code will work as long as you know how to get your player controller class instance into this Actor's tick(). I can recommend
as a baseline starting point till you have more precise code tailored to your project.
Note this will cycle through all players and the actor in this example will always be looking at the last active playercontroller in the world.
~~~
Thank You Spoof
-If you want to be able to use any of these interpolation functions (http://wiki.beyondunreal.com/UE3:Obj...nterpEaseInOut) for your actors, many of which don't use deltatime but instead use a value between 0 and 1, Spoof's Interpolator is ideal!
-If you want to know exact interpolation positions at exact world times, Spoof's Interpolator is the best!
-And if you want to be free of frame rate drops affecting your in-game interpolations, Spoof's Interpolator is a must.
And finally, my personal favorite:
As a programmer, I want to be able to say "take this many seconds to do this rotation" and know that's what the actor will do.
This is only possible using Spoof's Interpolator which is reliant not on an alpha of 0 to 1, not on random strange ever-changing beast called DeltaTime, but instead on the hard simple concrete fact of actual in-game world seconds.

♥
Rama
Spoof the pro software engineer released a new version of RLerp!
He mentioned how it is especially useful in games where the critters can move in 6 axis of freedom.
I added this code to my version of Spoof's interpolator below.
~~~
Dear Community,
In this thread I am providing you with an implementation of Spoof's interpolator which allows for interpolations based on game world seconds rather than deltatime.
Precision: This means you can completely control the interpolation and it will not be affected by drops in game frame rate.
Additionally, many of the Unrealscript functions use Alpha, a value between 0 and 1, instead of deltatime, which is inconvenient in pawn/actor classes.
Versatility: Spoof's interpolator resolves this issue.
Lastly, I was encountering some visual flicker using RLerp and RInterpTo, the UnrealScript interpolators.
I modified Spoof's interpolator to get rid of this flicker issue!
My contribution: This was a visual improvement for my game beyond even the unrealscript functions.
Fully functional code sample provided below.
~~~
Interpolators
IF you are not familiar with Interpolators for unrealscript, they are awesome!
They enable you to rotate or move an object over a period of time from one value to another.
this is great for smooth rotation and moving of pawns for example.
They can also be used for blending materials to cause a smooth transition over time.
Here is a list of all the interpolators build into unrealscript already:
http://wiki.beyondunreal.com/UE3:Obj...nterpEaseInOut
~~~
How to Use UnrealScript Interpolators
Here's a sample usage in tick() of an actor (a pawn for example):
Code:
Simulated Function tick( Float DeltaTime ) { //rotates this actor to face the player camera Self.SetRotation(RInterpTo(Self.Rotation, PlayerController.Rotation, deltatime, 0.7)); }
So the above code that sets the actor's rotation is running very fast, with the result of a smooth appearance of motion.
Tick() is always told the following by unrealscript:
deltatime = the time interval in seconds between ticks.
Keep in mind that deltaTime can always be changing, as the resources being used by the computer to render the game change, as well as in-game changes to the scene that cause lower frame rate.
So RInterpTo in the code above says "Set this actor's rotation to some rotation between its current and the PlayerCamera rotation, here is the current time between ticks and here is the desired speed."
If there is a drop in frame rate, deltatime will be larger, as the whole game is running slower so each tick() function call is spaced out further.
This means that the results of RInterpTo in-game are affected by changes in the frame rate of the game; so you cannot exactly know what position the rotating actor will be in at any given time, since its position is not based on game world seconds, but is based on the change in time between ticks
So what if you want to exactly determine how long you want one of these interpolations to last?
And what if you don't want drops in frame rate, which affect delta time in Tick(), to influence how long the interpolation takes?
What if you want to be able to exactly say "at game time 15.7 seconds, the actor will be facing the player camera after having completed a linear interpolation over 3 game seconds to that rotation"
Well!
Now we come to Spoof's awesome interpolator!
I found this forum post by Spoof and decided to fully implement what he was suggesting.
He wrote code that allows for an interpolator based on Game Seconds, rather than relying on just delta time, or an alpha value between 0 and 1.
This means that using his interpolator you can say "I want this interpolation to last 2 seconds and I want the actor at this position at world time 11 seconds"
Spoof: "A completely alternative method, and one I prefer, is to use time to control Alpha directly, using fixed values of A and B. This requires a little extra setup, but is completely deterministic, and automatically supports both delta time and time dilation effects."
Code:
var float StartTime, EndTime, A, B; function Go( float inA, float inB, float Duration ) { A = inA; B = inB; StartTime = WorldInfo.TimeSeconds; EndTime = StartTime + Duration; } event Tick() { float t; t = ( EndTime - StartTime ) / ( WorldInfo.TimeSeconds - StartTime ); if ( t >= 1 ) { result = B; // TODO: stop the interpolation } else { result = Lerp( Start, End, t ); } }
My Implementation of the Spoof Interpolator
This is my version of what Spoof wrote above, that allows for what he is saying, completely "deterministic" linear interpolation where you can exactly know in advance how many game seconds a liner interpolation will take, so after a smooth in-game linear rotation you can know/determine exactly what rotation an actor should have at say game time 12.3 seconds.
My Contribution, No More Flicker:
Even using RLerp I was getting some flicker on my actor that I was rotating, I was using a spawnable static mesh as my actor.
I modified my implementation of Spoof's interpolator to remove the flicker I was experiencing with it as well, the exact same behavior as RLerp, until I made my modification.
~~~
Fully Functional Code to Rotate Actor to Face Camera
For this fully functional code example, whatever actor class you put this code in, each instance of the actor will always rotate to face the player camera over time.
To clarify, you are not putting this in Actor.uc (as per a comment below).
You are putting this code in your custom class that extends some class that extends Actor, like Pawn for example.
Note the global vars below
These are needed because you cannot use SetTimer on a function that has parameters.
http://wiki.beyondunreal.com/UE3:Act...(UDK)#SetTimer
The reason I am using SetTimer is because tick() is for the Actor, and we may not always need to have the Spoof Interpolator running.
So I chose to implement Spoof's code as a timer within the actor class.
Code:
// ========= SpoofInterp Vars ========= var Rotator startValue; var Rotator endValue; var Rotator currentValue; var float StartTime, EndTime, DurationTime; var bool SpoofInterpRunning; //spoof's RLerp using quaternions static function Rotator RLerpQuat( Rotator A, Rotator B, float Alpha, bool bShortestPath ) { return QuatToRotator( QuatSlerp( QuatFromRotator( A ), QuatFromRotator( B ), Alpha, bShortestPath ) ); } function startSpoofInterp( rotator inA, rotator inB, float Duration ) { //restarts spoof Interpolater //if run again before SpoofInterp gets to t == 1 DurationTime = Duration; startValue = inA; EndValue = inB; StartTime = WorldInfo.TimeSeconds; EndTime = StartTime + Duration; SetTimer(0.01, true, 'SpoofInterp'); SpoofInterpRunning = true; //could use isTimerActive('SpoofInterp') instead //to always know if SpoofInterp is running } function SpoofInterp() { local float t; //for debugging, lets you know when the actor is in the process //of rotating, and spoofInterp is running successfully `log("time"$WorldInfo.TimeSeconds); //based on current time, decide where the actor should be on //scale of 0 to 1 toward 1 = final destination t = ( WorldInfo.TimeSeconds - StartTime ) / ( DurationTime ); //so if the interp was told to run at gameTime 10 for 2 seconds //and 1 second has elapsed, that means we are halfway to goal //so the interpolation should be at 1/2 = 0.5 using equation above //>= 1 means we are at or beyond the desired duration for this interpolation, so finish if ( t >= 1 ) { currentValue = endValue; ClearTimer('SpoofInterp'); SpoofInterpRunning = false; //not needed if use isTimerActive } else { //replace with other interp func as needed currentValue =RLerpQuat( startValue, EndValue, t ); } //My Contribution //makes effect more smooth visually to exclude fringe values //adjust this depending on the precision required //This is how I removed the flicker I was getting even using RLerp if (Vsize(Vector(Self.Rotation) - Vector(currentValue)) < 0.016) { return; } //update Actor's Rotation/Position SetRotation(currentValue); } function tick(float deltatime) { local Rotator angletoCamera; //if you are extending a class that has tick() contents you need super.tick(deltatime); //get angle between this actor location and the player camera location angletoCamera = Rotator(playercontroller.Location - Self.Location); //if this actor is not facing the camera if(Self.Rotation != angletoCamera){ //start the SpoofInterpolator if(!SpoofInterpRunning){ startSpoofInterp(Self.Rotation, angletoCamera, 1.2); } //the joy of the Spoof Interpolator //is that you can determine exactly how long //you want the interpolation to take //here it is set to take 1.2 seconds; } }
Code:
if(!SpoofInterpRunning){
Note that the "Self." is not required but I use it for clarity.
How to Make This Code Work
This code will work as long as you know how to get your player controller class instance into this Actor's tick(). I can recommend
Code:
ForEach WorldInfo.AllControllers(class'PlayerController', PlayerController) { LocalPlayer = LocalPlayer(PlayerController.Player); }
Note this will cycle through all players and the actor in this example will always be looking at the last active playercontroller in the world.
~~~
Thank You Spoof
-If you want to be able to use any of these interpolation functions (http://wiki.beyondunreal.com/UE3:Obj...nterpEaseInOut) for your actors, many of which don't use deltatime but instead use a value between 0 and 1, Spoof's Interpolator is ideal!
-If you want to know exact interpolation positions at exact world times, Spoof's Interpolator is the best!
-And if you want to be free of frame rate drops affecting your in-game interpolations, Spoof's Interpolator is a must.
And finally, my personal favorite:
As a programmer, I want to be able to say "take this many seconds to do this rotation" and know that's what the actor will do.
This is only possible using Spoof's Interpolator which is reliant not on an alpha of 0 to 1, not on random strange ever-changing beast called DeltaTime, but instead on the hard simple concrete fact of actual in-game world seconds.

♥
Rama
Comment