Christmas Wind-down

Hi everyone,

With the holidays almost upon us I just wanted to wish everyone a very Merry Christmas and all the best for the New Year!

If possible, I will do my best to crank out a further post between now and the New Year. Here’s a teaser for the first part of the year (likely approximately the first quarter), taken from my original ‘pot of things’ to cover with a few additions that are taking precedence, based on current interests:

  • Continued prodding around in F# (likely starting with charting as promised).
  • The Razor View Engine (basic overview).
  • An Arduino starter project.
  • Deeper dives into JavaScript (in the build up to some exams…more to follow here).
  • As an extension to this, I want to do some ES6 coverage.
  • A return to Unity (I’ll probably do a big hit around the start of Spring).
  • Plus other things from my original cooking pot, including Udemy courses and sneak peaks on other libraries/utilities as I can, etc.

I may well revise my posting frequency a little also. After planning on doing two posts a week I’ve become acutely aware that I’m not really hitting that mark, so I’ll either go down to one post a week or learn to produce posts faster (and better!). We’ll have to see how all of this pans out.

Anyway, have a wonderful holiday!

Future Decoded 2015 Play-by-play

Hello beautiful people!

It’s a fantastic, gorgeous Saturday morning (it’ll be Monday by the time I hit the publish button, such is the enormity of the post!); the birds are chirping, the sun is shining through the balcony windows (and there is a bloody wasp outside, STILL!!!) and my wife has left me…………to go on a girly weekend (that probably sounded more alarming than intended; hmmm, oh well, it stays!). Whilst she is away fighting the good fight, this gives me the opportunity to go over my thoughts on the recent Future Decoded 2015 event that took place at ExCel in London.

The links to outline this event have been posted before on my blog, but just in case, here are the goods again:

Future Decoded 2015
Future Decoded 2015: Technical Day Highlights

Before we begin, it’s worth pointing out that I attended this event a couple of weeks ago, so apologies if any inaccuracies pop up. I’ll do my best to stick to the facts of what I can remember and specific points that interested me; other commitments ended up preventing me from getting to this particular post sooner. You’ll all let me off, being the super gracious, awesome folks you are, I’m sure :-).

So, FIGHT!!!!!

Sorry, I had a dream about Mortal Kombat last night and upper-cutting people into the pit – What a great stage that was! Ah, the memories….Let’s begin/start/get on with it then.

Morning Key Notes

The morning Key Notes were varied and expansive in nature. I won’t discuss all of them here, only the takeaway points from the talks that struck a chord with me.

1) Scott Guthrie. EVP Cloud and Enterprise, Microsoft (Azure).

I was particularly looking forward to this talk being a keen follower of Scott Guthrie (include Scott Hanselman), and I normally try to catch up with Channel 9 features and Azure Fridays whenever possible (I’ve linked both, although I’m sure most of you, if not all, have come across Channel 9 before or heard of Azure Fridays).

The talk did have primer elements as you would expect, i.e. here’s the Azure Portal and what you can expect to find (in relation to resources, templates you can access for applications, services, Content Distribution Networks (CDN), etc). The next bit really caught me cold, who was expecting a giant image slide of a cow! I certainly wasn’t…

Estrus in Cows

What followed was a full example of real-time data recording and assessment surrounding the monitoring of cows in Asia. I’ve provided a link below that sums up the concept of Estrus (being in heat) nicely enough, but it laymen’s terms it relates to cows ‘being in the mooooooood’ (wife insisted I added that joke). Obviously, a farmers’ ability to accurately detect this, urm, state of being in a cow is an incredibly important factor in the ability to produce calves.

It turns out that a cow tends to move more when in the Estrus state; something that can certainly be measured. So, with pedometers attached to cows to measure steps taken and an Azure based service receiving and providing feedback in real-time, the farmer in question was able to take action to maximise calf production. Further to this, analysis of the data gathered was able to identify trends against how long cows have been in the Estrus state, and the gender of offspring. Crazy stuff, but all very interesting. Feel free to read further to your hearts content:

Cow Estrus Detection

The Internet of Things (IoT) was briefly touched on and another brief, live coding example ensued.

Scott produced a small, bog-standard heat sensor (apparently, just a few pounds, I was impressed he didn’t say dollars!) and proceeded to demonstrate a basic WinForms application passing a JSON payload to Azure in real-time (measurements taken a few times a second). This strikes me as exciting territory, and I have friends who do develop applications working in tandem with sensors already, backed up by technologies such as the Raspberry Pi and Arduino, for example. The talk closed with the conceptual idea that the majority of data, in the world today, is still largely unmeasured, and hoped that Azure would be an important platform in unlocking developers potential to measure previously untapped data.

2) Kevin Ashton. Inventor of the “Internet of Things”.

Kevin coined the term the Internet of Things (IoT), and gave a very good talk on what this means, as well as identifying certain ‘predictions’ for the future. For instance, that we, as a species, would survive climate change for one. He quickly noted that calling ‘BS’ on this particular one would be tricky should we suffer a doomsday style event at the hands of climate change (I don’t imagine the last thoughts of humanity to be, ‘oh, Kevin Ashton was so bloody wrong!’). Another interesting prediction; we would all own a self-driving car by 2030. Prototype examples already exist, such as Googles (and Apples) efforts, and the Tesla:

Google/Apple (Titan) Self Driving Cars
The Tesla

Self-driving cars being one of the cases in point, the IoT relates to how a whole new host of devices will now become ‘connected’. Besides cars rigged up to the internet, we are all aware of the hooking up of internal systems in our homes (heating, etc) and utility devices (the washing machine), as to always be online and accessible at a moments notice. This world isn’t coming per say, it’s essentially already here.

Pushing past this initial definition, Kevin was keen to stress that the IoT was not limited in its definition to just ‘the connecting of hardware to the internet’ only. Wiki sums this up quite nicely on this occasion, but software (services and analytics) that moves forward with hardware changes will ultimately change the way we live, work, shop and go about our daily lives. Whether this be data relayed from the fridge to google glasses (yes, you are out of milk!), or perhaps a self-driving car ordering ‘click and collect’ shopping and driving you to the collection point after work (not to mention triggering the heating x miles from home!). Software, and the analysis of the new kinds of data we can record from interconnected elements, will be a huge driving force in how our world changes:

Internet of Things (IoT)

Lastly, before I forget and move on, a key phrase voiced several times (although I cannot remember the exact speaker, so apologies for that, it was probably David Chappell) was to reset your defaults. Standard client/server architecture was discussed, and for those of us that are part of long running businesses this is what we are exclusively, or at least partially, dealing with on a daily basis still. However, the change to the use of mobile devices, tablets, etc, as clients and the cloud as the underpinning location for the services these clients communicate with is becoming the norm. For start-ups today, mobile first development and the cloud (Azure or Amazon Web Services (AWS)) are probably the initial go-to.

For some of us (speaking from a personal standpoint only), a major factor in our success as developers could simply be determined by understanding the cloud and getting the necessary experience to make the transition (for those who are not actively taking part in this world of course).

So, now we have the IoT, let’s talk security…

3) Graham Cluley. Security Analyst, grahamcluley.com.

Graham delivered a funny and insightful talk surrounding everyones’, ‘Oh my God, the horror, please kill me’ subject, the wonderful world of security.

In a nutshell, he argues (and certainly proves his point as you’ll read next) that the IoT will bring wonders to our world, but not without issues. We now have a scenario whereby a breadth of new devices have suddenly become internet connected. However, are the driving forces behind these changes the people who are used to dealing with the murky world of malware, viruses and hacking attempts (such as OS developers)? Probably not, is the initial answer. This is, of course, just a cultural divide between those used to trans-versing the security world and protecting devices from such attacks, and those tasked with bringing new devices to the interconnected world.

The hacking of self-driving cars (big topic it would seem) was discussed:

Fiat Chrysler Recalls

Also, the potential of hacking pacemakers was covered (bluetooth/wifi enabled), famously featured in the TV series Homeland and which actually lead to Vice President Dick Cheney’s cardiologist disabling the wireless functionality of his device:

Pacemaker Hacking
Could Pacemakers Be Hacked?

