0
\$\begingroup\$

I have a huge list of predefined game objects with different actions they do. What is the best (in terms of code simplicity and runtime performance) way to store, dynamically refresh and execute their actions after placement them in game in runtime?

Let's say GO1 every game turn creates copy of itself nearby. GO2 destroys all GO3's. GO3 adds resources. GO4 removes resources on its creation, etc. Each turn player instantiates one object from the list in the game world and after that they start to execute their actions. Player can build multiple objects of the same type, and there are hundreds of different gameobjects with hundreds of different types of actions. Objects can't change their actions in the runtime, for the sake of simplicity of this question. Each action can be very heavy on processor - for example, look through each other object. Having those be all executed at the same time is a problem itself.

Some ways I can think of (but having very little experience with the subject, I have no idea of their actual effectiveness):

  1. Assign every object a method on its own. Object initialisation list becomes very complicated and you can't really store it in xml-like file.

  2. Initialise objects with some kind of lambda or Action<> literal parameter. I can't imagine this is okay in terms of game resources, and probably is a hell for debugging.

  3. Initialise objects with a string of parameters. Simple to initialise, but parsing requires extra processor time.

  4. Initialise object with a struct-like list of actions. Simple to initialise, but number of childs in said mega-struct will become extremely big.

  5. Hardcode a mega-function with a lot of calls like "if (objectID == GO2) then do" or cases. Sounds stupid, probably is.

  6. Unity-way: assign each instantiated object an own script, pass script name on initialisation, similar to p. 2. Most simple way, but can't be easy for a machine to execute. Also, changing object parameters will be complicated.

It should not matter, but I'm using Unity3D with C#.

\$\endgroup\$
  • \$\begingroup\$ Could you clarify what you mean in the first paragraph by "dynamically refresh"? \$\endgroup\$ – Chris Mills-Price May 7 '18 at 17:47
  • \$\begingroup\$ "Dynamically refresh" the list of objects currently played. I should have used more accurate terms, but am not a native English speaker, so often struggle with precise descriptions. You can probably see it a lot in the opening post. \$\endgroup\$ – FREEZE_ball May 8 '18 at 4:23
0
\$\begingroup\$

The Unity way to do this would be to implement each of these object behaviors as an own MonoBehaviour. Create a prefab for each object type and assign the appropriate MonoBehaviour to it. When a player spawns one of these object, instantiate the respective prefab.

\$\endgroup\$
0
\$\begingroup\$

I tend to tackle things like this using Option 7: Polymorphism

  • All Objects inherit from the same basetype
  • Store a data structure of the basetype (which allows the polymorphed versions to be in the same data structure for iteration)
  • And overwritten function in the derived classes allows them to act different without managing what you're talking to

In case you're wondering, I do define these types as their own dedicated classes in my code at the moment (but may find a better way later as I get a lot of types.) In general (because most of my information is static at the moment and requires no additional functions) my derived classes are only a few lines of adjusted stats, a changed Update function, a reference to the model or texture it uses.

Anyway, I do this method for handling my guns/bullets/projectiles. I also use it as a way for all my things to use similar drawing code (and thus not have to implement it more than once) and they use a custom model-batcher. This is all to say that an implementation like this can work if you're patient with it.

In my case I have something like:

public abstract class BulletType
{
    public double Duration { get; set; }
    public uint Damage { get; set; }
    public double Speed { get; set; }
    public DrawData3D.TextureType Texture { get; protected set; }
}

public class Bullet3D : BaseObject3D
{
    public BulletType Type { get; set; }
    private int LifetimeTicksRemaining { get; set; }

    public void Set(...){
      //...
    }

    private void CalculateMovementVector()
    {
      //...
    }

    public override void Update()
    {
       //..
    }

    private void Reset()
    {
        //..
    }
}

public class TankRound : BulletType
{
    public TankRound() : base()
    {
        Speed = 4.0;
        Duration = 1.5;
        Texture = DrawData3D.TextureType.BIGBULLET;
    }
}

Which means all my bullets get to be managed and updated by a single manager and utilize the same code. My manager actually never deletes or creates bullets either AND the stats are stored inside that singleton struct, so those stats are memory efficient because they only exist in one place.

I hope this is enough to validate the idea that using polymorphism can do this for you.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.