[My Dev Journals main page]

Page 1 2 3 4 5 6 7 8 9

 

April 09, 2016

Choosing A Programming Paradigm

A Little Background

This is not something I do for every project. Normally, I just develop the current game much in the way I developed the game before this one. However, about every 2nd or 3rd project I like to experiment with doing things a different way. I mean I do that to some degree on all projects at a micro level here and there but occasionally I do it on a bigger architectural level.

Unity is based around the Component Based Architecture. The idea behind it is that composition is good.  I am not here to argue for or against that. It is what it is. Pros and Cons like all things.

The idea is you break things down into multiple tiny things. These things are generally classes and then through composition (that is adding components / classes to a GameObject) you build up more complex behavior as well as customizing the overall behavior of any given GameObject.

For example, if you want a GameObject to be controlled by the keyboard you could simply add a KeyboardController script to it. If you want other objects to be able to collide with it you add a collider to it. And so on.

This also ends up making it so nearly every GameObject has one or more components attached to it. Scripts will nearly all have an Awake() and Update() method. Communication between these different objects has given more than a few Unity devs a real headache. These are some of the downsides of the component-based architecture.

I probably develop in Unity differently than most folks do. For example, I don’t use any of the built-in physics nor do I use the Collision Events system instead relying on various casting methods. The reason is that I also develop in other languages and frameworks (examples may be found around this site). And I like to keep things reasonably consistent when moving back and forth between different languages and frameworks.

And I generally do not use the Component-Based Architecture elsewhere although I have used it up til now in my Unity projects.

So this time around I am testing what I think will be a better way to develop (at least for me personally).

 

A More Procedural Architecture

What I will be testing is using a more procedural architecture. Sure it will still be OO but will be strongly leaning toward traditional procedure programming as well.

The first thing I plan on doing is removing all custom code from GameObjects. They will have no classes assigned to them in the Editor. However, they will still have colliders, character controllers and such added in the Editor.

Basically, I will be applying an approach I have found to be very successful in my programming outside of Unity.

It centers around the use of Managers. Dedicated managers that… manage… collections of objects.

In the Editor there will be a single GameObject (GO) defined that will have code added to it. This GameObject will be named GameManager.

The GameManager class added to this GO will represent the main loop commonly found in traditional game programming using a procedural architecture.

Inside the GameManager class will make use of many different Manager classes:

Each manager will then be responsible for managing a list of objects of a certain kind. In the simplified example above EnemyManager is responsible for initializing and updating all of the enemies, CollectibleManager does the same for all collectibles and ProjectileManager does the same for all Projectiles.

In addition, each manager can provide a list of references to every object under its management. Collision detection and communication between different objects (or at least managers) becomes much simpler.

Each update instead of dozens, hundreds or even thousands of Unity GameObjects each receiving a call to their attached scripts Update() methods… only the GameManager has an Update method. In fact, only the GameManager GO actually has a script on it. The rest of the code exists entirely outside of the Unity Editor not attached to any GOs. So only this one call happens to the GameManager.Update() method. GameManager in turn calls the Update method of each Manager. Each manager then loops through all of the objects it is managing and updates them as needed.

Basically each GameObject now becomes a lighter weight object. They’ll still have colliders on them but they won’t each individually be running their own Update() method every update cycle.

Obviously, not rocket science. Like I said, this is just the normal way I have done game dev for decades now (although admittedly I am always incorporating the latest and greatest ideas in software engineering). It works. I am not saying it is better or worse than Component-Based Architecture. I am just saying that for me personally I find it to be a cleaner approach and easier (faster) to develop with.

As time (I’m talking many years… decades) passed and I continued to embrace the latest & greatest ideas in software engineering I noticed that although they had value solving various problems they also added layer upon layer to the development requirements. So, in a way this is a test of stripping out a lot of the modern practices and dropping back to a more “old school” development approach. More straightforward. Less to think about as far as applying the modern development philosophies. And instead taking me closer to a more pure development approach much like I used a long time ago.

The only way to know for certain if this is a good or bad decision is to put it to the test. And that is what I am doing. 🙂

 

April 10, 2016

Testing The Player Manager

Time to get the player moving. To do this, I needed to create one more GameObject (GO) named Configuration.

So, it turned out I already had to adjust my original plan of only the GameManager GO existing inside the Unity Scene Editor. Because, I need a way to easily configure movement speed and so forth. Normally Unity devs expose such config properties on each individual GO. However, in this case I don’t want that so I created a GO dedicated to the various settings.

Next, I created the PlayerObject class. This class is simply a container object with the following public fields:

Then I created a PlayerManager class. This new class simply creates an instance of the PlayerObject container and initializes it in the PlayerManager.Init() method (called by the GameManager.Start() Method). The initialization process sets up the GameObject, Transform, CharacterController and Camera properties of the PlayerObject.

Yes, the Player GO actually has a CharacterController. I have tested various ways of doing this including completely writing everything from scratch and ultimately I find that using the built-in CC is actually a good way to go.

Then GameManager.Update() calls PlayerManager.Update() each update frame. The PM.Update() method takes the various config settings specified in the Configuration into account when moving the player and adjusting the camera for the “bobbing” motion. Easy! 🙂

Definitely different than the way I have developed in Unity previously (and based on code I’ve seen on the Unity forums, the official tutorials and around the web… different than what most folks are doing too). I like this approach so far. It just seems to make things… simpler. Of course, a big part of this may be due to it being much closer to the way I developed games before using Unity.

Sure, there is some redundancy in the model in that having a reference to the GameObject I could get the Transform, CharacterController and Camera. But that is kind of the point. I fetch those references in during the Init and store them. Then I have them readily available at any time I need to work with them from that point on.

 

A Quick Test of the Enemy Manager

Just to do another test of this approach I created the Enemy Manager and did a bit of work on it.

The enemies roam around scanning their environment. Nothing happens when they detect the player.  When they detect a wall directly ahead they turn away from it.

The little floaty balls in front of the enemies are simple scan markers. Just a visual indicator of how far out the enemy is scanning. Of course, that range is adjustable.

Implementing this very simple enemy test was another win for this new approach to my Unity dev. Very straightforward. Simple. Obviously, they need to be fleshed out a lot more than this for the actual game and I am pretty sure it will be easy to do.

That’s it for this log. I don’t work on these projects much. Just when I feel like it. Tomorrow night I should be back to work with another dev session and log.

 

 

April 11, 2016

Quick Update To The EnemyManager

Tonight, I worked on the roaming behavior of the Sentry.  I really wanted this enemy to have an obvious sweeping motion when moving to actively scan back and forth in front of it. I already had the basis implemented in my last log. So I simply adjusted the sweep range, movement speed, scan speed and so forth. It detects obstacles and the player but at this time only reacts to the obstacles that block its movement. The idea is the player will enter a room and find these things patrolling around searching for things that shouldn’t be there.

 

The Collectibles Manager

I also created the CollectiblesManager. Knocked out a couple quick models. Not sure if either will actually be used but yeah anyway here is a collectible waiting to be collected:

Not much to say about this because it is so basic it took hardly any time at all to implement.

The Collectibles use the same pattern as the Enemies. I created a CollectibleObject class that serves as a container for each collectible GO. The CollectibleManager is responsible for initializing and updating the collectibles.

I think it might be time to get into something a little more interesting now. Perhaps tomorrow I will implement the player weapons or the enemy engaging the player. Not sure yet. I will figure it out tomorrow night. 🙂

 

Page 1 2 3 4 5 6 7 8 9