Class Question / Design for a RTS game

I need general help… I am designing an RTS game that will have many pieces in play at the same time. These pieces will range from infantry, to tanks to oil rigs, etc. All these pieces, though different, will have many properties in common that I need to track in a Class called Piece. Properties in common will be…

ID (unigue ID ranging from 1 to the total number of pieces in the game)
Age (How many days old the piece is)
Type (What is it)
Owner (which player owns the piece)
Health (over all health of the piece)

you get the idea…

So how do I use this Class? Do I drag it on every game object prefab, so when it is instantiated in the game it has it? I would need some global array that holds all instances of this class so I can loop through them, correct?

So here is my biggest question… When I loop through all these classes how do I actually relate the class I am on to the actual game object? For example lets says I have some stupid rule that any piece in the game that is alive for more then 100 days (turns) gets destroyed. I’m looping through the array and I come to a piece that is now 101 turns old. How do I relate this back to the actual game object if I wanted to destroy it?

If the class is a MonoBehaviour, you can find its gameObject simply like this:

myClassInstance.gameObject;

So what you are saying is that since the class file is already attached to the game object, I don’t have to do anything if I want to relate back to it? Which is good news, because I was thinking I might have to create 100+ tags and give each 3D object is own unique tag and then use gameObject.Tag = “what ever” to relate back to the 3D object.

Yup, it’s that simple :slight_smile:

you should look more into prefab.

You don’t have to have many class for each unit.
You could just have many prefab for every unit and 1 class for them all.
Which hold health, age, type, owner.

dont think you need to go tru your unit when you design it like this.
But could have a scenemanger holding it.

I would make a few recommendations for your RTS (having worked on one or two strategy games in the past and all that):

  1. Make sure your ID is unique to that object, never, ever recycle your IDs. Your ID can be a simple counter mechanism, but if you want to get fancy, I recommend a ShortGUID.
  2. Create a manager that will store all of the Piece IDs in a Dictionary<ID, Piece> that you can quickly use to look up a Piece given an ID.
  3. Keep a manager that tracks all of the units in a big list that can be used to query for particular unit types. LINQ is your friend in this case. Otherwise you will have to resort to Unity’s built-in mechanisms for tracking these units with functions such as FindObjectsWithTag.

You have a design choice with regard to Unity:

You can either create a single prefab for mobile units with your Piece script attached, and a single prefab for static units with your Piece script attached, and then instantiate either one of those prefabs and begin to change all of the variables, meshes, particle effects, from a database of information such as an XML file which makes for easier editing by people who do not have Unity but a pain in the arse for you.

Or:

You can create a prefab for each mobile unit type, and a prefab for each static unit type, setting the properties in the inspector and treat Unity as your database of information making it easier for you and people who have Unity to edit, with a nice graphical editor, but making it awkward to edit for people without Unity.**

** You could write a custom serializer that will permit both, but that depends on how much work you want to go through to make everyone happy.

Thanks for the tips, I do have a few questions though.
1.) Why are you against recycling ID? If I destroy properly, I can keep the collection size (or array) down. Or will this cause problems in a multi-player game?
2.) Does Unity support LINQ? I haven’t used LINQ yet so all I know is we use it at work in some of our c# code.
3.) About creating a single prefab for mobile units and a single prefab for static units, I was thinking this… since most static units can not be destroyed or created, just captured and utilized by the capturing player. Is creating a prefab for each possible mobile unit (maybe 20 prefabs in total) better or not?

Recycling IDs is a bad idea for a couple of reasons. In no particular order: if you have a bug elsewhere in your code, whereby you store the ID reference in another data structure, say, another Mobile Unit that is attacking that ID, and your code does not properly clear out the unit ID reference, it may be that at some point in the future, the ID is reused and now the unit that maintains the reference to the old version of the ID now knows about the new unit.

Another reason is with multiplayer games. If you recycle IDs, however unlikely it may be, players may be able to somehow find an exploit that stores one or more previously used IDs and when that ID is then recycled, use the information to pull out information that they may not have access to.

