Help with creating an efficient 'Manager' class

I’ll start with the backstory of what I’m trying to do… I’m working on a Radar system for my Hovertank Game, and in order to work I need to store a big chunk of information somewhere where the UI can access it. As a bonus, other classes such as my weapon classes will be able to access this data so they don’t have to create arrays of their own (for iterators and such-like). I figure the best way to do this is to create an overarching ‘Manager’ class which will manage all of my Game Objects.

Since the game is both Multiplayer AND has the potential to have a LOT of trackable objects on the map (potentially thousands), I need something that’s not going to be replicating any data (that is, clients can manage their own data and the Actors’ own replication will keep their copy of the data in check with the Servers’ copy. Any discrepancies won’t have any game-altering effects). I also need something that’s fast, and doesn’t eat through too many cycles keeping track of all these objects. I have all of this in place already, my GameInstance invokes my Game Managers on initialization.

It gets a little easier at this point, since all of the object that I will ever want to track will alwayshave a custom ActorComponent I’ve created, a ‘GameObjectComponent’. Essentially I want to track these objects’ location in the world, and a few properties from them too, such as:

  • Location (Vector3)
  • Team ID (uint8)
  • Class (ENUM (uint8))
  • Dead / Alive (Bool)
  • Signatures (Struct of 3 Floats)

I figure that I’d create a Struct of exactly this information, and have the Manager cycle through all the GameObjectComponents in the world with an ObjectIterator and update this information constantly. Or, is it better that I update the Manager from the GameObjects instead, so that each updates the Manager as and when it wants to?

The problem with the latter approach is that I can never pin down when exactly the Components will update the manager, so there may be cases when I get huge slow-downs because they’re all accessing that big array at once and changing stuff. I figure that isn’t a great way to go since it gets less and less scalable the more objects I have in the world.

Instead I want the manager to have an upper limit as to how many cycles it can take up, or how many milliseconds it’s allowed to spend updating per frame. When that time is up, it has to wait until next frame to continue updating the Array. That way I always know exactly how costly my Manager is, and only the accuracy of the information suffers as more objects are added to the world. How can I go about doing something like this?

Additionally, My GameObjectComponents are NOT Scene-Components, just regular Actor Components. What this means is that they don’t have Transforms and therefore will have to get the location with Two pointer dereferences (this->GetOwner()->GetActorLocation()). Does it make more sense for me to make these components SceneComponents so that I can cut down on how many dereferences I have to do? I’m also going to assume that creating Const Inline functions that access all the information I want from the Component would be a better approach than just making those Vars public?


The gameplay behind this, is that Players will be able to see a Top-Down view of the entire map, which shows all units that the players team has coverage of. For example, say a unit on the players team has a Radar Range of 500 but is 5,000 units away from the Player, the player will be able to see all units on the Radar that are within a 500 unit radius of that team member too on their Top-Down radar.

The radar also identifies certain things like what team the object is on (indicated by colour), what type of object it is and how strong it’s signatures are etc (Image, Heat, Radar).

Eventually, players will also have a 3D-radar of the surrounding area that highlights only units in it’s local radar range, and the topography f the surrounding terrain. This also has implications on the managers functionality, should I also potentially store another array in the Manager that only has objects within the Players range, so that the Radar can access it faster, or do I let UMG sort out what it should and shouldn’t display?

Hi,

I would say that there is no “generic best way” to collect objects in a range under arbitrary conditions, but I have done something like this for a minimap.

Basically, our spaceship-actor is the singleton-object which collects all relevant actors which are in “scannerrange”.

As the spaceship and all actors are moving, and the scannerrange can also change, I have decided to iterate through all exsting actors in the spaceship-singleton and add them to a list, if they are not already in scannerrange (bool) and also save the tick-count when it was last seen in scanner range (integer, increasing each tick).

After iterating through all actors, I can iterate over my updated scannerlist, and remove only those which have not been seen this tick.

Other optimisations are:

  • update the list each 0.1 seconds and not each frame
  • only update actors which are visible in a global processing range (another list in another singleton)

You could also open another thread but I think this is a bit overhead.

As for the const inlining vs public members thing I would believe that this would not make any difference as the compiler will optimize it anyway.

Hope this helps