Category Archives: Game Development

Building Block Game in Unity 3D

Not sure this qualifies as a game, but it’s a computerised version of the building blocks that you might give to a three-year-old. What can I say, it was a nice way to spend a Sunday afternoon !

Here’s what the finished game / program looks like:

The Script

There is only one script:

public class BehaviourScript : MonoBehaviour
{
    
    private Vector3 screenPoint;
    private Vector3 offset;
 
    void OnMouseDown()
    {
        screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
        offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
    }
 
    void OnMouseDrag()
    {
        Vector3 cursorPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
        Vector3 cursorPosition = Camera.main.ScreenToWorldPoint(cursorPoint) + offset;
 
        if (cursorPosition.y > 0)
        {
            transform.position = cursorPosition;
        }
    }
}

The Scene

Basically, the blocks are standard unit cubes with a wood texture, a rigid body and the above script attached:

Mesh Colliders in Unity

Mesh colliders are, generally speaking, a bad idea in Unity. The reason being that they cause collision based on the detailed mesh that forms the object. This is bad, basically because this generates many collision points. Consider this object:

meshcollider1

As you can see, it’s a basic cylinder (a cup), so a box collider would add eight collision points. A mesh collider generates a point for each of the 496 vertices.

meshcollider2

So, whilst it’s more accurate, it uses more resources.

Okay, so now I’ve said why you shouldn’t use a mesh collider, I’ll cover how to use them.

Firstly, you need to add a mesh collider:

meshcollider3

There are three important things to note here:

  1. There is a mesh collider
  2. It is convex
    1. The convex flag allows the collider to collide with other colliders
  3. It is not a trigger
    1. The trigger flag turns the collision into a programmatic notification only

The manual for this is here.

Adding Cheats and Features to a Unity Game for Development Only

I’m currently writing a breakout style game (which, if you’ve seen any of my previous posts, you might have divined). One of the things that I would like to do with this, without having to play through all the levels is to complete the level quickly. This led me down the path of creating a “Cheat” button. However, for those amongst you that remember the ZX Spectrum, the makers of Jet Set Willy may have had a similar idea, but left the “Pokes” in the final game.

To avoid this, I thought it must be possible to use a feature such as the compiler directive in C#. In fact it is. Unity has its own, and one is to determine whether you’re running in the editor.

Here’s how I conditionally display the button:

    void OnGUI()
    {
#if UNITY_EDITOR
        if (GUI.Button(new Rect(10, 30, 50, 30), "Cheat"))
        {
            var o = GameObject.FindGameObjectsWithTag("Brick");
            foreach (var b in o)
            {
                var r = b.GetComponent<Rigidbody>();
	        r.transform.position += new Vector3(0, 0, zOffset);
                r.useGravity = true;
            }
        }
#endif
    }

This particular cheat just makes all of the bricks fall out of the sky. UNITY_EDITOR is one of a list of pre-defined “Platform Defines” that can be found here.

Saving and Loading Level Data in Unity

This describes a method of persisting data in Unity. For example, saving and loading the current game level.

The first thing that you will need is to create a helper class to read and write the data that you need:

        public static void SaveGameState()
        {
            XmlDocument xml = new XmlDocument();
            var el = xml.CreateElement("PlayerStatus");
            el.SetAttribute("CurrentLevel", Application.loadedLevel.ToString());
            xml.AppendChild(el);
            xml.Save("data.xml");
        }

        public static void LoadGameState()
        {
            XmlDocument xml = new XmlDocument();
            xml.Load("data.xml");
            var el = xml.GetElementsByTagName("PlayerStatus")[0];
            string currentLevel = el.Attributes["CurrentLevel"].Value;
            int loadLevel = 0;
            if (!string.IsNullOrEmpty(currentLevel))
            {
                loadLevel = int.Parse(currentLevel);
                if (Application.loadedLevel != loadLevel)
                    Application.LoadLevel(loadLevel);
            }
        }

The next stage is to plug this into Unity. I put the following in a Master Script (which is essentially just a script associated with an empty game object).


    void OnApplicationQuit()
    {
        GameState.SaveGameState();       
    }

    void Start()
    {
        GameState.LoadGameState();
    }

I’ve seen plenty of articles on using serialisation for this, and that would obviously have the same effect, but this is another option.