Although funny, the talk did indeed bring up a very serious issue. The ramifications could be catastrophic, depending on the types of devices that ultimately end up being exposed to the masses via the web. Essentially, as the IoT age develops, extra care must be taken to ensure that security is right on up there, in the hierarchy of priorities, when developing software for these devices.

4) Chris Bishop. Scientist and Lab Director, Microsoft Research.

The last talk I would personally like to discuss briefly was by Chris Bishop; there were a few great nuggets here that are well worth covering.

The idea of Machine Learning (not a topic I was overly familiar with for starters), Neural Networks and Pattern Recognition laid the foundation for a talk looking at the possibility of producing machines with human-level, or even super-human, intelligence.

The Microsoft Kinect was used to demonstrate hand-tracking software that, I have to admit, had an incredible amount of fidelity in recognising hand positions and shapes.

Lastly, a facial recognition demonstration that could estimate, with good accuracy, the emotional state of a person was kicked off for us all to see. Very, very impressive. There was most certainly an underlying feeling here (and as much was hinted at) that his kind of technology has many hurdles to jump. For instance, building something that can consume an image and accurately describe what is in that image is still a flaky concept, at best (and the difficulties of producing something capable of this are relatively vast).

Still, a greatly enjoyable talk! A book was touted, and I believe (please don’t shout at me if I’m wrong) this is the one:

Pattern Recognition and Machine Learning

After the morning Key Notes, a series of smaller talks and break-out sessions were available to us. Here’s how I spent my time…

Unity3D Grok Talk

Josh Taylor. Unity Technologies.

It’s my sincere hope that, on discovering this, my employer won’t decide to sack me! This was over lunch and was a self-indulgent decision I’m afraid! You’ll know from some of my historical posts that I have a keen interest in Unity3D (and have spent time making the odd modest prototype game here and there), and I was interested to see how Unity 5 was progressing, especially as a greater cohesive experience with Visual Studio had been promised.

In this short, 20 minute talk, we experienced how Visual Studio (finally) integrates nicely into the Unity3D content creation pipeline. Unity3D now defaults to using Visual Studio as the editor of choice, with Monodevelop being pushed aside. Apologies to anyone who likes Monodevelop, but I’ve never been able to get behind it. With wacky intellisense and with what I can only describe as a crash-tastic experience in past use, I haven’t seen anything yet to sway me from using Visual Studio. In fact, it was demonstrated that you can even use Visual Studio Code if you wish and, as it’s cross-platform, even Mac and Linux users can switch to this if they wish. More reasons to leave Monodevelop in the dust? It’s not for me to say really, go ahead and do what you’ve got to do at the end of the day!

In order to debug Unity projects in Visual Studio in the past a paid for plugin was required. This particular plugin has been purchased by Microsoft and is now available to all. Being able to easily debug code doesn’t sound like much, but trust me it’s like having a basic human right re-established – such good news!!!

The new licensing model was also commented on, a massive plus for everyone. The previous Free/Pro divide is no more; now everyone gets access to the lions share of the core features. You only need to start spending money as you make it (fair for Unity to ask for a piece of the pie if you start rolling in profit/expanding a team to meet the new demand). For me, this means I actually get to use the Unity Pro water effects, hoorah ;-).

Following this, I spent a bit of time last weekend watching the Unite 2015 Key Notes, discussing 2D game development enhancements, cloud based builds and Oculus support. Well worth a look if and when time allows:

Unite 2015 Key Notes

Plus, if Oculus technology interests you, then it’s definitely worth watching John Carmacks (formerly of ID Software, the mind behind Wolfenstein and Doom) Key Note from the Oculus Connect 2 event:

John Carmack Oculus Keynote

Very exciting times ahead for Unity3D I believe. Self-indulgence over, moving forward then…

Journey to the Intelligent Cloud

Corey Sanders. Director of Program Management, Azure.

Following the Unity3D talk, I made my way back to the ICC Auditorium (I missed a small section of this particular talk, but caught the bulk of it) to catch up on some basic examples of how the new Azure Portal can be used. This took the form of a brief overview of what’s available via the portal, essentially a primer session.

In my recent, personal work with Azure I’ve used the publishing capability within Visual Studio to great affect; it was very transparent and seamless to use by all accounts. A sample was provided within this particular session which demonstrated live coding changes, made in GitHub, being published back to a site hosted on Azure.

Going into a tangent….

Very much a personal opinion here, but I did find (and I wasn’t the only one) that a good portion of the content I wanted to see was a) on at the same time (the 1:15pm slot) and b) was during the core lunch period where everyone was ravenous, I’m a ‘hanger’ sufferer I’m afraid. C# with Mads Torgerson, ASP.NET 5, Nano Servers and Windows 10 (UWP) sessions all occupied this slot, which drove me a little nuts :-(. This felt like a scheduling issue if I’m honest. I’d be interested to hear from anyone who did (or didn’t) feel the same.

I was so disappointed to miss Mads Torgerson, I very much enjoyed the recent C# language features overview and would have loved to have made this breakout session! I did walk past him later in the day, and I hope he never reads this, but he seemed ridiculously tall (perhaps Godly C# skills made him appear several inches taller, who knows!). It doesn’t help that I’m on the shorter side either, I just wanted to be 5′ 11″, that’s all I ever wanted (break out the rack, I need to get stretching!). I should have said hello, but wimped out!

F# Language Breakout Session

Don Syme. Principal Researcher, Microsoft Research.

This was easily the part of the event that resonated the most with me, and strongly influenced the foray into F# that I undertook recently. Don Syme, the designer and architect of the F# language, took us through a quality primer of the syntax and how F# can be used (and scaled) for the cloud.

All of this aside, the most impressive part of the talk was a live demonstration of F# Type Providers. Again, this is fully covered in my previous post so I’ll just direct you to that, which in turn will aid me in cutting down what is now becoming a gargantuan post. In summary, the ability to draw information directly from web pages, rip data straight from files and databases, and combine and aggregate it all together using minimal code produces a terse, easy to understand and pretty darn good experience in my book. Even the code behind producing visual feedback, in the form of the charting API, is succinct; the bar really isn’t set too high for new starters to get involved.

If you decide to give anything a go in the near future, I would give F# the nod (followed closely, just a hair’s breadth away, by jQuery in my opinion). Certainly check it out if you get the chance.

Final Key Note

Professor Brian Cox. Physicist.
Krysta Svore. Senior Researcher, Microsoft Research.

The day proceeded in fast forward and, before we’d really had the chance to gather our thoughts, we were sitting in the main auditorium again faced by Professor Brian Cox, Krysta Svore and a menagerie of confused attendees staring at mathematical formulas outlining quantum theory.

Into the wonderful world of quantum computers we dance, and in my case, dragging my brain along from somewhere back yonder in a desperate attempt to keep up. Thankfully, I’m an avid TED talk fanatic and had, in the run up to the event, brushed up on a few quantum theory and quantum mechanics videos; lucky I did really. The content was dense but, for the most part, well put together and outlined the amazing (and potentially frightening) world of possibilities that quantum computers could unlock for us all.

Professor Brian Cox cruised through the theories we’d need to be intimate with in order to understand the onslaught of oncoming content surrounding quantum computers. In essence, a traditional ‘bit’, has a defined state (like a switch), on or off. However, and this is the simple essence of what they were trying to get to, traditional bits are reaching limitations that will prevent us from solving more complex problems, in a timely manner (you’ll see what I mean in a second). Therefore, qubits, born from quantum theory, are the answer.

Now, I’m not going to insult your intelligence and go into too much detail on a subject that I am clearly not an expert in. So, just in ‘laymen’s bullet points’, here is what I took from all that was said and done across the Key Note:

  • With bits, you are dealing with entities that can have a fixed state (0 or 1). A deterministic system if you will, that has limitations in its problem crunching power.
  • Qubits, however, take us into the realm of a probabilistic system. The qubit can be in a superposition of all of the allowed states, not just 0 or 1.
  • Therefore, the problem crunching powers of qubits are exponential in nature, but the probabilistic nature makes measuring them (and interactions involving them) difficult to get to grips with.

So is it worth fighting through the technical problems in order to harness qubits? What kind of gains are we talking about here?

