Delay on UObjects, multithreading, tasks??

Hey guys, I’m developing a turn-based action system in Unreal 4.27 and I’m making Actions inheriting UObject. It’s an object class with tons of cool functions to simulate an action/skill, such as DamageTargets(), HealTargets(), MoveToTarget() and so on so forth, however… it’s all happening asynchronously because UObject doesn’t have a delay function like AActor, and I can’t figure it out how to use timers when we have multiple combinations of functions and we never know which will get called first or next. :frowning:

I can make it an AActor and make the designer use the delay, but I don’t think it makes sense because I don’t need to have a scene transform for it.

Here’s a snippet of the action with the StartAnimation() function. I have access to the length of the animation, so, in lack of better words, how can I use it to “pause the thread” and call the next function defined by the designer in the blueprint when it resumes?

I’m also attaching an image to visualize better what I’m trying to say lol. Thank you in advance!

float UBattleElement::StartAnimation(UAnimSequence* Animation, TArray<ABattleCharacter*> Targets)
{
	if (!AreTargetsValid(Targets) || !Animation) return 0.f;
	for (ABattleCharacter* Target : Targets)
	{
		if (Target)
		{
			if (USkeletalMeshComponent* Mesh = Target->GetMesh())
			{
				if (Mesh->GetAnimationMode() == EAnimationMode::AnimationBlueprint)
				{
					float PlayLength = Animation->GetPlayLength();
					FTimerHandle AnimTimer;
					GetWorld()->GetTimerManager().SetTimer(AnimTimer, [Mesh]()
						{
							Mesh->SetAnimationMode(EAnimationMode::AnimationBlueprint);
						}, PlayLength, false);
				}
				Mesh->PlayAnimation(Animation, false);
			}
		}
	}
	return Animation->GetPlayLength();
}

Are you looking for

FPlatformProcess::Sleep(time);

to pause the thread for a specific amount of time?

If you want fine thread pausing / resuming then you would need an external thread manager that can handle the thread itself. (you can’t pause and unpause a thread at will from within the thread itself besides though sleep)

I could be wrong but i dont think you want delays, you want callbacks to know when a previous action is complete

1 Like

Isn’t using FPlatformProcess::Sleep(time); dangerous though? Does Unreal 4.27 have an external thread manager?

Maybe so! But I still don’t know how I can achieve this…

If as the thread title implies you are using multi-threading then no it is not dangerous at all.

It will sleep the current thread in which you are running your task. If it is not the game thread then it will not pause the thread, if it is then the worse it can do is pause the game for the set amount of seconds.

You should be working with a thread manager and inheriting from FRunnable to work with threads.
Then you can start and stop threads on command.

Thank you so much, I’ll look into it! But I have a question, if my first function sleeps the thread for 2 seconds, the thread will resume after 2 seconds and call the second function?

After the time of thread sleep ends it will resume from the next line after the sleep.

1 Like

Okayy so, one last question I think, if i want my UObject to run on my new thread, do i create an UObject variable inside the new FRunnable class?

It depends on the use case. Is it going to only be used inside of the thread?

If not then a shared pointer or weak pointer can be made as a link to the outside world (passed through a function). I’ve noticed that weak pointers seem to resolve with no problems compared to shared pointers that can cause errors upon the termination of the thread.

If it will live inside of the thread then remember to clean it up on completion.

i feel your question and your code are asking different things,

i think you want a Latent or Async task not a Multithreaded task.

to use a simple example you have StartAnimation which would be similiar to the inbuilt PlayMontage which has latent output delegates.

Multithreading is more for massive tasks that you dont want to freeze the main thread.

Correct me if im wrong

I’m trying to understand the use case.

You just want effects to go off either at the start or end of an animation? In that case you just want simple callback events when the animation starts, ends, or is interrupted.

Timers or sleep might not even line up and how would you even handle pausing, time dilation, animation cancels, or the thing doing the animation dying while animating?

Using multithreading for this sounds like a recipe for pain. :sleepy:

2 Likes

You might be making things harder than you need it to be…

Search the engine source for FTickableGameObject.

Implement the interface then spawn instances within the game world (make sure that the ‘outer’ parent object/actor is within the world where IsGameWorld() is true).

Then your UObject is going to Tick just like any actor/component class.

1 Like

So many good answers, thank you so much everyone! I’ve been doing some search and I found something called UBlueprintAsyncActionBase and I think that will help me more than using threads, which is a class for making Async tasks with delegates. I’m also going to do some search on the FTickableGameObject.

Thanks everyone for the suggestions! <3

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.