I want to completely control the tick of all actors in the world. I found in class UWorld a variable called bShouldTick. There is a note on top that says this :
I toggle this bShouldTick value from a remote client as and when I need. When I set it to true, all actors start ticking and when I set it to false, they stop ticking. Now, if I move the actor from remote client using setactorlocation() with tick disabled, the actors position is updated and rendered as well. So, I can assume that Tick() does not control the update of actors location. However, the actor’s components do not move along with actor, even though they are attached to it. When I start ticking, the components shift to the new location instantaneously.
My questions:
Is it a good idea to control Tick functionality of all actors this way? OR is there any other way to do this?
In my current way, is there a way to move components along with their parent actors, with tick disabled?
I’ve not disabled Actor’s Tick. The Actor has bCanEverTick=true and bStartWithTickEnabled=true. The only enable and disable of tick I’m doing is that of the World. Disabling World tick does not disable actor tick. I’ve verified this. So, for your question, Actor Tick is always enabled.
Also, I’ve set all the actor’s components (scenecapture2d and staticmesh) tick as true and all as false with same behavior.
Btw, I tried running the game in PIE and standalone mode with same behavior.
I have the following followup questions:
Why does the comment in source code -
say that it’s ok for worlds with no rendering? In my case, I’m seeing the change in actor’s location and this means that the view is rendered right?
Is this way of controlling world tick to control all actor’s tick acceptable?
if I disable actor’s tick, does this make all of it’s components also non tickable?
Is there a way I can enable this WorldTick to make it run just once or as many times as I need?
What is the source of the propogating Tick() function? I can’t seem to find who/where this UWorld’s bShouldTick is used. So, not able to understand how bShouldTick of UWorld affects Tick() of all actors.
Setting PrimaryActorTick.bCanEverTick = false; is the way to achieve this.
An endless number of things won’t work properly if you disable the world/level tick, even stuff as basic as timers and the camera view. As the comment says, it’s really not designed with game worlds in mind, it’s most likely used for editor worlds. Components can still tick even if the owning actor doesn’t.
Setting PrimaryActorTick.bCanEverTick = false will not register the actor to tick. So, Tick() of this actor or any other actor will not be called. But, I want to call Tick() of all actors at my request. Is there a way to achieve this?
But then how am I able to see the actor moving if the camera view is not rendering?
Eventually I want to control all actors in parallel i.e a scenario like this
Let’s say I have zombie actors with predefined behavior and non-zombie actors that I control.
I setup the new location of all non-zombie actors by getting information from a remote client. I don’t execute it on any actor yet. Info is just stored.
Then I send a request from this client to Unreal to update the non-zombie actors location with the new location.
The problem here is I want zombie actors to execute their logic in sync with when I send the request from my client to update location of non-zombie actors.
I thought this can be done using Tick() since it’s common to all actors. And by controlling worldtick, I can simultaneously call Tick() of all actors. If disabling world tick is not a good idea, is there any way I can achieve this?
I don’t understand, you want to disable the world tick, but also have your actors’ tick? Why do you want to disable the world tick at all then?
If you want to control the ticking of a selected group/type of actor, then you should create some kind of manager class that ticks them instead of driving them from their primary actor tick. Just create your own function call ‘MyTick’ or ‘Update’ or something, have the actors register themselves with that manager, then use the managers’ tick function.
When I meant disable world tick, I meant only for a certain duration. I’ll enable world tick again on need basis. This is the reason why I still want actor’s tick. I’ll have to enable and disable world tick many times from an external client.
I didn’t know about having tick managers, looks like a promising way to do it. I’ll look into it. Thanks much!
Looking at UGameEngine::Tick(), it seems that first UWorld is ticked (this is where all levels tick and hence all actors registered (through FTickFunction) to these levels tick), and then FTickableGameObjects are ticked. This is good but only a part of what I need. I still won’t be able to control when to tick i.e not when to tick in a frame, but when to tick in a game. I can ofc call IsTickable() whenever I want to tick actors associated with my manager, but then I won’t be able to control how many times it ticks or is there a way to track how many frames it ticks?
So, a tick manager would be derived from UObject and FTickableGameObject. Now, how do I register my actors/components with this manager? I don’t see any functions in FTickableGameObject that allows this.
Also, is there a way to tick group of actors using FTickableGameObject or something else, before world ticks, without modifying source code?
I was able to do this using delegates. As of now, I can tick my actors by creating a custom MyTick(float DeltaTime) function in my actors and bind that to a delegate which broadcasts during Tick() of my manager. But, this does not allow me to tick my actors’ components. I’d have to define these custom MyTick() in all the components to be able to bind them and to do this I’ll have to create separate classes for all the components I choose to use. This seems a bit overkill. Am I thinking this right or is there another way to do this?