Krystra Svore outlined an example that displayed that it would take roughly one billion years for a current super computer to crack (more complex than standard) RSA encryption. How long would it take a quantum computer you may ask? Significantly faster is the answer, estimated at around one hundred seconds in fact. This clearly defines for us the amazing problems we’ll be able to solve, whilst simultaneously illustrating the dangerous times that lay ahead from a security standpoint. Let’s just hope cryptography keeps up (I can see a few sniffs to suggest things are in the pipeline, so I will keep an eye out for news as it pops up).

So you want a quantum computer I hear you say! Hmmm, I wouldn’t put it on the Christmas list anytime soon. Due to the fact current quantum computers need to be super cooled (and from the pictures we got to see, didn’t look like you could hike around with it!), we’re not likely to get our hands directly on them in the near future.

Can you get your mitts on quantum simulators today? Apparently yes in the answer (completed untested links, just for you to peruse on your own, good luck):

QC Simulators
Project Liquid

Taking nothing away from the Key Note though, it was a concrete finish to an excellent event. Would I go again? You bet! Should we get the train next time instead of driving? Taking into account the mountains of free beer and wine on offer, of course! To finish up, before summarising the Expo itself, if you haven’t been and get the opportunity (in fact, actively seek the opportunity, enough said) then definitely book this in your calendar, thoroughly brilliant.

Expo

Very, very quickly, as I am acutely aware that your ability to focus on this post (if not already) must have completely diminished by this point, I wanted to describe what the Expo itself had to offer. If you’re still reading, give yourself a pat on the back!

One of the more compelling items we saw was the use of the new Lumia phone as a (kind of) desktop replacement attempt. Let’s get one thing straight, you’re not going to be doing hardcore software development using Visual Studio or any other intensive task on this device anytime soon. However, there was certainly enough evidence to suggest that basic productivity tasks would be possible using a mobile phone as a back bone to facilitate this.

The Lumia can be hooked up to a dock, akin to the Surface Pro 4 (the docks are subtly different apparently, so are not cross-compatible), and that allows it to be tied to a display device. You can also get a folding mouse and keyboard, for a very lightweight, on-the-go experience. Interesting certainly, but there is a definite horse-power issue that will prevent anyone working on anything remotely intensive from getting on board. Anyway, for those interested the link below will get you started:

Lumia Docking Station

I saw a few Surface Pros, and wondered whether we could potentially smuggle a few out of the Expo! Only kidding, no need to call the Police (or for anyone I work with thinking I am some kind of master criminal in the making) :-).

An Oculus demonstration booth was on the Expo floor, and displays were hooked up to show what the participants were experiencing. It was noted that a few of the people using the Oculus seemed to miss the point a bit, and kept their head completely still as they were transported through the experience. Once the heads started moving (to actually take in the world) you could visibly see people getting incredibly immersed. Alas, the queues were pretty darn large every time I made my way past, so I didn’t get a chance to experience it first-hand. One for the future.

There was also a programmable cocktail maker, an IoT masterpiece I think you’ll agree. A perfect union of hardware, software and alcohol, a visionary piece illustrating the future has arrived!

The next time an event like this comes around I will endeavour to get a post up in a timely fashion (which will vastly improve the content I hope).

Thanks for reading and a high five from me if you made it this far. Back to coding in the upcoming post I promise, until the next time, cheers from me (and would you believe it, it’s now Tuesday)!

Back Online: Normal Service Resumed

I’m back from my hiatus which encompassed getting married, eating far too much food and drinking wine and beer on the wonderful Adriatic coast. It’s time to get back to some serious coding and perhaps reconsider the longer term plans for this blog.

To start us off, I’ve been contemplating pushing a little money into this to sharpen up the experience a little and will most likely give the blog some dedicated presence on Facebook/Twitter. Why do it by halves; I’ll go balls deep and hope for the best!

There are numerous items that I previously wanted to, and still plan on, covering but other nuggets of technology have caught my eye in the interim. In addition to just writing code, I would also like to reflect on my own methodologies for learning subject matter and trying to improve comprehension as I progress on this journey. Anything I do to this end will get ‘air time’ within this blog and I’ll you all know if I come across anything that works particularly well (or falls flat on its face!) as and when it happens.

Lastly, although not strictly ‘code’ based, my wife (weird to say that!) plans on starting her own business this year so it provides us both with an opportunity to reimagine our workspace in the home. The plan is to turn our crap-hole of a box room into a useable work area; as we get stuck into this I’ll post updates to show how this evolves.

As we all know, putting something down on paper (or the internet!) is the first step on any journey. Here’s the redefined hubs of activity as I see them covering things you can expect to see on this blog in 2015/2016.

  • Reimagining of the Blog and some kind of dedicated presence on Facebook/Twitter.
  • Changes to our home workspace to show you how this progresses.
  • Updates covering any learning techniques as I study them. If these are useful to coding then expect them to get ‘air time’. For starters, look out for:
  • Coverage on the following topics (not sure on how basic/advanced this will be – Most likely this will comprise of feelers into a topic unless something really takes my fancy):
    • Finishing off the Epic Quest project.
    • F# Forays.
    • Coverage of Python.
    • Some further raw JavaScript coverage including jQuery.
    • Hello World level Raspberry Pi.
    • Coding against the Leap Motion Controller API.
    • Xamarin Tools.
    • ASP.NET MVC.
    • My friend Pete has written a superb object-orientated take on JavaScript – Picket.JS.
    • Further C# Unity game development (I still see myself covering a larger scale project encompassing the use of Blender, Gimp and Unity to make a standalone title).
    • Posts covering C# and TSQL (I’ve done some MySQL work recently so I will incorporate this into the proceedings if possible) as interesting topics catch my eye.
    • WPF (Rooting around in XAML) as time allows.

In and around this, I’m starting to sniff around the idea of completing full Microsoft Certifications in the next year to year and a half, so as I hop hurdles surrounding this I’ll give you all of the details.

This is not really designed to be a personal ransom note and I’m not going to outright hold myself to completing all of these things, but I do want to make a commitment to producing content as and when I can and keeping this fun (for myself and anyone reading along).

All that’s left to say is wish me luck and watch this space!

Code Project: Epic Quest! Starting up…

Howdy all,

As promised (somewhat belatedly!) I’m going to undertake a small coding project that, hopefully anyway, fits around my current commitments and the incredible weight of jobs I need to do before my impending wedding.

The plan, in the long term, will be to revisit Unity 3D as well as to continue the journey and forays into other technologies that I’m less familiar with. For now however, I just fancy (whether the results are good or bad) coding.

To that end I’m going to do a series of posts on creating an RPG/Adventure (classic D&D dice roller) packaged into a simple console application.

The snapshot below shows a set of stub classes, interfaces and other utility files that I’ve mocked up to start development on the project. This is all subject to change of course but I always find it relatively helpful to plan ahead and start drawing up interfaces and base classes upfront. These elements can always be removed later if it is discovered that there is a touch of over-engineering going on, therefore leading to a need to tighten the reins on a project and move to a simpler model. All of the code is presently tucked into the application project; I’ve opted to create no additional class libraries at this time (unless some interesting, reusable code comes out of this that I want to keep under source control for later use).

Epic Quest Solution

Epic Quest Solution

Most of the files are currently empty with the exception of some static utility methods and the following code in the core GameManager class.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using EpicQuest.GameEnums;
using EpicQuest.Models;
using EpicQuest.Utility;

namespace EpicQuest.Manager
{
    /// <summary>
    /// Epic Quest core GameManager class
    /// that handles general game state.
    /// </summary>
    internal class GameManager
    {
        #region Private Data Fields

        //Private List representing the party members involved with this adventure
        private List<Hero> partyMembers = new List<Hero>();

        #endregion Private Data Fields

        #region Main Game Loop Method

