Unity3D/C#: Simple Battle Maths

I don’t think I’ve covered my battle mathematics in a previous blog post. I’ll keep it simple for now, for things like magic it gets a little more complicated. But the basic formula is (for melee):

AttackMod  = Strength + Weapon Damage

RandomMod = Random Number between Strength & AttackMod

Damage = AttackMod + RandomMod – TargetVitality

Clamp Damage so it doesn’t go below 0 or above 9999.

There is also a formula for calculating accuracy. I won’t cover that in depth because it requires coding outside of the method used to calculate damage, and I just want to show the maths. The calculation is as follows:

AccuracyPower = Dexterity/2

RandomMod = RandomNumber between 0 and Dexterity – RandomNumber between 0 and TargetAgility

Accuracy = AccuracyPower + RandomMod

If Accuracy < 0 then miss

If Accuracy > 0 then hit

As you can see Accuracy is a lot more random than damage. The way I think of it, the larger the ‘Dexterity’ number is, the more likely it is that it’s going to hit a positive number, but of course it’s battling for chance with the enemy’s agility, which if too high will result in more misses. Plus on higher level enemies you’ve still got a chance to hit, even if low (Dex could return 5 and TargetAgi could return 0, 5 – 0 = 5 therefore hit). At the very least your accuracy will equal half of your total dexterity.

For each battle calculation I do I have a method inside of a static class called ‘CalculateDamage’. This class is different to other Unity3D C# classes, because it doesn’t need to use any MonoBehaviours and is static.

using UnityEngine;

public static class CalculateDamage

//Your Code Goes Here


So now we just need the method (which is also static)

public static float MeleeDamage()

        var strMod = Overlay.Instance.MeleeStat.STR + 15;
        var rndMod = Random.Range(Overlay.Instance.MeleeStat.STR, strMod);

        var damage = strMod + rndMod – Overlay.Instance.Enemy.VIT;
        damage = Mathf.Clamp(damage, 0, 9999);

        return damage;


Overlay.Instance.MeleeStat.STR is just pointing to a variable in another class, but it doesn’t matter where your ‘Stats’ are, just as long as you can point to them. Smile

Random & Mathf are Unity3D specific classes, although the .NET Framework has its own ‘Random’ class as well, but it doesn’t work the same way. Random.Range is basically “pick a random number between ‘X’ and ‘Y’”.

Mathf.Clamp is used to limit a variable so that’s in between a lowest set number (or 0 in this case) and a highest set number (9999). So damage can’t hit the minus numbers (where it would actually heal the target) and it won’t exceed 9999. If you didn’t want to clamp it on the higher end, you could just make your own clamp with:


if (damage < 0)
            damage = 0;

So, here’s an example of it in action:

var dam = CalculateDamage.MeleeDamage();
dam = Mathf.RoundToInt(dam);
Enemy.HP -= dam;

Of course, what you could also try doing is adding arguments to MeleeDamage() so that you could get:

MeleeDamage(str, enemyVIT)

My specific system is specific to my game, where you have 3 characters, a Melee, a Ranged and Magic user, so each requires different mathematical calculations and enemy calculations have slight differences too, so I don’t need to use these arguments,


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s