Tag Archives: .NET

How To Build A Spawner In Unity

Spawning objects in Unity exists in just about every project out there. Whether we’re spawning enemies for a player to fight or collectables for them to pickup, at some point and time you’re going to need systems that can create and manage these objects. Let’s walk through what this can look like in a Unity 2D project.

There’s no best way to implement a system that creates objects and every project has slightly different needs but there are some commonalities and ways you can create your system to be reusable. For this particular example we’re going to look at spawning for Survive!

Advertisements

There are two main objects that are currently created in Survive using the current spawning system with a handful more on the way. The great part is that implementing each objects spawning logic and system is fairly simple after the first one is in place. Let’s take a look at how that’s done.

Currently we are creating two objects at game start. The white blocks that act as walls and the green enemies the player must avoid. Both of these are built using the same spawning system and code base. We do this so that we can then re-use these objects and scripts to easily add new features to our project. Here is what our spawner code currently looks like:

Advertisements
using UnityEngine;

public class Spawner : MonoBehaviour
{
    public GameObject objectToSpawn;
    public GameObject parent;
    public int numberToSpawn;
    public int limit = 20;
    public float rate;

    float spawnTimer;

    // Start is called before the first frame update
    void Start()
    {
        spawnTimer = rate;
    }

    // Update is called once per frame
    void Update()
    {
        if (parent.transform.childCount < limit)
        {
            spawnTimer -= Time.deltaTime;
            if (spawnTimer <= 0f)
            {
                for (int i = 0; i < numberToSpawn; i++)
                {
                    Instantiate(objectToSpawn, new Vector3(this.transform.position.x + GetModifier(), this.transform.position.y + GetModifier())
                        , Quaternion.identity, parent.transform);
                }
                spawnTimer = rate;
            }
        }
    }

    float GetModifier()
    {
        float modifier = Random.Range(0f, 1f);
        if (Random.Range(0, 2) > 0)
            return -modifier;
        else
            return modifier;
    }
}

And here is what our script looks like from the Editor:

As you can you see, our script allows us to pass in the ‘Object To Spawn’ which is the prefab of the object we want to create. We can then assign it an empty parent object (to help keep track of our objects) and from there we are free to tweak the number of objects it spawns at a time as well as if there should be a limit and how frequently they should be spawned.

Advertisements

With this approach we have a ton of flexibility in how we can control and manipulate object creation. We could attach another script to this object that randomly moves the spawner to different places on the screen (this is how it currently works) or we could create multiple spawners and place them in key locations on the map if we wanted more control over the spawn locations. The point is, we have options.

The best part about this approach is that we can easily include or add another object to use this same functionality with little effort. Here’s the same script, same code, but for creating wall objects:

And a third time for a new feature I’m currently working on:

Advertisements

Each object and system has it’s own concept and design to how it should work, for example the wall objects need to create so many objects quickly (higher rate) and then stop (reach their limit). The zombie objects need to be created over and over as the player destroys them but not as fast (slower rate). The new Heart Collectible needs to be created only once until the player collects it (limit).

When building objects and writing scripts in Unity we should always be thinking of how we can create something that is reusable. It might not be reusable in this particular project, but it can save you mountains of time when you go to the next project and you already have a sub-system like spawning built and ready to go!

If you want to take an even deeper dive, take a look at an article on Object Pooling: Taking Your Objects for a Swim that can help with performance issues you may run into while working with Spawning Systems.

Don’t forget to go checkout Survive and sign up for more Unity tips and updates:

How to Write Unit Tests in .NET

Unit testing is the idea of writing a separate set of code to automatically execute your production code and verify the results. It’s called a ‘unit’ test because the idea is that you are only testing a single ‘unit’ of code and not the entire application. Writing Unit Tests is often seen in Test Driven Development but can and should be used in any development environment.

Unit tests give your application increased testing coverage with very little over-head. Most unit tests can execute extremely fast which means you can write hundreds of them and execute them all relatively quickly. In environments with multiple developers, unit tests can provide a sanity check for other developers making changes to existing code. But how do we actually go about writing a unit test?

Advertisements

In .NET there’s a couple of ways we can do this. In Test Driven Development, you write your tests first. That sounds backwards but it’s really about teaching your mind to think a certain way before you start writing any code because to write unit tests, you need highly decoupled code with few dependencies. When you do have dependencies you’ll want to use Dependency Injection (which we can cover at another time).