        /// <summary>
        /// Main Game Loop 'Start' method
        /// called from the Main entry point method of the 
        /// Program class (for this executable).
        /// </summary>
        internal void RunMainGameLoop()
        {
            //Debug information (method entered)
            Debug.WriteLine(Utils.MethodDebugMsg());

            //Game startup initialisation logic
            GameStartup();

            //Always run the game loop at least once (currently, break when user types EXIT)
            do
            {
                //Start game message
                Console.WriteLine();
                Console.Write("Do you want to venture into the dungeon? Type EXIT and hit ENTER to flee in terror or simply press ENTER to continue: ");

                //Does the user want to quit...
                if (Utils.InterpretUserInput(Console.ReadLine()) == GameAction.ExitGame)
                {
                    break;
                }

                //Clear the current game state (i.e. Party Members)
                ClearGameState();

                //Create a new Party of heroes
                CreateQuestParty();
            } 
            while (true);

            //RunMainGameLoop method exit (confirmed via the output window)
            Debug.WriteLine(Utils.MethodDebugMsg(DebugMsgType.MethodLeft));
        }

        #endregion Main Game Loop Method

        #region Private GameManager Helper Methods

        /// <summary>
        /// Private helper method that contains all of the Epic 
        /// Quest game initialisation logic (on start).
        /// </summary>
        private void GameStartup()
        {
            //Write out a formatted string (in a red text colour) that represents the Games Title
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(Utils.WriteGameTitle());

            //Reset the console to it's default colour scheme
            Console.ResetColor();
        }

        /// <summary>
        /// Private helper method that can be called to clear
        /// down the Epic Quest game state.
        /// </summary>
        private void ClearGameState()
        {
            partyMembers.Clear();
        }

        /// <summary>
        /// Private helper method (to be refactored/potentially moved) that
        /// allows the creation of a Party of heroes (currently allows 3 members).
        /// </summary>
        private void CreateQuestParty()
        {
            //Input help information - print to the console
            Console.WriteLine();
            Console.WriteLine("Create your Party (BRW = Brawler, CLR = Cleric, MAG = Mage, NEC = Necromancer, THF = Thief)...");

            //Loop three times and allow the creation of the relevant heroes
            for (int i = 0; i < 3; i++)
            {
                //Create a new hero (based on user selection)
                Console.WriteLine();
                Console.Write("Choose your hero number {0}: ", i);
                Hero newHero = null;

                switch (Utils.InterpretUserInput(Console.ReadLine()))
                {
                    case GameAction.ClericChosen:
                        {
                            newHero = new Cleric();
                        }
                        break;
                    case GameAction.MageChosen:
                        {
                            newHero = new Mage();
                        }
                        break;
                    case GameAction.NecromancerChosen:
                        {
                            newHero = new Necromancer();
                        }
                        break;
                    case GameAction.ThiefChosen:
                        {
                            newHero = new Thief();
                        }
                        break;
                    case GameAction.BrawlerChosen:
                    default:
                        {
                            newHero = new Brawler();
                        }
                        break;
                }

                //Safety check - Only add the hero if it's set correctly
                if (newHero != null)
                {
                    partyMembers.Add(newHero);
                    Console.WriteLine("{0} added to the Party.", newHero.GetType().Name);
                }
            }
        }

        #endregion Private GameManager Helper Methods
    }
}

Nothing overly ‘classy’ (bad pun, sorry!) here to kick us off. I just wanted a stub class with the main game loop placed in to give us a template. The few take away points here are that all of the hero classes (Brawler, Cleric, Mage, etc) all feed off a, currently very lightweight, ‘Hero’ base class. A simple List of type Hero is serving as a way to keep track of the different adventurers as of this iteration; this is stored within the GameManager which may well change.

A very useful language feature worth mentioning here, which comes in especially handy when programming WPF applications and working with the MVVW design pattern, is the CallerMemberName attribute. In this case I’m using it as a debug mechanism via a call to Utils.MethodDebugMsg. This attribute essentially exposes a very simple way to gain access to the calling method/properties name in a called method (without using the archaic StackFrame class).

/// <summary>
/// Internal static utility method that consumes a string method name and  
/// formats it as a short debug message (denoting when we enter or exit a method).
/// </summary>
/// <param name="msgType">The message type (have we entered or exited a method for example) as a enum. Defaulted to DebugMsgType.MethodEntered.</param>
/// <param name="methodName">The calling method name as a string</param>
/// <returns>A formatted string representing the method called (depending on the debug message type).</returns>
internal static string MethodDebugMsg(DebugMsgType msgType = DebugMsgType.MethodEntered, [CallerMemberName] string methodName = "")
{
    //If a valid method name is not provided simply return an empty string
    if (string.IsNullOrEmpty(methodName))
    {
        return string.Empty;
    }

    //Use the DebugMsgType provided to return a formatted string (Have we entered/exited the given method name). Default = string.Empty
    switch (msgType)
    {
        case DebugMsgType.MethodEntered:
            {
                return string.Format("Entered the {0} method.", methodName);
            }
        case DebugMsgType.MethodLeft:
            {
                return string.Format("Exited {0} method.", methodName);
            }
        default:
            {
                return string.Empty;
            }
    }
}

CallerMemberNameAttribute MSDN Reference

As far as architecture goes this is pretty much it for the time being.

Concept wise, I envisage a game with the following mechanics:

  • 5 Hero classes with different skills and attributes.
  • A ‘Dice’ rolling system supporting 3 different types of die (Green, Blue and Red).
  • The concept of attack and defence dice (anyone remember Hero Quest!? Would like a spin-off of that).
  • Various monsters to take on.
  • Various weapons, armour and items to interact with and the ability to sell and purchase (via a simple vendor system).
  • Basic sounds plugged in to accompany the game play.

Running the application, as it stands (with a few utility methods firing that I haven’t shown here yet), gives the following output in the console window:

Epic Quest Console Window.

Epic Quest Console Window.

You can tell you’re a developer when everything is zero indexed (hero number 0 come on down!), I probably need to change that!

As usual, comments and thoughts welcome; drop me a line if anything crosses your mind. As a little muck around, and as I’m still getting a feel for the various word press features available (the dream being to chuck some money at this later in the year), I’ve included a poll here to allow readers to pick a monster to be included in the game. Push buttons! You know you want to. Cheers all.

Event/Delegate based Notifications Manager in Unity 3D (10 minute prototype!)

Working backwards (a little anyway, what developer worth his salt doesn’t wander from task to task in a strange order after all!), and with a view to getting a new FPS project up and running as rubber-stamped in my last post, I decided to head towards something I could achieve. Namely, a tidier NotificationsManager class that didn’t rely on using Unity’s in-built object messaging functionality (and its heavy dose of reflection) and instead picked a different approach. You’ve got to do something when a heavy dose of insomnia kicks in!

Based on my own thoughts and a 2 minute trawl online this is what I’ve come up with. This definitely falls into the realm of prototype but I think something along this line could certainly have legs. So without further ado here’s a run-down of the sample project and code I’ve just cooked up, most likely with a view to improve upon once a project gets off the ground.

The game built involves collecting spheres to gain points; 50 points and you win! AAA right there I think you’ll agree! We pull the following components together to form the basic structure/functionality of this game:

  • A GameManager Class (the core class handling central game interactions).
  • A NotificationsManager class (the object responsible for handling events).
  • A PlayerController Class (handling player-centric logic/interactions).
  • A SphereScript Class (simply triggers an event to increment the players score on collision).

The Game World is structured like this:

Game World Configuration.

Game World Configuration.

As with the FPS project I created and reviewed in my previous post, this sample will utilise a core GameManager class. Only one instance of this class will exist per game (I’ve taken steps to ensure this will be a singleton object) and it will ultimately control access to the NotificationsManager directly (for other game objects to call) and handle the game win condition, aka collecting enough spheres. As a cheeky extra, which wouldn’t normally live in this class, a small piece of GUI logic has been added to render the player score in the top left hand corner of the screen.

using UnityEngine;

/// <summary>
/// The core test project GameManager.
/// </summary>
[RequireComponent(typeof(NotificationsManager))]        //A GameManager (when added in the Unity Editor) will automatically attach a NotificationsManager script (if one does not exist)
public class GameManager : MonoBehaviour
{
    #region Private Data Fields

    //A reference to the Player Controller object (on the First Person controller)
    private PlayerController playerCont = null;

