Search Unity

Combat System Logic

Discussion in 'Scripting' started by baazul, Jul 17, 2019.

  1. baazul

    baazul

    Joined:
    Jul 29, 2018
    Posts:
    42
    Hello,

    I am a beginner and trying various things to learn. Currently, I am making a combat system but it's not working the way I expected. I know the reason and realized the script is not at "fault", but it's the logic behind. And I may lack knowledge to find the best logic to make this system working. You may find it stupid, I start to think that my brain is just tired due to all the recent learning I did... I am confused.

    1. I want to make a combat method that will display life and damage from both player and enemy
    2. Once I press the "attack" button, both hit in same time and the damage number is removed to the life number for each
    3. Player fights one enemy at a time but there are multiple different enemies with different stats in-game

    Currently the way I tried is:

    I have a combat method that remove the damage number from the life number for each with something like:

    Code (CSharp):
    1. Public void combatMethod (int life, int damage)
    2. {
    3.     // life = life - damage;
    4. }
    Then I made a method for both the enemies. Something like:

    Code (CSharp):
    1. public void enemy1 ()
    2. {
    3.       // display enemy sprite
    4.      combatMethod (50,10);
    5. }
    6.  
    7.  
    8. public void enemy2 ()
    9.  
    10. {
    11.      // display enemy sprite
    12.      combatMethod (70,12);
    13. }
    So I call one of the enemy method to set the "life" and "damage" variable to the value I want the I planed to attach the combatMethod to an "Attack" button in unity with an OnClick event.

    First issue, I noticed that I could not attach in unity the combatMethod function to a button. Apparently because there is the (int life, int damage). I don't know the reason...

    So I removed this part and tried to include the life and damage variables within the "enemy1" and "enemy2" method directly. With something like:

    Code (CSharp):
    1. public void enemy1 ()
    2. {
    3.       // display enemy sprite
    4.       int life = 50;
    5.       int damage = 10;
    6.      combatMethod ();
    7. }
    But this way it leads to another issue. The combat method is in the same class but is still separate from the enemy method so it does not know what are the life and damage value... Maybe I should use one of these "Static" kinda of things somewhere...? I don't understand the accessibility things very well yet.

    The solution I am thinking about is to create a combat method and to make a new script for each enemies then call the combat method inside. I think it would be ok for 2 enemies but not for 100. There is probably a smarter way to do it. An infinity of smarter way.

    If you read it this far, do you have any suggestion ?

    Thank you
     
  2. GeorgeCH

    GeorgeCH

    Joined:
    Oct 5, 2016
    Posts:
    222
    Hi Baazul -

    Welcome to game development! I hope you have fun - the learning curve is quite steep, but it can be a very fun journey.

    As you said, you're just starting out, and, personally, I think you're biting off a little bit more than you can chew at the moment. That's alright, nothing wrong with that - but I'd suggest you take a step (or two) back and try playing around a bit more with the fundamentals.

    In this particular case, let's examine logically what you're trying to achieve:
    • You have a player and one (or more) enemies
    • The player and each enemy have hitpoints
    • The player and each enemy can attack a target
    • Attacking reduces the target's health
    There are a lot of ways to go about it, and the one I'd suggest wouldn't necessarily be the optimal one, but, probably, the easiest one to implement. So, with that said, here goes.

    What are the commonalities between the player and the enemies? Clearly, they're living things that can be attacked and take damage, which, in turn reduces their health. So, if we were to create a common class around them, it would go something like this:

    Code (CSharp):
    1.        
    2. public class Humanoid : MonoBehavior
    3. {
    4.     public int currentHitPoints = 100;
    5.     public bool IsPlayer;
    6.  
    7.     public void Attack()
    8.     {
    9.         // Let's figure out all the humanoids in the game that can be attacked
    10.         var _humanoids = GameObject.FindObjectsOfType<Humanoid>();
    11.    
    12.         // Now, let's figure out who to attack
    13.         Humanoid _target;
    14.            
    15.         // If this humanoid is the player, then we need to make sure that the target humanoid is an enemy - that is, their IsPlayer flag must be set to false.  
    16.         if (isPlayer)
    17.         {
    18.             foreach (var possibleTarget in _humanoids)
    19.             {
    20.                 if (!possibleTarget.IsPlayer)
    21.                 {
    22.                     _target = possibleTarget;
    23.                     break;
    24.                 }
    25.             }
    26.         }
    27.    
    28.         // But if this humanoid is an enemy, then we need to make sure that whatever target they pick, their IsPlayer tag is set to true.
    29.         else
    30.         {
    31.             foreach (var possibleTarget in _humanoids)
    32.             {
    33.                 if (possibleTarget.IsPlayer)
    34.                 {
    35.                     _target = possibleTarget;
    36.                     break;
    37.                 }
    38.             }
    39.         }
    40.    
    41.         // Great, we now have our target! Now, let's whack 'em with some of that righteous fury, shall we? How do 100 points of righteous fury sound?
    42.         _target.TakeDamage(100);
    43.    
    44.     }
    45.  
    46.     // And this is our target taking damage! Look at them run! Aren't we awesome?
    47.     public void TakeDamage(int amount)
    48.     {
    49.         currentHitPoints -= amount;
    50.     }
    51.  
    52. }
    The above code isn't perfect or optimal (for example, it will always attack the first non-player target it finds, rather than choosing randomly from the list of possible targets; the amount of damage to deal is hard-coded; it assumes that all enemies are humanoids, which may not turn out to be the case; it exposes every single method and variable under the sun; etc) and there are better, more advanced ways of achieving this (using interfaces, for instance). But if you're just starting out, this should give you an idea of classes, instances of classes, finding class instances within the scene, and calling functions on them.

    Good luck!
     
    baazul likes this.