The .NET stack provides a built in testing harness called MSTest. It gets the job done but doesn’t come with the bells and whistles. I personally prefer xUnit which can be downloaded as a Nuget package. There is also NUnit which is very similar but I prefer xUnit because each execution of a test is containerized where as in NUnit all tests are run in a single container.

So once we’ve installed xUnit we can start writing our first tests. The first thing to do is to create a new project in your solution. We can do this by opening up our project in Visual Studio and then right-clicking on our solution, choosing Add, and then new project. From the ‘Add a new project’ window we can search for ‘xUnit Test Project‘ and add that. I simply name the project ‘Test’ and click create.

Advertisements

By default a new class is created which contains your new test class. You should also see the ‘Test Explorer’ window in Visual Studio on the left-hand side. If you don’t, go to the ‘View’ menu and select it. This menu contains all of your tests that you write and allows you to run them all or run them individually. You can also kick off a single test to debug it.

Now the fun part, writing a test! Let’s keep it simple for starters and look at an example test:

[Fact]
public void ItCanAddTwoNumbers()
{
   var result = AddTwoNumbers(1, 4);
   Assert.Equal(5, result);
}

So this test is doing a couple of things. By defining [Fact] we are saying this function is a test function and not some other helper function. I try to name my test functions based around what the application is trying to do like, ‘ItCanAddTwoNumbers’ but that is completely up to you.

Within the test function we can then call the function we want to test which in this case is ‘AddTwoNumbers(int num1, int num2).’ Simply calling this function and making sure the application doesn’t crash or throw an error is already a little bit of test coverage which is great, but we can go farther. We can not only make sure it doesn’t error, we can make sure we get the right results back.

We can do this using ‘Assert‘ which gives us some different options for verifying the results are correct. In this case, our test will check to make sure the ‘result’ variable does equal 5. If it does, our test will pass with green colors. If not, our test will fail and show red in our Test Explorer. This is great when you already have some test written, you make some code changes, and then re-run all of your tests to make sure everything is still working correctly.

One last tip, instead of using [Fact] we can use [Theory] to allow us to pass in multiple test values quickly like this:

[Theory]
[InlineData(2)]
[InlineData(5)]
[InlineData(7)]
public void ItCanAddOneToANumber(int number)
{
    var results = AddOneToNumber(number);
    Assert.Equal(number + 1, results);
}

Hopefully this gives you a brief introduction into how to write Unit Tests in .NET using xUnit. Unit testing will save you hours of debugging and troubleshooting time when that sneaky bug shows up that you can’t quite track down. Even if the bug is not in your unit tests, it can help you track down the issue faster because you’ll know it’s not in any of your code that you have unit tests for.

Always test and happy coding!

How to Intercept WebMethods in .NET

Legacy applications often suffer from tech debt. It’s a natural part of the development life cycle and depending on the size, scope, and team, tech debt can range from a few lines, to most of the project.

In a perfect world though, tech debt wouldn’t exist, but perfect is the enemy of progress, and so progress is made and tech debt is built. As tech debt mounts it can become increasingly difficult to integrate additional features and functionality. A good refractor can always help, but what about in cases where you need to add in things like logging or metric collection?

Previously you may have been stuck with having to sprinkle code throughout the application to collect the logging that was needed or you may have had to try and hunt down each place a specific line of code was called or used (and it’s various implementations). This can be difficult and unreliable. It also means that any time you want to make a change you need to go track down each of those little sprinkles and change them.

Enter PostSharp:

photo cred: Markus Spiske

PostSharp is a 3rd party library that you can include in your project and setup through Nuget. It allows you to apply Attributes to your functions that will then override your function and pass it through as a parameter. In other words, you can add a custom Attribute to any function and then either execute your new code before or after the execution of the original function. Let’s look at some examples:

After I’ve installed the Nuget package the first thing I want to do is create a new class that will handle my needs. In this example we’ll say we want to use some sort of metric collection functionality and to inspect the results of the function.

[PSerializable]
public class CollectMetric : MethodInterceptionAspect
{

}

Our new class CollectMetric.cs class will require that we inherit from MethodInterceptionAspect and that we apply the PSeriablizable Attribute. Both are PostSharp requirements. Next we can write our actual implementation. Some of this won’t be real code but you’ll get the idea.

[PSerializable]
public class CollectMetric : MethodInterceptionAspect
{
     public CollectMetric(){}//constructor

     public override void OnInvoke(MethodInterceptionArgs args)
     {
          //more code to come
     }
}
Advertisements