    //A cheeky reference to a rectangle (to draw a score on the screen in the OnGUI method)
    private Rect screenRect = new Rect(2.0f, 2.0f, 45.0f, 30.0f);

    #endregion Private Data Fields

    #region Private Static Data Fields

    //Our core, singleton, GameManager instance
    private static GameManager gameManagerInstance = null;
    
    //A singleton instance (accessible through this class) of the NotificationsManager
    private static NotificationsManager notifications = null;

    #endregion Private Static Data Fields

    #region Public Static Properties

    /// <summary>
    /// Global access to a singleton GameManager class (for all game
    /// objects to utilise during play).
    /// </summary>
    public static GameManager GameManagerInstance 
    {
        get
        {
            //Create a new GameObject and add a GameManager script to it if it doesn't already exist (allocating this to the gameManagerInstance field)
            if (gameManagerInstance == null)
            {
                gameManagerInstance = new GameObject("GameManager").AddComponent<GameManager>();
            }

            //Return the instance for global use
            return gameManagerInstance;
        }
    }

    /// <summary>
    /// Global access to a singleton NotificationsManager class (for all game
    /// objects to utilise during play).
    /// </summary>
    public static NotificationsManager Notifications 
    {
        get
        {
            //Set the private notifications field to reference the NotificationsManager script on the GameManagerInstance.
            if (notifications == null)
            {
                notifications = GameManagerInstance.GetComponent<NotificationsManager>();
            }

            //Return the instance for global use
            return notifications;
        }
    }

    #endregion Public Static Properties

    #region Awake/Start

    /// <summary>
    /// In Unity horrific things happen when you use constructors. To that end, 
    /// ensure that only one GameManager comes into existence at game start.
    /// </summary>
    void Awake()
    {
        if (gameManagerInstance != null && gameManagerInstance.GetInstanceID() != GetInstanceID())
        {
            DestroyImmediate(gameObject);
        }
        else
        {
            gameManagerInstance = this;
            DontDestroyOnLoad(gameObject);
        }
    }

    /// <summary>
    /// After Awake, when we've establised one instance of this class for global use, ensure 
    /// that this object has a valid reference to a player object (to read out the score to 
    /// game screen). Register for the OnAllSpheresCollected event.
    /// </summary>
    void Start()
    {
        playerCont = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>();

        //As we've registered for the OnAllSpheresCollected event we don't need to check the player score
        //in the Update method (although we could as we have a PlayerController reference). When a sphere is touched it's 
        //collider will trigger an event picked up in this class (minimising the amount of processing we have to do each frame)
        Notifications.OnAllSpheresCollected += Notifications_OnAllSpheresCollected;
    }

    #endregion Awake/Start

    #region OnGUI

    /// <summary>
    /// Very rudimentary GUI operation. Write 
    /// the player score to the screen.
    /// </summary>
    void OnGUI()
    {
        if (playerCont != null)
        {
            GUI.Label(screenRect, new GUIContent(playerCont.Score.ToString()));
        }
    }

    #endregion OnGUI

    #region Event Handlers

    /// <summary>
    /// Pick up on the NotificationsManager triggering the 
    /// OnAllSpheresCollected event. In this case, this is the 
    /// win condition for the game (simply close and exit).
    /// </summary>
    /// <param name="sender">The component that triggered the event (PlayerController).</param>
    void Notifications_OnAllSpheresCollected(Component sender)
    {
        //We could interrogate the state of the Component here if we needed to (aka the player controller).

#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#else
        Application.Quit();
#endif
    }

    #endregion Event Handlers
}

Beforehand, our NotificationsManager maintained a list of strings/components and used the strings (as defined event names) to call the SendMessage method on applicable objects. The GameManager listed above begins to hint at a slightly different approach in this regard. Notice, within the Start method, how an event is being registered (against the NotificationsManager OnAllSpheresCollected event) instead with a handler being exposed within this class; making this class a listener for this event. The Notifications_OnAllSpheresCollected event, which could easily have been an anonymous method (using a lambda expression) has been mocked up to simply end the game.

A NotificationsManager component, as before, is still marked as required and will be added whenever a GameManager script is added to a GameObject within the Unity Editor. Below is an illustration of how the GameManager object is configured in the Unity Editor; showing the scripts added for reference:

Game Manager Configuration.

Game Manager Configuration.

Let’s get into the real beef (not that there is much ‘beef’ in this project, it’s more of a low-fat implementation really!) of the changes made to the NotificationsManager. The tweaked mock-up relies on a single delegate outlining a method that has no return type, which I could expand on later down the line if necessary, and that supports a single argument of type ‘Component’ (most likely another script).

Two public events are then configured to allow objects to register as listeners for the ‘sphere collected’ and ‘all spheres collected’ events. In the first iteration listed here I haven’t given consideration yet to how this should ultimately work (i.e. should these be instance or object level based, aka static – Perhaps even considering the whole class declaration), it’s bare bones. As the NotificationsManager exists as a singleton in the previous project (is instance based), and I only want to prove a concept, having these as non-static and accessible at the instance level works ok for now and allows appropriate access through the GameManager instance.

Finally, two public methods allow objects to ‘post’ notifications to any listening objects, provided the event handler is not null.

using UnityEngine;

/// <summary>
/// Test implementation of a NotificationsManager class
/// using an event/delegate foundation.
/// </summary>
public class NotificationsManager : MonoBehaviour
{
    #region Delegates

    /// <summary>
    /// A delegate representing (outlining) a method that has no return type
    /// and takes a single component as an argument (would have sufficed for the entirety
    /// of the last project I created).
    /// </summary>
    /// <param name="sender">A game component object (a component part of a game object).</param>
    public delegate void ComponentEventHandler (Component sender);

    #endregion Delegates

    #region Component Event Handlers

    /// <summary>
    /// Allows registration for the OnSphereCollected event.
    /// </summary>
    public event ComponentEventHandler OnSphereCollected;

    /// <summary>
    /// Allows registration for the OnAllSpheresCollected
    /// event (essentially our 'win' condition).
    /// </summary>
    public event ComponentEventHandler OnAllSpheresCollected;

    #endregion Component Event Handlers

    #region Public Event Triggers

    /* The meat of the NotificationsManager lies here */

    /// <summary>
    /// Trigger an event on all listeners 
    /// registered with the OnSphereCollected event.
    /// </summary>
    /// <param name="sender">A game component object (a component part of a game object).</param>
    public void SphereCollected(Component sender)
    {
        //Only trigger the event if something is registered
        if (OnSphereCollected != null)
        {
            OnSphereCollected(sender);
        }
    }

    /// <summary>
    /// Trigger an event on all listeners 
    /// registered with the OnAllSpheresCollected event. 
    /// </summary>
    /// <param name="sender">A game component object (a component part of a game object).</param>
    public void AllSpheresCollected(Component sender)
    {
        //Only trigger the event if something is registered
        if (OnAllSpheresCollected != null)
        {
            OnAllSpheresCollected(sender);
        }
    }

    #endregion Public Event Triggers
}

The NotificationsManager is inherently tied to the GameManager and exists on the same GameObject, in the Unity Editor, as the Game Manager.

We’ve started to see the concept of how an event/delegate system could work in Unity for listening/posting objects. The player and sphere objects and associated scripts should hopefully prove the concept in a very basic sense.

Starting with the PlayerController class; the implementation simply allows for a players score to be recorded and the object to be marked as a listener for any object triggering the OnSphereCollected event. This is taken care of by the logic found with the Start initialisation method and the Notifications_OnSphereCollected event handler. The event handler, triggered by a sphere on collision, will just increment the players score by 10 points. If the players score hit 50 points or above then an AllSpheresCollected event can be triggered for all listening objects.

using UnityEngine;

/// <summary>
/// Class representing the player (state, etc).
/// </summary>
public class PlayerController : MonoBehaviour
{
    #region Unity Inspector Public Variables

    /// <summary>
    /// The Players Score. Made public to surface in the 
    /// Unity Editor for fiddling, prevents encapsulation that drives me
    /// a little nuts. Oh well, sigh :o(
    /// </summary>
    public int Score = 0;

    #endregion Unity Inspector Public Variables

    #region Start