Working with the threading system in Unity

Unity seems to have a multi-threaded system, but I could find no way of accessing the dispatcher. Consequently, it’s necessary to create some kind of self-rolled task queue. The specific problem that I faced was with using the timer; here’s the code for the timer:

public class MasterScript : MonoBehaviour
{
    private Timer _timer;

    void Start ()
    {
        _timer = new Timer();
        _timer.Interval = 1000;
        _timer.Elapsed += _timer_Elapsed;
        _timer.Start();
    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        SpawnNewObject();
    }
}

The idea being that every second, and new object would appear on the screen. However, as soon as you run this, it crashes (or as close as Unity comes to crashing):

FindGameObjectWithTag can only be called from the main thread

The solution that I came up with was as follows:

public class MasterScript : MonoBehaviour
{
    public static Queue<Action> TaskQueue;

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        SpawnNewObject();
    }

    private void SpawnNewObject()
    {
        TaskQueue.Enqueue(() =>
        {
            var newObj = Instantiate<GameObject>(MyObject);

Then, simply change the Update function to run them:

    void Update ()
    {
        if (TaskQueue.Count > 0)
        {
            TaskQueue.Dequeue().Invoke();
        }
    }

I’ve used the idea of a “Master Script” to deal with the queue, and this can be queued to from somewhere else in the game, which makes it more flexible.

Advancing to the next Level in Unity

I’m quite new to Unity, and so thought I would start blogging useful things that I’ve discovered. Obviously, there is the which is basically where all this information comes from, and also an excellent tutorial on YouTube. I found this after trying a Pluralsight course on Unity, but rapidly losing the will to live while watching it.

In my particular example, I have a game, whereby touching a specific object progresses to the next level. Here’s the code (against the target object):

    void OnCollisionEnter()
    {
        if (Application.loadedLevel < Application.levelCount)
            Application.LoadLevel(Application.loadedLevel + 1);
        
    }

I admit, it’s not exactly rocket science, but it took me a while to work this out. I spent some time trying to parse the level name, and other workarounds, before I spotted that it’s all in the Application object.

Handling Input in XNA / MonoGame

This morning I didn’t have internet access and was trying to find this in my notes (which are also my blog posts), and I couldn’t; so purely for my own benefit, the following is a method of handling touch or mouse input in Monogame:

        public void HandleInput()
        {
            ProcessMouseInput();
            ProcessTouchInput();
            ProcessKeyboardInput();
        }

        private void ProcessMouseInput()
        {
            var currentMouse = Microsoft.Xna.Framework.Input.Mouse.GetState();

            if (currentMouse.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
            {
                HandlePressed(currentMouse.Position, _controlledObject);
            }
        }

        private void ProcessTouchInput()
        {
            var currentTouch = Microsoft.Xna.Framework.Input.Touch.TouchPanel.GetState();

            foreach (var touch in currentTouch.Where(t => t.State == Microsoft.Xna.Framework.Input.Touch.TouchLocationState.Pressed))
            {
                HandlePressed(touch.Position, _controlledObject);
            }


        }

        private void ProcessKeyboardInput()
        {
            var currentKeys = Microsoft.Xna.Framework.Input.Keyboard.GetState();
            if (currentKeys.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Left))
            {
                _handler.GoLeft(_controlledObject);

By changing Pressed to Released, you can detect when the mouse button click / touch finished; however, if you hold your finger / mouse button down, it will only return a single result.

Enabling Consumable Purchases in Windows Store Apps

What are consumables

Consumables are a type of in-app purchase that can be used within your app or game; by used, I mean, for example, coin, food, life-force, credit; anything that can be bought and then the same item be bought again. This is opposed to durables, which are in-app purchases, such as removing adverts, premium features, etc.

Where to go first

The MSDN article does cover most of what you need. However, it doesn’t seem to cover everything, hence this post.

The documentation for the CurrentAppSimulator is also useful.

The Principle

Actual purchasing is done through the CurrentApp class. However, there is an identical test version of this, which simulates the purchasing of in-app products. Part of the store certification process is to ensure you haven’t forgotten to switch these to their live counterparts; although using the #Debug and #Release configurations might be an idea, too (see the bottom of this post for more details on this).

Step 1 – WindowsStoreProxy.xml

When you run your application in real life, it will download the purchase information from the store. However, when you’re testing, you need to simulate this. The linked documents do have examples; however, IMHO, they don’t completely explain the implications of each section. Here’s an XML file:

<?xml version="1.0" encoding="utf-16" ?>
<CurrentApp>
  <ListingInformation>
    <App>
      <AppId>988b90e4-5d4d-4dea-99d0-e423e414ffbc</AppId>
      <LinkUri>http://apps.windows.microsoft.com/app/988b90e4-5d4d-4dea-99d0-e423e414ffbc</LinkUri>
      <CurrentMarket>en-gb</CurrentMarket>
      <AgeRating>12</AgeRating>
      <MarketData xml:lang="en-gb">
        <Name>App with several in-app products</Name>
        <Description>Sample app for demonstrating an expiring in-app product and a consumable in-app product</Description>
        <Price>0.00</Price>
        <CurrencySymbol>£</CurrencySymbol>
      </MarketData>
    </App>
    <Product ProductId="MORE_CASH_1000" LicenseDuration="0" ProductType="Consumable">
      <MarketData xml:lang="en-gb">
        <Name>Consumable Item</Name>
        <Price>0.99</Price>
        <CurrencySymbol>£</CurrencySymbol>
      </MarketData> 
    </Product>
  </ListingInformation>
  <LicenseInformation>
    <App>
      <IsActive>true</IsActive>
      <IsTrial>false</IsTrial>
    </App>
  </LicenseInformation>
  <!--
  <ConsumableInformation>
    <Product ProductId="MORE_CASH_1000" TransactionId="00000001-0000-0000-0000-000000000000" Status="Active" />
  </ConsumableInformation>
  -->
</CurrentApp>

It looks a lot like the MS example, with a few key differences: firstly, it only contains a single consumable; second, it’s in GBP; and thirdly, the “ConsumableInformation” is commented out. The single consumable is just because that’s what I’m working with, but the other two burnt me:

  • If you change the language or currency, you need to be consistent. I left an en-us in and it, point blank, refused to read the document. I spent a while checking the XML was the correct format, and finally just guessed at this.
  • The ConsumableInformation node is commented out. If you put it in, then when you read the license, it will tell you that it is unfulfilled. This is definitely useful for testing, but looks like a bug in your code if you don’t know this.

Store this in a Data folder within the project:

consumables1

Step 2 – Create a helper class for managing the purchase

Obviously, this isn’t a requirement; but I would create a class for each consumable purchase. If you have common code then create a helper and base class as well.

namespace BetRaces.Purchases
{
    public class Purchase
    {
        public const string MORE_CASH_PRODUCT = "MORE_CASH_1000";
        public const int MORE_CASH_AMOUNT = 1000;

The following steps are building on the existence of such a class.

Step 3 – Create a dictionary of purchased GUIDs

The idea here is that you can track what has been bought.

private Dictionary<string, List<Guid>> grantedConsumableTransactionIds;

Step 4 – Grant Feature Locally

If you read the linked documents, they suggest a version of this function; basically, you need a function that will perform the task that you’ve asked for. In this case, it will manage the purchase of the coins, time, bonus, whatever. The following code is pretty much an exact duplicate of that offered by MS:

        private async void GrantFeatureLocally(string productId, Guid transactionId)
        {
            if (grantedConsumableTransactionIds == null)
                grantedConsumableTransactionIds = new Dictionary<string, List<Guid>>();

            if (!grantedConsumableTransactionIds.ContainsKey(productId))
            {
                grantedConsumableTransactionIds.Add(productId, new List<Guid>());
            }
            grantedConsumableTransactionIds[productId].Add(transactionId);

            // Grant the user their content. You will likely increase some kind of gold/coins/some other asset count.
            App.settings.CashPot.Total += MORE_CASH_AMOUNT;
            App.settings.SaveSettings();  // Ensure that the purchase is saved before reporting it as successful.
            FulfillmentResult result = await CurrentAppSimulator.ReportConsumableFulfillmentAsync(MORE_CASH_PRODUCT, transactionId);

        }

Step 5 – Get Unfulfilled Consumables

The reasoning here is that you have started to make a purchase, but the line above `ReportConsumableFulfillmentAsync` has not been called. This then sits in a status which blocks future purchases.

        private async Task GetUnfulfilledConsumables()
        {
            var products = await CurrentAppSimulator.GetUnfulfilledConsumablesAsync();

            foreach (UnfulfilledConsumable product in products)
            {
                GrantFeatureLocally(product.ProductId, product.TransactionId);
            }
        }

Obviously, there is a risk that the code in step 4 will crash just at the point before you report the fulfilment; however, I’d rather that, than the user having paid for something they haven’t received.

Step 6 – Purchase

The next stage is a RequestProductPurchase() method; here’s the code:


        public async Task<bool> RequestProductPurchase(string productId)
        {
            Uri uri = new Uri("ms-appx:///Data/WindowsStoreProxy.xml");
            Windows.Storage.StorageFile storeProxy = await StorageFile.GetFileFromApplicationUriAsync(uri);

            await CurrentAppSimulator.ReloadSimulatorAsync(storeProxy);
            
            Guid product1TempTransactionId;

            PurchaseResults purchaseResults = await CurrentAppSimulator.RequestProductPurchaseAsync(productId);
            if (purchaseResults == null) return false;

            switch (purchaseResults.Status)
            {
                case ProductPurchaseStatus.Succeeded:
                    product1TempTransactionId = purchaseResults.TransactionId;

                    // Grant the user their purchase here, and then pass the product ID and transaction ID to currentAppSimulator.reportConsumableFulfillment
                    // To indicate local fulfillment to the Windows Store.
                    GrantFeatureLocally(productId, product1TempTransactionId);
                    return true;

                case ProductPurchaseStatus.NotFulfilled:
                    product1TempTransactionId = purchaseResults.TransactionId;

                    // First check for unfulfilled purchases and grant any unfulfilled purchases from an earlier transaction.
                    await GetUnfulfilledConsumables();

                    // Once products are fulfilled pass the product ID and transaction ID to currentAppSimulator.reportConsumableFulfillment
                    // To indicate local fulfillment to the Windows Store.
                    if (grantedConsumableTransactionIds != null && grantedConsumableTransactionIds.ContainsKey(productId))
                        return true;
                    return false;                    
            }

            return false;
        }

The above code is what I was referring to in Step 1, when I mentioned the NotFulfilled return status.

Step 7 – Test the change

When you try to make a purchase, you should see a screen such as this:

consumables2

You can then test possible eventualities.

Step 8 – Enable them in the store

The next step is to enable your purchases in the App Store. The code has to be the same; and for larger games (the producers of which will probably not be reading posts such as this) the codes will be generated on a server, so they can manage special offers, etc. centrally.

In the Services section of the dashboard:

consumables3

Now enter your offer code, along with the price and make it a “Consumable”:

consumables4

Step 9 – The Old Switcheroo

All you need to do now is to substitute CurrentAppSimulator for CurrentApp.

Because both classes are static, I couldn’t find a better way than this:

#if DEBUG
            PurchaseResults purchaseResults = await CurrentAppSimulator.RequestProductPurchaseAsync(productId);
#else
            PurchaseResults purchaseResults = await CurrentApp.RequestProductPurchaseAsync(productId);
#endif

Windows Store Apps automatically compile in Release mode for the store.

Once you’ve found all the CurrentAppSimulator references and replaced them with this conditional construct (by my count there are 4 places for this); you should see the following when you try to make the purchase:

consumables5

consumables6

Conclusion

The links at the start are by far the best resource available for this; but hopefully this will fill in a couple of the gaps that tripped me up.

Adding and Using a New Font in MonoGame (The 11 Step Program)

This is not an undocumented subject; however, I didn’t find everything I needed in a single place; so this is my single point of reference.

The Problem

There is currently no facility within MonoGame to create a new Sprite Font. The workaround described below is, to put it mildly, time consuming.

Adding a Font

Step 1

The first step is to download Visual Studio 2010

This is the only download link to the express edition (obviously if you have an MSDN license, you can get the full edition. VS Express has now been replaced by the Community Edition, but that’s VS2013.

Step 2

Next, you need to download XNA Game Studio

… and install it.

Step 3

Now, load up VS2010 and create a new XNA game:

MonoGame1

You should end up with a project that looks like this:

MonoGame2

Step 4

In the Content Project, add a new file:

MonoGame3

… and add a new SpriteFont:

MonoGame4

Step 5

If you now open the file, you can edit key aspects of the font, such as size, font name, etc…:

MonoGame5

Step 6

To test, make the following changes in the main project (Game1.cs):

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Font1 = Content.Load<SpriteFont>("SpriteFont2");
            FontPos = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2, graphics.GraphicsDevice.Viewport.Height / 2);

        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();
            string output = "abcdefghijklmnopqrstuvwxyz!";
            Vector2 FontOrigin = Font1.MeasureString(output) / 2;
            spriteBatch.DrawString(Font1, output, FontPos, Color.Black,
                          0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);
            spriteBatch.End();

            base.Draw(gameTime);
        }

Step 7

Run the project:

MonoGame6

Step 8

Okay, now you have a font (the font was compiled when you ran the project in the previous step). Locate the compiled font:

MonoGame7

Step 9

Copy the compiled font to your MonoGame content directory.

Step 10

Set the properties of the font to be Content:

MonoGame8

MonoGame9

Step 11

You’re done, you can now use it in your project in the same manner as you did in the test project earlier.

Conclusion

Work is underway to incorporate this into MonoGame. However, it’s still a massively painful process!

References

Below are some useful links that I found (I’d be happy to add more, or just leave a comment):

http://www.c-sharpcorner.com/uploadfile/iersoy/how-to-use-spritefont-in-xna/

http://gamedev.stackexchange.com/questions/46128/how-to-generate-spritefonts-for-monogame

http://stackoverflow.com/questions/18268413/loading-a-font-using-monogame-with-vs2012-13

Using Asynchronous methods within a Windows Game

The new async / await syntax in .NET 4.5 + makes asynchronous programming really easy. However, there are times when having an assumption of asynchrony can impede you. One such example is programming for games (see my post on why you might want to avoid this).

However, what happens when you want to display a windows message box, or some other action that is asynchronous; See my post on a message box helper for an example.

In my particular case, I was to show a message box asynchronously, and perform a certain action based on the result; however, I don’t want to stop the game, and I don’t want to have to introduce an async / await into the programming model (for reasons in the linked post).

My solution was to use a combination of two, slightly outdated, methods of asynchronous programming: call backs and continuation blocks (strictly speaking, async / await does use continuation blocks behind the scenes admittedly). The following code will attempt to make an in-app purchase from the store:

        internal static async Task<bool> PurchaseCash()
        {
            var result = await Windows.ApplicationModel.Store.CurrentApp.RequestProductPurchaseAsync(PURCHASE);
            return (result.Status == ProductPurchaseStatus.Succeeded);
        }

What that function actually does it not important; however, it needs to be called from within a game loop. Here’s how it is called:


                        Purchase.PurchaseCash().ContinueWith((purchaseTask) =>
                        {
                            purchaseTask.Wait();
                            if (purchaseTask.Result)
                            {
                                App.settings.CashPot.Total += Purchases.Purchase.MORE_CASH_AMOUNT;
                            }

                        });

This will only execute the purchase action if the purchase was successful; it’s completely asynchronous, and it doesn’t affect the main thread. All well and good, but what if, instead of a specific task, we wanted to execute a conditional command; for example: when the purchase is called, we want to turn on a specific feature.

In this case, I decided to use a call back; the method signature looks like this:

        private bool MakePurchase(int cost, Action onSuccess)

And it is called like this:

                    if (!App.settings.Purchase1)
                    {
                        MakePurchase(PURCHASE1_COST, () =>
                        {
                            App.settings.Feature1 = true;
                        });
                    }

Inside MakePurchase, I only call the onSuccess method where the purchase was successful:

                        Purchase.PurchaseCash().ContinueWith((purchaseTask) =>
                        {
                            purchaseTask.Wait();
                            if (purchaseTask.Result)
                            {
                                onSuccess.Invoke();
                            }
                        }

Conclusion

The syntax above is nowhere near as clear and concise as a simple await statement; however, await statements can’t be used outside of an async method and, especially when programming games, that’s not always practical. The other thing that I haven’t mentioned here is exception handling – I may make that the subject of a later post.