Recycling IDs also permits you to easily record all of the IDs for debugging purposes, logging, database storage, etc. You are assured that the ID was used once, and only once, for a very specific object.

IDs should be a unique key of some description, both for ease of implementation and for your own sanity. Nobody would propose ever storing a non-unique key in a database to uniquely identify** a record, and an RTS game (many games in fact) are just databases with a fancy user interface put on top of it.

I am not sure what you mean by “keep the collection size… down.” You would not ordinarily track all IDs ever created all the time, you would just make sure you never reuse a previous ID, which means you either have a simple cycling counter, i.e. you set up a counter that starts at zero, and when you create a new unit, static or mobile, you increment the counter by one. Alternatively, you could use a GUID or a ShortGUID to assign unique IDs to your units.

Unity supports LINQ, you just have to put the appropriate “using” at the top of your source module and you are good to go. LINQ to Objects, and you probably know all this based on your familiarity with LINQ, is a very powerful way to query your data objects for that match particular criteria and perform an action on those objects. I have used LINQ in traditional websites – which is where I first starting using it – and in projects as diverse as a MMORPG bot, a World of Warcraft multiboxing application, a Bookworm-like word game, a genetic game solver and a medical simulation.

With regard to creating lots of prefabs or just one prefab with different data, that comes down to personal preference for your architecture and managing the complexity of the project. Neither way is inherently better than the other in this particular instance. If you know how many unit types you have ahead of time, and you do not have dozens or even hundreds of unit types, multiple prefabs, e.g. a single prefab representing each unit type, may be the ideal way to go.

You may also want to consider a Unity editor extension specifically created to handle the creation and modification of unit prefabs. What form this editor extension takes, and the functionality it provides, I cannot say at this time as I have no clear idea of the unit types you will be defining in your game. Most units, I suspect, are going to be your standard ones, e.g. infantry, ground armoured transports and various flying units.

Philosophically, if I were approaching this with Unity as my engine, I would create a number of standard scripts that do one specific part of the functionality for a unit, e.g. ground movement, ground navigation and fighting, that could be attached to each unit prefab. I would define a number of unit prefabs, at least at the beginning if I had no clear idea of how many units I was implementing, i.e. I am just rough prototyping the game rather than working from a well written game design document. I would also write a number of scripts that can be attached to the more esoteric units, e.g. flying movement, flying navigation, healing effect, laying mines effect.

Each unity prefab would be a “pick and mix” aggregate of all the smaller scripts. I would, philosophically speaking, steer away from attempting to make the monolithic uber-script that does every feature and every action for every unit type possible as it will very quickly grow to be unmanageable and cause many headaches as you yourself hit your complexity limitation. If you are creating scripts for units that are more than one or two hundred lines long, you’re probably putting too many features in a single script. It’s okay to have scripts that are longer, but the majority would be better if they were kept to the tens of lines of working code (this doesn’t include blank lines and comments and curly braces) rather than the many hundreds of lines.

I would also suggest that you make use of some of the more complex ideas of both .NET and software development, things such as state machines for each unit, behaviour trees for units deciding what to do next, LINQ to query objects, delegates and events for inter-object communication, and an overall good, solid architecture to build off of. You will find that if you build a good architecture for your game, you can try out new ideas for it very quickly, and should you actually finish your project, be able to turn the now reasonably generic “RTS engine” to other games too.

For your unit design, I would recommend a rock-paper-scissors approach, and keep the number of possible unit types very low until you have a good strong structure available to you.

** They might store a record with a non-unique key for unique identification, but it is an esoteric usage that we don’t need to explore here.

Unity provides a unique id through GetInstanceID()

It does, thank you! I had forgotten or overlooked that feature. :slight_smile:

Thanks for the tips. I was thinking one under script but now agree with you on smaller scripts. Against thanks for the tips. Will be a learning experience., but fun.