    /// <summary>
    /// PlayerController initialistion logic. In this case, simply
    /// register this class as a listener of the OnSphereCollected event
    /// (so we can increment the score and delegate win condition handling to the 
    /// GameManager (as this would likely have more stuff to do, aka further level loading, etc)).
    /// </summary>
    void Start()
    {
        GameManager.Notifications.OnSphereCollected += Notifications_OnSphereCollected; 
    }

    #endregion Start

    #region Event Handlers

    /// <summary>
    /// OnSphereCollected event handler (will be triggered by
    /// a sphere when it's collider comes into contact with the player).
    /// </summary>
    /// <param name="sender"></param>
    void Notifications_OnSphereCollected(Component sender)
    {
        //Debug (check sender object type for reference)
        if (sender != null)
        {
            Debug.Log(sender.GetType());
        }

        //Increment score
        Score += 10;

        //Game won
        if (Score >= 50)
        {
            //It might be more than the GameManager that needs to know about this - This call would take care of all registered objects (listeners)
            GameManager.Notifications.AllSpheresCollected(this);
        }
    }

    #endregion Event Handlers
}

In addition, notice the little bit of debugging listed in the Notifications_OnSphereCollected event handler. We’ll see this in action a little later on. The Player, First Person Controller, GameObject configuration is as follows:

Player Configuration.

Player Configuration.

The last component we need is something that will trigger our NotificationsManager.SphereCollected method; in turn triggering the relevant event to move the game forward (and push the player towards the AllSpheresCollected event that will end the game). The following class definition completes the puzzle.

using UnityEngine;

/// <summary>
/// Class representing Sphere interaction logic.
/// </summary>
public class SphereScript : MonoBehaviour
{
    #region OnTriggerEnter Event

    /// <summary>
    /// OnTriggerEnter event that handles collisions between the object
    /// attached to this script on other colliders.
    /// </summary>
    /// <param name="other">A reference to the colliding object.</param>
    void OnTriggerEnter(Collider other)
    {
        //If this sphere comes into contact with something that isn't the player then return
        if (!other.CompareTag("Player"))
        {
            return;
        }

        //Trigger the sphere collected event and hide this game object
        GameManager.Notifications.SphereCollected(this);
	    gameObject.SetActive(false);
    }

    #endregion OnTriggerEnter Event
}

When a sphere collides with another object the objects tag is inspected. If the object turns out to be the player we can post a notification to the public method found on the NotificationsManager class to trigger the appropriate event (sphere collected) on all listening objects. The final configuration of the sphere GameObject looks like this:

Sphere Configuration.

Sphere Configuration.

Proof is in the pudding so they say so let’s spin the game up and see if we can:

  1. Physically ‘collect’ sphere objects and see the players score increment by 10 points (proving that the OnSphereCollected event is being handled).
  2. Verify that the game ends when the players score is equal to or greater than 50 points (proving that the OnAllSpheresCollected event is being handled).
  3. Verify we receive appropriate debug information during the game.

So, the game fires up and our sphere collecting quest begins!

We’ve toiled hard and finally triumphed; the first sphere has been discovered! Our score is currently 0:

Before sphere 'collection'.

Before sphere ‘collection’.

Let’s pick that sucker up. Walking towards the sphere increments our points score by 10 (and triggers debug information as expected):

After sphere 'collection'.

After sphere ‘collection’.

Collecting 5 spheres, equaling 50 points, ends the game. Hoorah!

I call that a successful test of a 10 minute prototype. I’ve got a strong feeling that, under load, this will definitely perform better than the SendMessage approach and this is still very much open to refinement; given a few hours to think about it I’ll probably overhaul everything. It’s possible to bypass the events entirely and just use raw delegates or setup interface based solutions. However, this seems like a nice step up from the implementation I originally had introduced to me during the previous project.

I’ll definitely plod my way over to Blender shortly and get working on content creation but I’m happy that, given a short amount of time, I can come up with modest solutions to improve upon the backbone components of any proposed game engine I plan to write. I wanted to share the most simple implementation I could think of; this is by no means a complex or definitive example, but I hope it proves a point. If anyone reading does have any suggestions or links to ‘you should do it this way, it’s the best’ documentation or resources then I’d be happy to hear about it.

Signing off!

Forays in Unity 3D Game Development…For sh*ts and giggles

Good evening all,

I hope everyone has been having a super, duper New Year so far. In the process of getting back into the swing of things at work and preparing for my impending big day (well, I say impending, June – Nevertheless I’m sure it’ll come around quickly!) I’ve been spending little pockets of time looking at game development. Specifically, rooting around in Unity 3D in the efforts to produce an FPS shooter.

I ended up with a small wedge of cash for Christmas so I did what anyone nowadays does (not save for the wedding, cough cough) and splurged on a few development books. In addition to a book on AI programming and shaders this little number also crossed my path:

Pro Unity Game Development with C#

The content has been pretty damn good by all accounts and the resources provided have been top notch. The parts that have particularly caught my eye in my short time with this so far have been in handling event notifications between game objects and general asset management (i.e. the import and configuration of meshes created in Blender/Maya). The events manager, as implemented here, is an incredibly simple configuration that consists of the following NotificationsManager class:

using UnityEngine;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// Represents our core Event Handling Class for the 
/// CMOD FPS game.
/// </summary>
public class NotificationsManager : MonoBehaviour
{
    #region Private Data Fields

    //Private dictionary that tracks listeners for given event types
    private Dictionary<string, List<Component>> listeners = new Dictionary<string, List<Component>>();

    #endregion Private Data Fields

    #region Public Methods

    /// <summary>
    /// Ties the provided listener object (component) to the specified
    /// event type. If the event type is not yet being handled then a new dictionary 
    /// entry is created for the event type (notification name) and a new list of components
    /// instantiated ready for additions as required.
    /// </summary>
    /// <param name="sender">The component to be notified of a given event.</param>
    /// <param name="notificationName">The event to tie to the provided listener object.</param>
    public void AddListener(Component sender, string notificationName)
    {
        //Check to see if this notification (event) type is currently stored locally. If not, create a new dictionary entry for it
        if (!listeners.ContainsKey(notificationName))
        {
            listeners.Add(notificationName, new List<Component>());
        }

        //Tie a listener object to the given notification (event) type
        listeners[notificationName].Add(sender);
    }

    /// <summary>
    /// Allow specific listeners to unregistered themselves for a given
    /// event/notification type.
    /// </summary>
    /// <param name="sender">The object that no longer needs to listen for the given event.</param>
    /// <param name="notificationName">The event/notification type to be removed from.</param>
    public void RemoveListener(Component sender, string notificationName)
    {
        //Debug.Log("Removing listeners");

        //See if the notification type is supported currently. If not, then return
        if (!listeners.ContainsKey(notificationName))
        {
            return;
        }

        //Remove 'all' references that match (by instance id) for the given notification type
        listeners[notificationName].RemoveAll(li => li.GetInstanceID() == sender.GetInstanceID());
    }

    /// <summary>
    /// Allow for an event 'poster' to trigger a named method (based on the notification
    /// name) on all listening objects.
    /// </summary>
    /// <param name="sender">The poster who has latched onto an event in the first instance.</param>
    /// <param name="notificationName">The event/notification name (ties to a method name on listening objects).</param>
    public void PostNotification(Component sender, string notificationName)
    {
        //If there are no references based on the notification name then simply return (no work to do)
        if (!listeners.ContainsKey(notificationName))
        {
            return;
        }

        //Notify each, relevant, object of that a specific event has occurred
        listeners[notificationName].ForEach(li =>
        {
            if (li != null)
            {
                li.SendMessage(notificationName, sender, SendMessageOptions.DontRequireReceiver);
            }
        });
    }

    /// <summary>
    /// Removes redundant listeners (to cover scenarios where objects might be removed
    /// from the scene without detaching themselves from events).
    /// </summary>
    public void RemoveRedundancies()
    {
        //Create a new dictionary (ready for an optimised list of notifications/listeners)
        Dictionary<string, List<Component>> tempListeners = new Dictionary<string, List<Component>>();
        
        //Iterate through the notification/listener list and removing null listener objects. only keep a notification/listener dictionary entry if one or more
        //listening objects still exist for a given notification
        listeners.ToList().ForEach(li =>
        {
            li.Value.RemoveAll(listObj => listObj == null);

            if (li.Value.Count > 0)
            {
                tempListeners.Add(li.Key, li.Value);
            }
        });

        //Set the listener dictionary based on the optimised/temporary dictionary
        listeners = tempListeners;
    }
    
