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.
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);
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.
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:
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,