Software Craftsman (...mostly) Game Engineer @TurboStudios, Unity3D enthusiast, wannabe photographer, film snob, all things creative.

18 Comment

  1. Thanks for the tutorial! well written!

  2. Excellent, this was very helpful!

  3. Beautiful.

  4. Simple yet elegant

  5. Thanks for the tutorial! you really saved me a lot of time on my game!!

    Just let me ask you one thing.
    I’m developing a 2D game (early Pokemon style, just so you have a general idea). I have several different types of enemies (skeleton, ghoul, rat, etc), which have EXACTLY the same behaviours and type of animation (2 sprites, giving a bouncy sensation, just up and down). The only different things are the attributes (some have more Hit Points, some have more Attack, etc etc) and obviously the sprite image.

    What I initially did was creating an animator controller and an animation for each type of enemy. With your tutorial, I made it a bit more organized by having a general controller plus an override and an animation for each type of enemy. So, the only thing I gained was organization, because I only changed the multiple controllers for one controller with multiple overrides.

    What I wanted was to have something like one animation per type of enemy (different sprites, can’t really escape there) and one generic controller, to which I would assign the animation depending on the type of enemy. Would this be possible?

    Thanks in advance,

  6. @Rodolfo Well, if every enemy has indeed a unique animation, then you really have no choice, 1 controller and X overrides is the solution.

    But if, say, you have 3 units that should animate the same exact way, then they should share the same override and make sure they have the same skeleton.

    If all your units have the same exact animation and skeleton, then you don’t need the overrides at all, you just use the same controller for all of them.

    Regardless of how many units you have though, you still should use 1 controller because the animation STATE MACHINE is the same for every unit. So it’s not just organizational. If you add a new state, you don’t want to add it to all controllers, you just want to add it to 1 and then set the correct animation to the overrides (if any).

    Does this all make sense?

  7. @Panagiotis thank you for the reply! It most certainly does make sense!

    As per your reply I think that in my particular case the only advantage really is the fact that, if by any reason I need to add a state to the state machine or change it in some way, I only have to do it once instead of for each type of enemy which I doubt will happen. But it certainly was awesome to learn how to do this as it will definitely save time in tons of other situations.

    Let me just take a bit of advantage of our little conversation to ask your opinion on a different problem I’m having. I’m used to program in classes and when I programed simple games in my early experiences, I obviously leave the attributes of each enemy or character in their own class, as they should be. But in this particular situation I’m not really sure what to do… My main character has its attributes (health, attack and defense) and the different enemies have the same attributes but with different values for each enemy. When the player battles the enemy I use these values from both to calculate if the player is strong enough and what amount of health it looses or if it dies. The thing is, since the player has to move, I already have a playerController script class to handle movement and where I have the player attributes. The enemies are completely static in the game (similar to the trainers in the pokemon games, the player has to walk over them to trigger a battle) so I have no script class for them. But how should I manage the attributes of the enemies? Hard-code them in the same script of the player? Or create a script for each type of enemy with only the attributes as public variables and access these scripts in each battle? Or is there any other solution?

    Thanks so much

  8. Definitely not hard code them in the same script as the player.

    So, from what you’ve said I gather that you only have a PlayerController that contains movement and collision logic and also the player’s stats. I’m also assuming that the battle logic is in the same class, if it exists at all. Your problem is figuring out where to put the enemy data and how they are passed to the battle logic.

    I am assuming here that you are familiar with Unity and that you know how to create prefabs and edit a component’s attributes that are stored in the prefab. If not, I suggest you watch some of the many Unity tutorials on YouTube.

    I’m also gonna assume that you are coming from a inheritance-based codebase where you typically have a class named Entity, which both the Player and the Enemy class extend, blah blah blah. In Unity though, you want to have a flat class hierarchy and have small components that encapsulate behavior.

    So, with those assumptions, the components that sound useful in your case would be a PlayerController that only contains movement and collision logic for your player, a CharacterStats that contains all the common attributes a player and an enemy has and then a BattleManager class that would take 2 CharacterStats and perform combat logic.

    Your project setup then would be to have a Player prefab with the PlayerController component and the CharacterStats component (as well as his visual representation). For each enemy you have in the game, you would also have a prefab that has the CharacterStats component. Since all the entities are prefabs, and every prefab has the CharacterStats, you can simply edit the stats on the prefab eliminating the need to hard code them anywhere.

    Once the setup is done, you need a BattleManager class. I would suggest making it a Singleton for now (warning: not a good long-term solution) which makes it easy to be accessed everywhere. Have a single InitiateBattle method that takes 2 CharacterStats components and does whatever it needs to do. You can even pass the 2 game objects instead if you need more information about the entities.

    So once all this is in place, the PlayerController will call the BattleManager.InitiateBattle method whenever it collides with another game object that has a CharacterStats component.

    This should be enough to get you started. Let me know if this works or I greatly underestimated you and my assumptions are incorrect.


  9. All your assumptions were correct ( PlayerController indeed has movement, collision and battle calculations and yes, passing the values to the battle logic). What I was doing here for the battle was creating a box collider trigger and using the function OnTriggerEnter. There I would check the tag of the collider that originated the trigger and calculate the values based on hardcoded stats for each enemy. I know this is not good programming at all, hence why I asked how you would do it!

    Regarding the other assumptions, you were also absolutely correct, except for the Unity part. This is my first game in Unity ever and I’ve been at it for less than a week! ahahah But I know how to create prefabs, actually I am creatting prefabs for almost every single thing in the game. I even created a prefab for each level with the whole layout (yes I know I will not use it again since all levels are different but I thought it might be a good practice and will be a good work habit).

    Regarding your suggestion I think I understood everything and will definitely give it a try now, but just to make sure: what you suggest is to remove all the battle logic from the PlayerController and place it in another class in another script. So instead of calculation on the OnTriggerEnter function, I would call a function in said new class and give it as arguments the gameobject of the player and the gameobject of the collider, making the calculation there. The only thing that was a bit cloudy was the CharacterStats. I assume you mean another script, that I would add to the prefabs of both player and enemies with only the variables of the stats and no functions. Is this correct? If yes, how would I go about giving each character their correspondent different stats? Would this mean that this isn’t actually a single generic script for all the characters but actually several scripts that look the same, one for each type of character? Or is there a way to crate only one general script and then somewhere specify that for this character the values are these and for that character the values are those?

  10. Yes, you will end up with 3 classes: PlayerController (movement & collision), CharacterStats (entity stats) and BattleManager (battle logic). And yes, player controller will call the battle manager and pass it both the player’s and the collided enemy’s CharacterStats.

    So CharacterStats is a component that exposes in the editor all the stats you care about. You’ll basically have a bunch of public ints like so:

    public class CharacterStats : MonoBehaviour
    public int attack;
    public int defense;
    // etc.

    Now, when you add that component to a prefab, you will see in the inspector those values exposed and you can set whatever value you want.

    This is kind of a short term solution, of course, because if you want to edit a bunch of units, you’ll have to go to each prefab and change the field. Not to mention that you’ll have to make a new release every time you want to balance the game. A more long term solution is to setup a Google Spreedsheet with all the stats in one Sheet that you can download as a JSON file and deserialize it into a class during the initialization of your game.

    As for storing the whole layout into a prefab, that’s actually a good practice since you can have a single empty scene that loads the layout dynamically. And if you split the layout into parts (GUI, Map, etc) you can avoid stuttering when a huge scene is loaded (and also de-couple a bunch of logic).

  11. I see! I get it! I will leave the Spreadsheet and JSON serializaton/deserialization for later on but thats a great tip! Thanks!

    I think I managed to do it all! I’m finishing the code right now!

    Just let me ask you one last thing, more conceptual than practical really…
    Would you really recommend creating the BattleManager class? I mean.. I know it certainly is good practive and if it’s a complex combat with several turns and a lot of enemies at the same time I fully agree to it, but in my case it’s just a simple calculation of how much health the player looses based on his attack and defense and the enemy’s attack and defense. So I was thinking of actually removing the BattleManager class and make the calculation on the OnTriggerEvent directly. Do you have any strong reason not to do this?

  12. High cohesion (class only does things relevant to its data), the single responsibility rule (class only does one thing conceptually), re-usability (the battle manager can be called from anybody, not just player), extensibility (battle logic can be derived or swapped for other types of battle systems), easy to understand its responsibility (you know that a class named BattleManager is responsible for… managing a battle. You wouldn’t have thought the same about PlayerController unless you knew it… and trust me, sooner or later, you will forget it), easier to find (you can just search for a class named Battle to get the battle logic)… I can go on and on.

    Even for a trivial game like yours (which, by the way, is not trivial at all), I would still recommend a separate class. I’m not saying that you have to create a full fledged battle manager with dependency injections and whatnot, just a singleton class that can be accessed everywhere. Singletons are still bad (as you will find out if you Google it), but it’s easy to implement and provides a better foundation.

    One thing you want to keep in mind when designing your architecture is how fast a particular design will get you to a point where you need to spend a lot more hours just to get the damn feature in.

    Having tons of logic into a single class will really limit you really fast. What if you want something else to start a battle? What if you want to battle 2 enemies? I know these might not be cases that you are going to implement any time soon, but what applies here conceptually will apply to the next system you want to implement, let’s say a shop for example. Are you planning to put the shop logic in the player as well? What about an inventory system? You can already imagine how big that class will be with all those systems in.

    Of course, you’ll realize at some point, you need to refactor your player class. When do you think would be the best time to do that? When you already have all three systems in, or before those systems even exist? That isn’t to say you have to over-engineer. During prototyping, you want a quick solution that will be easy to change later and doesn’t necessary need to accommodate lots of things (it doesn’t have to be extensible). Having a single class that does one thing is a lot easier to change than having to change a class that does a lot.

    And trust me, you WILL change it sooner than you think. There’s a difference between having a hacky implementation of a sub-system and a hacky architecture; the first can make adding features time consuming, have a lot more bugs, etc, etc, the second can make or break your game entirely. Choose when and what to hack wisely.

    Yes, I have a strong reason not to do this ;)

  13. Keep in mind that I am assuming that you are working on a Pokemon style game who’s combat logic is a little more involved. If your “combat logic” is a single line of code, then I agree that a BattleManager will be overkill. Even still, I would at least make that a separate method (private void PerformCombat(CharacterStats charA, CharacterStats charB)) in your player controller instead of doing it inside the OnTriggerEnter method. Extracting that method into a separate class later is trivial.

    But I am willing to bet that the combat logic will expand from a single line to multiple ones a lot sooner than you’d think. Don’t forget, all programmers are bad at estimating ;)

  14. Well, those certainly are A LOT of reasons and I agree with all of them! ahahah

    Well, in my particular case I really can do the battle logic with one line (as i said, calculate the health lost depending on attack and defense of player and enemy). Since all enemies are always standing in the same place I will never have a fight with multiple enemies. I will not have any shops but I will, however, have an inventory. Note that I am not trying to make excuses to put this logic in the trigger, I’m just giving you some more context! ahahah

    Thank you for all your time and all your input. You’re being really great!

    I will most certainly place the logic in a separate method if not in the BattleManager class, firstly for all the reasons you pointed out and secondly because I also have a tiny bit of another problem I need to solve. I have an animation that I wish to play for every hit of the player to the enemy and am not sure how to handle it.

    Just an example: hero has 100/10/1 of health/attack/defense and enemy has 20/15/5 of the same. This means that the hero will have to hit the enemy 20/(10-5)=4 times. I wish that the player only controls the “entering” of the fight. So, the player only moves the hero on top of the enemy and then looses control until the hero dies or the enemy is destroyed. I have an animation for one blow. So in that particular case, I would like to loop that animation 4 times. But if the hero battles other enmies with different stats or if the player picked up some item and changed the hero’s stats, the number of hits will be different and I want to loop the animation a different number of times.

    Firstly I was thinking of dinamically change the transition of the battle state in the animator but I already searched and realize I cannot do that.. I was thinking of creating an animation event at the end of the animation and a counter to check if the number of times had passed or not… But I’m not sure if it give me the result I want or if the that is even the way to go here….

    Again, thanks for all your help and advice! You made me grow a lot in both Unity and game developement! :D

  15. Just to give a little update if anyone else is interested. The animation event solved the problem. I added the event referenced to the method that calculates the damage taken by the hero and created a book variable ‘finishedBattling’ which I used as the condition for transitioning out of the animation loop. In the trigger I set the book to true and in the method I decrement a counter. When the counter is zero I set the book to false and the state machine does the rest.

    Still not sure if this is a sort of ‘hack’ of these events actually serve this kind of purpose.

    @perk if you actually have an answer for it I would love to hear it! Ahahah again, thanks a lot for your help. You’re the best!

  16. OK, this is gonna get a little involved, so bear with me.

    I am assuming that you know what coroutines are and how they work. If not, stop what you are doing and go read about them, now. Seriously, they are immensely useful in Unity.

    First off, let’s setup the animation state machine. We need an Idle animation state and an Attack animation state. We also need a trigger parameter in our controller called “attack”. We create a transition from Idle to Attack with the “attack” trigger as the condition. And then we create a transition from Attack to Idle with the ExitTime as the condition. This should be pretty straight forward.

    If you don’t know what the controller parameters are, they are basically things you can set programmatically to cause a transition from one state to another. In our case, when our unit is in it’s Idle state and we programmatically fire an “attack” trigger, it will cause it to transition to the Attack state. This is basically how controllers are suppose to work. You do not force a transition from one state to another. Instead, you set parameters and let the state machine figure out when to transition.

    Go it? OK, moving on.

    Next, we create a component that handles a character’s attack logic (remember, we are in Unity, and every behavior should have their own component). Let’s call it CharacterAttackController and put it in every enemy and the player. When the player collides with an enemy, you will call your player’s attack controller. Let’s keep it simple for now and only pass it the number of times you want to play the attack animation. This method needs to be a coroutine for reasons that will become obvious shortly. Here’s what we have so far:

    public IEnumerator PlayAttackAnimations(int attackTimes) 
        // Animation logic here.

    So far, so good?

    So a cheap and hacky way to play an animation X amount of times is to transition to the Attack state and wait for the state machine to come back to Idle. Obviously, this will break if we never return to Idle, which is why this is hacky. Also, you are assuming things about the state machine that, if no longer true, will break your code. So, yeah, this is really hacky, but you have it encapsulated in a component, right? So you should be able to change it later on. Anyway, here’s how you would do such a thing:

    public IEnumerator PlayAttackAnimations(int attackTimes) 
        // Grab our animation controller
        Animator unitAnimator = GetComponent<Animator>();
       // Play this attack sequence as many times as requested
       for (int i = 0; i < attackTimes; i++)
          // Fire the "attack" trigger which will make our state machine transition to Attack
          // We know that we will eventually transition back to Idle, so we wait
          while (!unitAnimator.GetCurrentAnimatorStateInfo(0).IsName("Idle"))
             yield return null; // Wait a single frame

    In your PlayerController, you call the coroutine like so:

    private void AttackTarget(/* Your parameters here */)
        int attackTimes = // Your math here
        CharacterAttackController attackController = GetComponent<CharacterattackController>();

    And that’s the basics.

    Of course, you could do this with animation events, but then you’d have to break your logic into multiple methods, have to keep track of your counter in your class, etc, etc, etc. With a coroutine, everything happens in one method which is easy to follow.

    Now, if you want to get a little fancy, we can use animation events to play some animation on our target for when it gets damaged. Different attack visuals with have different timings for when the target gets hit, so animation events are ideal here. Let’s do that, shall we?

    To set this up, we need our attack animations to fire a “DamageTarget” animation event. WARNING: EVERY attack animation has to do that, otherwise this code will not work. We also need a new animation state called Damaged. The transition to that state will be via a new “DamageTaken” trigger and the transition back to Idle would be via ExitTime. Then we need to add one more parameter to the PlayAttackAnimations. And finally, we need the method that listens for the animation event and calls the target to play its damage animation. This time, I’m gonna use comments to explain things, so I’ve create a Gist with here:

    I know this is kind of hard to wrap your head around, but after you get use to coroutines playing along with animation events, you can do so much more. For example, you can easily add a ShakeCamera coroutine that’s called inside the PlayDamageAnimation coroutine to sprinkle some wow factor in it.

    Hope this helps.
    (man, this is almost a blog post by itself!)

  17. Well I think I understood most of what you said. The state machine logic is easy for me since I have background with that, but I hadn’t gotten the concept of coroutines yet (hence why it took me a bit to reply..ahah). But I think I get them now..

    Well I actually gave it a try with the animation events and I think I’ve manage to do it, but a bit diferently than I previously said:
    I changed the counter to a bool and made that bool the exit condition of the battle state. So, in the middle of my animation for the battle state I have the event that triggers a method Fighting(). In that method I make the hero hit the enemy (and drop it’s health). If the enemy’s is zero, fight is over and the bool becomes true, leaving the animation, if not, enemy hits the hero (and drops it’s health). If the hero’s health is zero, fight is over and it dies (calling the Die() method) where the game should end, so no real use of the bool/trigger/animation/etc.. If the player doesn’t die, the method simply ends, leaving the bool false, meaning the animation loops and calls the event again.

    So with this, allow me to disagree a bit with what you said about breaking the logic into multiple methods, because here I managed to do it in only one. But I agree this has many faults. The most obvious to me would be if the Fighting() method took longer to execute than the animation. The event would call the method a second time before the first was over and that would be a pain to solve. With coroutines I think I wouldn’t have that problem and I they sound “cleaner” than using animation events (at least for this situation in particular).

    I think I will leave it like this for now (mainly because of the thumb rule “if it works, don’t mess with it!” ahahah) and when I have a playable game with all the features I want, I’ll update it and remove the event…

    Thanks a lot for your time man!

  18. nice job, thanks!

Leave a Reply