So now that we have our constructor and the OnInvoke() function. We can actually wire things up and start to debug and see how this works. We can do this by going to any function that we want to intercept and adding a [CollectMetric] Attribute. Like this:

[CollectMetric]
public int MyOriginalCode(string inputs)
{
     //stuff
}

If we were to debug MyOriginalCode() we would see that before that function even gets called our OnInvoke() function will be called. Now all we have to do is decide what we want to do in our OnInvoke() function and then when to call the original MyOriginalCode(). It might look like this:

public override void OnInvoke(MethodInterceptionArgs args)
{
     args.Proceed(); //this calls MyOriginalCode() function like normal
     var value = args.ReturnValue; //output from MyOriginalCode()

     SaveMetricToDatabase(value); //some other thing we wanted to do
}

So by calling args.Proceed() we are really just calling our old original code like normal, MyOriginalCode(), and we can even capture the output of that function with args.ReturnValue. From there we can do whatever we want. Add logging, inspect the results of the function, whatever new things we want to do.

Advertisements

The big advantages we gain from this solution are that we no longer have to worry about creating bugs on existing code by modifying it. We also can encapsulate all of our changes in a single place and write unit tests around them. This is a far safer solution that going around and sprinkling in lines of code throughout the application.

If you get a chance to try the solution out let me know how your implementation went! I’d love to get some feedback on what worked and didn’t work for you and how I might improve my own implementation. If you attempt this project and get stuck, feel free to reach out to me by leaving a comment!

Taking your Objects for a Swim

There are times while we’re coding that we need to create a number of objects to handle various workloads. This could be a Factory producing a number of enemies for a game or a SaaS application firing up multiple instances of a worker process.



Whenever we start dealing with a number of the same object like this we have to start considering object management, the lifetime of the objects, and garbage collection. If we don’t we’ll have to deal with out of memory exceptions, rouge processes, and bugs, bugs, bugs…

photo cred: Wynand Uys

Thankfully there’s a solid way to handle all of these objects, not only in a clean way, but in an efficient way. That way is called, Object Pooling.

Object Pooling is the concept of taking each of our created objects and placing them into a group or “pool“. Then when our game or application needs to use one of these objects, we provide a way to check that pool, find an inactive object, activate it, and return it to the caller.

Advertisements

If we check our pool and find there are no free objects available because they’re all already in use somewhere else, then we can provide the functionality for our pool to create us a brand new object, add it to the pool, and return it to our caller.

When our callers are done with their objects they can shut themselves off and remain inactive in our pool until another caller needs to request the object. Whew… okay that got technical so let’s break it down a little bit and see how it looks in code:

//our "pool" of enemies
List<Enemy> enemies = new List<Enemy();

//our function to check our pool for an enemy that is inactive
public Enemy GetEnemy()
{
   foreach (var enemy in enemies)
   {
       if (!enemy.IsActive())
         return enemy;
   }
}

So in a very basic example we have our “pool” and a way to get inactive objects out of that pool. But what happens if there aren’t any objects in our pool to begin with? What happens if there are some objects in our pool but they’re all in use and there aren’t any in active ones to be returned? Let’s see what else we can add to fix this.

Advertisements
//let's add some functionality to create a new enemy if our list has none 

//our function to check our pool for an enemy that is inactive
public Enemy GetEnemy()
{
   //loop over our pool and find an inactive enemy to return
   foreach (var enemy in enemies)
   {
       if (!enemy.IsActive())
         return enemy;
   }

   //if no enemy returned, create a new one and add it to the pool
   var enemy = new Enemy();
   enemies.Add(enemy);
   return enemy;
}

So what did we change here? Well we gave our GetEnemy() function the ability to not only find an inactive object to return to the caller but we added the ability for it to create a new enemy if there aren’t any available enemies to return. This means that no matter what, when we call GetEnemy() we are guaranteed to get an available object returned back to us.

photo cred: Joe Calata

This is essentially the bread and butter of Object Pooling, but why is this better and what are the advantages?

  1. We get a single place to find and get an available object
  2. We’re not forcing our application to create and destroy objects over-and-over, eating up resources.
  3. We’re not allowing our objects to run free. They’re all contained and managed in our “pool” and if we wanted to, we could turn them all off.

Now how do we know when the best time is to use Object Pooling? If you find you’re creating and destroying a number of the same object, repeatedly overtime, you should be using Object Pooling. The performance gains are significant and the pattern can be implemented in any scenario.