    /// <summary>
    /// Removes all listener dictionary references.
    /// </summary>
    public void ClearListeners()
    {
        listeners.Clear();
    }
    
    #endregion Public Methods
}

Using a centralised game manager class (that holds a reference to a single instance of the NotificationsManager class) it’s been surprisingly quick to setup a solid event based system. I want to tweak this implementation however for future projects. As you can see here, this class revolves around a dictionary of type string/Component. This allows for classes registering as ‘listeners’ for a given event to provide a reference to themselves (the component) along with a string representing an event name (which matches a public method implemented on the class registering as a listener). For this to work, posting notifications relies on calling the SendMessage method on listening objects, a process which relies heavily on reflection based on my studies. In a small scale project where limited amounts of messages will be getting passed around this will perform fine (and this has been the case thus far for me). In the long run however (maybe my next project), it seems like a better approach will be to define interfaces and perhaps use a dedicated system structured around delegates. High levels of reflection are not going to cut the mustard when the levels of notifications being passed around start hitting even modest levels.

As far as handling the content pipeline and getting stuck into Lightmapping, Navigation Meshes (for AI Pathfinding) and the construction of Colliders when importing assets the instruction provided has been incredibly easy to follow.

Sprites are provided with the book assets and with a couple of basic scripts it was fairly simple to get a billboard sprite enemies up and running (with flip-book style animations). I’ve worked with 3D models in the past (using the Unity Mecanim system) and have produced rigged and animated models but I’ve really enjoyed utilising some 2D animation techniques (quite a bit of the 2D support now in Unity is quite new so it’s always great to skim over new material like this).

Unity UI.

Unity UI.

The enemies themselves use a basic FSM (Finite State Machine) to manage Patrol, Chase and Attack states as shown below. I’ve defined the class as abstract with the coroutines that handle each enemy state made virtual (to allow certain enemies to override the behaviour as necessary). Surfacing variables in the Unity Editor requires them to be public (and they can’t be properties), something that is driving me a little nuts – Treating as a nuance for the time being:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// Abstract base class that outlines the 
/// concept of an enemy.
/// </summary>
public abstract class Enemy : MonoBehaviour
{
    #region Public Enums

    /// <summary>
    /// Enum state for the enemy FSM.
    /// </summary>
    public enum EnemyState
    {
        Patrol = 0,
        Chase = 1,
        Attack = 2
    }

    /// <summary>
    /// Enum for enemy types.
    /// </summary>
    public enum EnemyType
    {
        Drone = 0,
        ToughGuy = 1,
        Boss = 2
    }

    #endregion Public Enums

    #region Unity Inspector Public Variables

    /// <summary>
    /// The enemies type.
    /// </summary>
    public EnemyType Type = EnemyType.Drone;

    /// <summary>
    /// Active enemy state (defaulted to patrol).
    /// </summary>
    public EnemyState ActiveState = EnemyState.Patrol;

    /// <summary>
    /// The custom ID of this enemy.
    /// </summary>
    public int EnemyID = 0;

    /// <summary>
    /// Represents the enemies current health.
    /// </summary>
    public int Health = 100;

    /// <summary>
    /// Attack Damage - amount of damage the enemy
    /// deals to the player.
    /// </summary>
    public int AttackDamage = 10;

    /// <summary>
    /// Recovery delay in seconds after launching an attack.
    /// </summary>
    public float RecoveryDelay = 1.0f;

    /// <summary>
    /// Total distance in Unity Units from current position 
    /// that agent can wander when patrolling.
    /// </summary>
    public float PatrolDistance = 10.0f;

    /// <summary>
    /// Total distance the enemy must be from player, in Unity units, before
    /// chasing them (entering chase state).
    /// </summary>
    public float ChaseDistance = 10.0f;

    /// <summary>
    /// Total distance enemy must be from the player before
    /// attacking them.
    /// </summary>
    public float AttackDistance = 0.1f;

    #endregion Unity Inspector Public Variables

    #region Protected Fields

    //Reference to the active PlayerController component for the player
    protected PlayerController playerCont = null;

    //Enemy cached transform
    protected Transform thisTranform = null;

    //Reference to the player transform
    protected Transform playerTransform = null;

    //The Nav Mesh attached to this enemy (for pathfinding)
    protected NavMeshAgent agent = null;

    #endregion Protected Fields

    #region Start

    /// <summary>
    /// Initialisation logic for an enemy.
    /// </summary>
    protected virtual void Start()
    {
        //Retrieve the Nav Mesh Agent for this enemy (cache it)
        agent = GetComponent<NavMeshAgent>();

        //How about? Get reference to player controller by using the controller 'tag'
        playerCont = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>();

        //Get player transform
        playerTransform = playerCont.transform;

        //This enemies transform
        thisTranform = transform;

        //Set default state
        ChangeState(ActiveState);

        GameManager.Notifications.AddListener(this, "SaveGamePrepare");
        GameManager.Notifications.AddListener(this, "LoadGameComplete");
    }

    #endregion Start

    #region Public Methods

    /// <summary>
    /// Change AI State.
    /// </summary>
    /// <param name="ActiveState"></param>
    public void ChangeState(EnemyState state)
    {
        //Maybe consider checking the state? Has it changed?

        //First, stop all currently running AI processing
        StopAllCoroutines();

        //Set new state and activate it
        ActiveState = state;

        //Start coroutines and in each case notify the game object in case we want to handle state change (might not just be here, perhaps in other components)
        switch (ActiveState)
        {
            case EnemyState.Attack:
                {
                    StartCoroutine(AiAttack());
                    SendMessage("Attack", SendMessageOptions.DontRequireReceiver);
                    return;
                }
            case EnemyState.Chase:
                {
                    StartCoroutine(AiChase());
                    SendMessage("Chase", SendMessageOptions.DontRequireReceiver);
                    return;
                }
            case EnemyState.Patrol:
                {
                    StartCoroutine(AiPatrol());
                    SendMessage("Patrol", SendMessageOptions.DontRequireReceiver);
                    return;
                }
            default:
                {
                    return; //Nothing else to do, return
                }
        }
    }

    /// <summary>
    /// Prepare data to save this enemy.
    /// </summary>
    /// <param name="sender">The component sender object.</param>
    public void SaveGamePrepare(Component sender)
    {
        //Create a reference for this enemy
        LoadSaveManager.GameStateData.DataEnemy thisEnemy = new LoadSaveManager.GameStateData.DataEnemy();
        
        //Fill in data for the current enemy
        thisEnemy.EnemyID = EnemyID;
        thisEnemy.Health = Health;
        thisEnemy.PosRotScale.X = thisTranform.position.x;
        thisEnemy.PosRotScale.Y = thisTranform.position.y;
        thisEnemy.PosRotScale.Z = thisTranform.position.z;
        thisEnemy.PosRotScale.RotX = thisTranform.localEulerAngles.x;
        thisEnemy.PosRotScale.RotY = thisTranform.localEulerAngles.y;
        thisEnemy.PosRotScale.RotZ = thisTranform.localEulerAngles.z;
        thisEnemy.PosRotScale.ScaleX = thisTranform.localScale.x;
        thisEnemy.PosRotScale.ScaleY = thisTranform.localScale.y;
        thisEnemy.PosRotScale.ScaleZ = thisTranform.localScale.z;
        
        //Add this enemy to the list
        GameManager.StateManager.GameState.Enemies.Add(thisEnemy);
    }

