Download

How to cause for loop to iterate at specified intervals

So I have a very basic function that I’m calling at begin play to test this implementation. I am aiming to display a count from 0 to 29 on the screen in .5 second intervals using the GetWorldTimerManager()

Here is the snippet of my code:


/////////////////////////////////////////////////////////

void AMyCounter::Looper()
{
	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Looper Called")));

		for (int i = 0; i < 30; i++)
		{
			MyNumber = i;

			GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCounter::PickedDelay, .5f, true);
		}
	
	return;
}

void AMyCounter::PickedDelay()
{

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Counter: %d"), MyNumber));
}

When I PIE 29 is displayed on the screen at .5 second intervals but I’m not sure what to alter in order to get the count to start at 0 and go up to 29.

I know it has to be something super simple that I’m just overlooking. Thank you in advance for the help.

1 Like

You’d need to set the timer handle just once (rather than 30 times), and then when PickedDelay is called, increment MyNumber there, and set the timer handle again if you haven’t hit whatever value you’re counting to.

I can’t seem to figure out how to keep the entire for loop from running, I apologize if you alluded to the solution but I changed my code to this and now it runs through the entire loop and then prints it all at once, waits .5 seconds, and then runs through the entire loop and prints it all again. Now granted, I getting the entire loop to print instead of just 29 - so I have that much at least. Is there something else I didn’t get?


void AMyCounter::Looper()
{
	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Looper Called")));

	GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCounter::PickedDelay, .5f, true);

	return;
}

void AMyCounter::PickedDelay()
{

		for (int i = 0; i < 30; i++)
		{
			MyNumber = i;

			GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Counter: %d"), MyNumber));
		}
}

Were you implying that I should put the iterator inside of the SetTimer() call?

Try this:



void AMyCounter::Looper()
{
    GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Looper Called")));

    GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCounter::PickedDelay, .5f, true);

    return;
}

void AMyCounter::PickedDelay()
{
      ++MyNumber; // Increment your counter.
      GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Counter: %d"), MyNumber));
     
     if (MyNumber < 30 ) // Have we reached our total?
     {
         GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCounter::PickedDelay, .5f, true);  // Nope, call this method again in half a second.
     }
}  

1 Like

Ah, getting rid of the for loop entirely worked. I just had to move ++MyNumber and the debug message into the conditional statement. Also, I found out that it works with out the second GetWorldTimeManager() call in the conditional.

Thanks for the help and insight!

it works for me, thanks

void AMyCounter::Looper()
{
    GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Looper Called")));

    GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCounter::PickedDelay, .5f, true);

    return;
}

void AMyCounter::PickedDelay()
{
      ++MyNumber; // Increment your counter.
      GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Counter: %d"), MyNumber));
     
     if (MyNumber < 30 ) // Have we reached our total?
     {
         GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCounter::PickedDelay, .5f, true);  // Nope, call this method again in half a second.
     }
     else
     {
          GetWorldTimerManager().ClearTimer(TimerHandle);
     }
}