Understanding of the two files

The elements I recognized:

.cpp file

  1. The UPositionReporter::UPositionReporter() constructor.

  2. The two functions. The first one runs only once and the second runs continuously. The second function takes 3 arguments, the first one I guess has to do with the game being paused or running, the second one indicates the type ot tick and the third one is a pointer to a function.

The header file

  1. The #pragma once.

  2. The class declaration

  3. The constructor’s declaration.

  4. The public/private/protected sections of the class.

I did not understand:
-The ticks in general.
-DeltaTime (at least not completely).
-What “meta” is in the class definition.
-The : public UActorComponent that follows the class’ name.
-GENERATED_BODY()

I won’t get into the other things, but I can explain the Tick(float DeltaTime)…

In setups like Unreal, Unity, etc, most code does not run “continuously”. In the BullCowGame, you’ll recall that the code ran in a loop, over and over again. Nothing interrupted that code, it just ran and ran. For a small console program, this is not a problem, but for a game, it’s a huge problem. If one method just sits and runs over and over and over again like BullCowGame, nothing else would happen in the game.
So the solution is that execution is divided up amongst all the objects in the game. Everybody gets a turn, round robin, to do their thing. If you look at your World Object tree, imagine that each object in that list gets a “Tick”… Like a bowling game… every player gets a turn, one after another. Once every object has had a turn, this is a Frame (just like Bowling). Then we give every player a turn again.
That’s where Tick(float DeltaTime) comes in. Every frame, Tick is called. If you have some action you want to happen over time (you might, want to adjust your course, move that chair you’re holding, aim that turret, etc), Tick is the opportunity to do it, but you don’t want to make the whole move, you just want to do as much of that action as you would do in the amount of time since the last time Tick was called.
That’s what DeltaTime is for. DeltaTime says “Since the last Tick, DeltaTime seconds have occurred.” You can use DeltaTime to adjust how far something moves this frame… if, for some reason the code ran very slowly last frame, you can move the barrel faster this frame to keep it looking like it ran smoothly… if the frame was particularly short, you move the barrel less.
Usually, you’ll see something like myMoveVector * DeltaTime… if you calculate myMoveVector to be how far an object should move in a second, then multiplying it by DeltaTime will be exactly equal to how far it should have moved since the last Tick.
Then, as quickly as possible, your Tick returns, giving the next object in the chain a turn, till the next frame when the cycle starts again.

1 Like

That’s a solid answer Brian. I appreciate the time you took to write this. I have the idea of how it works, I guess I’ll see it more in action as time passes.
But, I have a question. You said this: > So the solution is that execution is divided up amongst all the objects in the game.
Can’t we solve this with parallel programming? Probably a dumb question, but I have some experience with it and most PCs do have multi-core CPUs so that’s why I’m asking. It would be extremely difficult to do, but I’m curious to find out if it can actually happen. I also don’t know if Unreal can support this, I’m still new here :stuck_out_tongue:

It actually is a form of parralel programming, just not processor/thread based.

There are a couple of problems with using multiple threads instead of the Tick structure used by most game engines:

  1. They are a pain to set up. Hardware threading requires you give each thread its own sandbox, communication between threads has to happen through handlers, etc… The GameLoop method just adds a pointer to a Tick() for each object in the scene…
  2. You’d need a LOT of them (think about how many objects are in the scene… once we start adding particles, etc, yikes!)
  3. You don’t have the same level of control over timing in true parralel processing. In fact, that’s why threading is used in many other applications, especially network based ones. You don’t want to hang the game up while one thread gets hung up waiting for a response. The timing doesn’t matter… you say “fetch this file off the network, and let me know when you got it”. In the case of a game like this, you WANT everything to function ever frame. You simply can’t get the same level of precision in timing from threading. (That being said, Unreal DOES use threading, just not for gameloop management.)

Oh man I completely forgot about the last point you mentioned, that every other thread must wait for the slowest one to finish first. It’s good to know that Unreal handles the gameloop like this.
Again, thank you Brian, your help is greatly appreciated!

Privacy & Terms