I have time dilation being set to increase by a factor of 3 when I reverse time. Now this works, but only for animations. Movement and rotations are completely unaffected. Does time dilation only affect animations?
How are you setting movement and rotation?
Via C++ Code shown here:
void AGhostlineCharacter::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
timer += DeltaSeconds;
unsigned int newIndex;
if (timer >= 1 / 60) //Capture Player Information 60 times a second
{
if (!timeReversing) playerTransformInfo.push_back(this->GetTransform());
else if (playerTransformInfo.size() > 0) //We cannot continue to reverse time if the list is empty
{
newIndex = playerTransformInfo.size() - 1; //The very last element of the list
this->SetActorTransform(playerTransformInfo[newIndex]); //Set Player Transform equal to the last transform in the list
//We need to remove an element from the list
playerTransformInfo.pop_back();
}
else
{
timeReversing = false;
UGameplayStatics::SetGlobalTimeDilation(GetWorld(), 1.0f);
}
timer = 0; //Reset timer
}
}
Well, SetActorTransform is instantaneous so it’s not going to be interpolated. What is you intended behavior?
Basically to rewind time whenever the left mouse button is held down. Time resumes when let go.
When time is rewinding, all the past actions should be sped up by a factor of 3 and the above code just reverses all transform information that was stored.
Should I be using some form of Lerp function between the current position and playerTransformInfo[newIndex]?
Remember that SetGlobalTimeDilation will not make the actors tick more often, it will just increase the DeltaSeconds value, so you will execute that process 60 times per sec whether the Dilation is set to 1 or 100
If you want to have those transforms applied faster you will need a different approach. Unless the Dilation is less than 1
if (timer >= 1 / 60)
will execute pretty much every frame. But if you increase it over 1, it will still only execute once.
Consider using a loop to process multiple transforms per single tick
Try something like this
void AGhostlineCharacter::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
float CaptureRate = 1.0f / 60;
timer += DeltaSeconds;
unsigned int newIndex;
while(timer >= CaptureRate) // Instead of if(timer >= 1/60)
{
... // Your processing here
timer -= CaptureRate; // Instead of timer = 0;
}
}
Edit:
Changed from
float CaptureRate = 1/60;
That just results in the game being stuck in an infinite loop from the first tick.
Hmm, so how would I process more than one transform per tick when the transform will only change once per tick?
Can you paste your code? Because I tried it and it definitely didn’t result in an infinite loop.
Use a loop, like in the example I gave you
Sure, here it is:
void AGhostlineCharacter::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
timer += DeltaSeconds;
float CaptureRate = 1 / 60;
unsigned int newIndex;
while(timer >= CaptureRate) //Capture Player Information 60 times a second
{
if (!timeReversing) playerTransformInfo.push_back(this->GetTransform());
else if (playerTransformInfo.size() > 0) //We cannot continue to reverse time if the list is empty
{
newIndex = playerTransformInfo.size() - 1; //The very last element of the list
this->SetActorTransform(playerTransformInfo[newIndex]); //Set Player Transform equal to the last transform in the list
//We need to remove an element from the list
playerTransformInfo.pop_back();
}
else timeReversing = false;
timer -= CaptureRate; //Reset timer
}
}
I can’t really see anything wrong with it, but maybe I’m just not thinking today.
Ah, must have copied the lines wrong, or changed it by mistake. it was supposed to be
float CaptureRate = 1.0f / 60;
and not
float CaptureRate = 1 / 60;
Edit:
Updated the original code as well
Wow, I can’t believe it was that simple! Of course that makes sense.
Thank you very much for your help, I really appreciate it.