    /// <summary>
    /// Prepare data to load this enemy.
    /// </summary>
    /// <param name="sender">The component sender object.</param>
    public void LoadGameComplete(Component sender)
    {
        //Cycle through enemies and find matching ID
        List<LoadSaveManager.GameStateData.DataEnemy> enemies = GameManager.StateManager.GameState.Enemies;

        //Reference to this enemy
        LoadSaveManager.GameStateData.DataEnemy thisEnemy = null;

        for (int i = 0; i < enemies.Count; i++)
        {
            if (enemies[i].EnemyID == EnemyID)
            {
                //Found enemy. Now break break from loop
                thisEnemy = enemies[i];
                break;
            }
        }

        //If we can't find this enemy then it must have been destroyed on save
        if (thisEnemy == null)
        {
            DestroyImmediate(gameObject);
            return;
        }
          
        //We've got this far so load the enemy data
        EnemyID = thisEnemy.EnemyID;    //This is set from the inspector so not much point in reloading, keeping with the book code however
        Health = thisEnemy.Health;
            
        //Set position, rotation and scale (position done with warp)
        agent.Warp(new Vector3(thisEnemy.PosRotScale.X, thisEnemy.PosRotScale.Y, thisEnemy.PosRotScale.Z));
        thisTranform.localRotation = Quaternion.Euler(thisEnemy.PosRotScale.RotX, thisEnemy.PosRotScale.RotY, thisEnemy.PosRotScale.RotZ);
        thisTranform.localScale = new Vector3(thisEnemy.PosRotScale.ScaleX, thisEnemy.PosRotScale.ScaleY, thisEnemy.PosRotScale.ScaleZ);
    }

    #endregion Public Methods

    #region Coroutines

    /// <summary>
    /// AI method that handles attack behaviour for the enemy.
    /// Can exit this state and enter either patrol or chase.
    /// </summary>
    /// <returns>IEnumerator.</returns>
    public virtual IEnumerator AiAttack()
    {
        //Stop agent, ready for a new instruction
        agent.Stop();

        //Elapsed time, to calculate strike intervals (set to recovery delay so an attack is possible immediately after the enemy closes distance)
        float elapsedTime = RecoveryDelay;

        //Loop forever while in the attack state
        while (ActiveState == EnemyState.Attack)
        {
            //Update elapsed time
            elapsedTime += Time.deltaTime;

            //Check distances and state exit conditions
            float distanceFromPlayer = Vector3.Distance(thisTranform.position, playerTransform.position);

            //If outside of chase range, then revert to patrol
            if (distanceFromPlayer > ChaseDistance)
            {
                ChangeState(EnemyState.Patrol);
                yield break;
            }

            //If outside of attack range, then change to chase
            if (distanceFromPlayer > AttackDistance)
            {
                ChangeState(EnemyState.Chase);
                yield break;
            }

            //Make strike
            if (elapsedTime >= RecoveryDelay)
            {
                elapsedTime = 0;
                SendMessage("Strike", SendMessageOptions.DontRequireReceiver);
            }

            //Wait until the next frame
            yield return null;
        }
    }

    /// <summary>
    /// AI method that handles attack behaviour for the enemy.
    /// Can exit this state and enter either attack or patrol.
    /// </summary>
    /// <returns>IEumerator.</returns>
    public virtual IEnumerator AiChase()
    {
        //Stop agent, ready for a new instruction
        agent.Stop();

        //Whilst we are in the chase state then loop forever
        while (ActiveState == EnemyState.Chase)
        {
            //Set destination to the player
            agent.SetDestination(playerTransform.position);

            //Check the distance between the enemy and the player to look for state changes
            float distanceFromPlayer = Vector3.Distance(thisTranform.position, playerTransform.position);

            //If within attack range then alter to that state
            if (distanceFromPlayer < AttackDistance)
            {
                ChangeState(EnemyState.Attack);
                yield break;
            }

            //Enemy is out of range to chase, revert to the patrol state
            if (distanceFromPlayer > ChaseDistance)
            {
                ChangeState(EnemyState.Patrol);
                yield break;
            }

            //Wait until the next frame
            yield return null;
        }
    }

    /// <summary>
    /// AI method that handles attack behaviour for the enemy.
    /// Can only enter the chase state from here (once the distance
    /// to the player closes sufficiently).
    /// </summary>
    /// <returns>IEnumerator.</returns>
    public virtual IEnumerator AiPatrol()
    {
        //Stop agent, ready for a new destination
        agent.Stop();

        //Loop forever whilst in the patrol state
        while (ActiveState == EnemyState.Patrol)
        {
            //Get random location destination on the map (somewhere within a sphere with a radius based on PatrolDistance (center at zero))
            Vector3 randomPosition = (Random.insideUnitSphere * PatrolDistance);

            //Add as offset from current position
            randomPosition += thisTranform.position;

            //Get nearest valid position (on the Nav Mesh)
            NavMeshHit hit;
            NavMesh.SamplePosition(randomPosition, out hit, PatrolDistance, 1);

            //Set destination for this enemy
            agent.SetDestination(hit.position);

            /*
             * Set distance range between object and destination to classify as 'arrived' +
             * Set timeout before new path is generated (as a fail safe, destination too far or enemy could be having difficulty reaching the location) +
             * Create a elapsed time float to measure against the timeout
            */
            float arrivalDistance = 2.0f, timeOut = 5.0f, elapsedTime = 0;

            //Wait until the enemy reaches the destination or times-out, then get the new position
            while (Vector3.Distance(thisTranform.position, hit.position) > arrivalDistance && elapsedTime < timeOut)
            {
                //Update elapsed time
                elapsedTime += Time.deltaTime;

                //Can only enter chase (once the distance closes sufficiently). Can then move to other FSM states from there
                if (Vector3.Distance(thisTranform.position, playerTransform.position) < ChaseDistance)
                {
                    ChangeState(EnemyState.Chase);
                    yield break;
                }

                yield return null;
            }
        }
    }

    #endregion Coroutines
}

Coroutines (that have a return type of IEnumerator) are a useful feature within the Unity engine that allow you to mimic asynchronous behaviour. When previously using Unity, I would definitely be guilty of cramming all of the logic into the Update method (run every frame) which invariably lead to performance issues. Using an event based system and coroutines it’s been possible (in most cases) to abstract heavy lifting code out of areas where it gets hit every frame and is instead called when required (or as a side-line to the main thread).

This class also showcases the use of a NavMeshAgent. During the patrol state (where the most interesting implementation lies) a location is ‘sampled’ and then the nearest, valid position found on the scene Navigation Mesh is chosen as the enemy destination. When the destination is reached, within a certain tolerance range (time out also provided just in case), the enemy marches on his way to the next generated destination (until the player is found and a different state is initiated or the enemy is killed). This works surprisingly well.

I’ve got a book that talks through more advanced scenarios using Behaviour Trees which I’ll try and implement in a future project.

In all honesty, I think that’s probably where I’m headed. The assets provided in this book allow the rapid creation of a modular level environment and to this end the internet has been scoured for tutorials on creating this in Blender (including environment texturing and UV creation). I’ve picked a direction for this blog at long last, hoorah! A preliminary promise of sorts then…I aim to cover (not all strictly code based but indulge me!):

  1. Stick with the FPS formula and create a new project from scratch.
  2. Undertake some 3D content creation in Blender (modular environments and UV creation). I don’t have a clue what I’m doing here so I expect that to be damn funny to witness!
  3. Keep with the 2D sprite setup for enemies, perhaps making a set of 5 or 6 enemy types and at least 3 weapon types.
  4. Make a handful of 3D game world assets using Blender.
  5. Implement an enhanced NotificationsManager in Unity.
  6. Get all of the content into Unity and make a multi-level FPS shooter.
  7. Investigate the new UI components in Unity (to build a dynamic GUI of some sort).
  8. Produce my own sound content. I’ve tried this already via some online music/sound effect creation tools, the results were not good. If my brother is reading this he’ll know that I’ve never been all that musical and is probably cringing at the thought of anything knocked up by me in this department!

Big promises eh! Let’s see what gets delivered. I’m not expecting an AAA experience to fall out of the dredges of my file system and arrive on the doorstep of steam, this will just be for fun!

I’ll leave you with a few screenshots taken from the (pretty much finished) product. Enjoy!

Gun-play in action.

Gun-play in action.

Getting beaten around the head by an enemy drone.

Getting beaten around the head by an enemy drone.

Options GUI.

Options GUI.

Collecting cash before getting gunned down.

Collecting cash before getting gunned down.