Search Unity

go back to walk when stamina is empty

Discussion in 'Scripting' started by twn9009, May 14, 2019.

  1. twn9009

    twn9009

    Joined:
    May 2, 2019
    Posts:
    58
    hi i have a character script and i've got a stamina system, i have made it drain when the character is running however so far whenever i try and get the character to go back to walk if the stamina is too low it just stops still, i've tried adding a new vector to tell it to go back to walk speed but i cant figure it out, code below, thanks in advance.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class PlayerController : MonoBehaviour
    7. {
    8.     //movement and anim S***
    9.     public float jumpHeight = 1f;
    10.     public float walkSpeed = 2f;
    11.     public float runSpeed = 6f;
    12.     public float turnSmoothTime = 0.2f;
    13.     float turnSmoothVelocity;
    14.     public float gravity = -12.0f;
    15.     float velocityY;
    16.     [Range(0, 1)]
    17.     public float airControlPercent;
    18.     Animator anim;
    19.     Transform cameraT;
    20.     CharacterController controller;
    21.     public bool canRun;
    22.    
    23.  
    24.  
    25.     //stambar
    26.     public Image ImgStamBar;
    27.     public Text txtStam;
    28.     private float mCurrentStamPercent;
    29.     public int Stammin;
    30.     public int Stammax;
    31.     private int mCurrentStamValue;
    32.     public void SetStam(int Stam)
    33.     {
    34.         if (Stam != mCurrentStamValue)
    35.         {
    36.             if (Stammax - Stammin == 0)
    37.             {
    38.                 mCurrentStamValue = 0;
    39.                 mCurrentStamPercent = 0;
    40.                
    41.             }
    42.             else
    43.             {
    44.                 mCurrentStamValue = Stam;
    45.                 mCurrentStamPercent = (float)mCurrentStamValue / (float)(Stammax - Stammin);
    46.             }
    47.             ImgStamBar.fillAmount = mCurrentStamPercent;
    48.         }
    49.     }
    50.  
    51.     public float CurrentStamPerent
    52.     {
    53.         get { return mCurrentStamPercent; }
    54.     }
    55.     public int CurrentStamValue
    56.     {
    57.         get { return mCurrentStamValue; }
    58.     }
    59.  
    60.     public void CanRunCheck()
    61.     {
    62.         if (mCurrentStamValue > 1)
    63.         {
    64.             canRun = true;
    65.         }
    66.        else if(mCurrentStamValue <=  1)
    67.             canRun = false;
    68.     }
    69.      
    70.    
    71.  
    72.     //manabar
    73.  
    74.     public Image ImgManaBar;
    75.     public Text txtMana;
    76.     private float mCurrentManaPercent;
    77.     public int Manamin;
    78.     public int Manamax;
    79.     private int mCurrentManaValue;
    80.     public void SetMana(int Mana)
    81.     {
    82.         if (Mana != mCurrentManaValue)
    83.         {
    84.             if (Manamax - Manamin == 0)
    85.             {
    86.                 mCurrentManaValue = 0;
    87.                 mCurrentManaPercent = 0;
    88.             }
    89.             else
    90.             {
    91.                 mCurrentManaValue = Mana;
    92.                 mCurrentManaPercent = (float)mCurrentManaValue / (float)(Manamax - Manamin);
    93.             }
    94.             ImgManaBar.fillAmount = mCurrentManaPercent;
    95.         }
    96.     }
    97.  
    98.     public float CurrentManaPerent
    99.     {
    100.         get { return mCurrentManaPercent; }
    101.     }
    102.     public int CurrentManaValue
    103.     {
    104.         get { return mCurrentManaValue; }
    105.     }
    106.  
    107.     //health
    108.     public Image ImgHealthBar;
    109.     public Text txthealth;
    110.     private float mCurrentHpPercent;
    111.     public int Hpmin;
    112.     public int Hpmax;
    113.     private int mCurrentHpValue;
    114.     public void SetHealth(int health)
    115.     {
    116.         if (health != mCurrentHpValue)
    117.         {
    118.             if (Hpmax - Hpmin == 0)
    119.             {
    120.                 mCurrentHpValue = 0;
    121.                 mCurrentHpPercent = 0;
    122.             }
    123.             else
    124.             {
    125.                 mCurrentHpValue = health;
    126.                 mCurrentHpPercent = (float)mCurrentHpValue / (float)(Hpmax - Hpmin);
    127.             }
    128.             ImgHealthBar.fillAmount = mCurrentHpPercent;
    129.         }
    130.     }
    131.  
    132.     public float CurrentHPPerent
    133.     {
    134.         get { return mCurrentHpPercent; }
    135.     }
    136.     public int CurrentHPValue
    137.     {
    138.         get { return mCurrentHpValue; }
    139.     }
    140.     //regen
    141.  
    142.     public int HealthRegen = 1;
    143.     public int ManaRegen = 1;
    144.     public int StamRegen = 1;
    145.     public bool isHPRegen = true;
    146.     public bool isManaRegen = true;
    147.     public bool isStamRegen = true;
    148.  
    149.     //hpregen
    150.     public void HPRegen()
    151.     {
    152.         if (mCurrentHpValue < Hpmax && !isHPRegen)
    153.         {
    154.  
    155.  
    156.             StartCoroutine(HPREGEN());
    157.  
    158.         }
    159.     }
    160.     IEnumerator HPREGEN()
    161.     {
    162.         isHPRegen = true;
    163.         while (mCurrentHpValue < Hpmax)
    164.         {
    165.             SetHealth(mCurrentHpValue + HealthRegen);
    166.             yield return new WaitForSecondsRealtime(2);
    167.         }
    168.         isHPRegen = false;
    169.     }
    170.     //manaregen
    171.     public void MREGEN()
    172.     {
    173.         if (mCurrentManaValue < Manamax && !isManaRegen)
    174.         {
    175.  
    176.  
    177.             StartCoroutine(ManaREGEN());
    178.  
    179.         }
    180.     }
    181.     IEnumerator ManaREGEN()
    182.     {
    183.         isManaRegen = true;
    184.         while (mCurrentManaValue < Manamax)
    185.         {
    186.             SetMana(mCurrentManaValue + ManaRegen);
    187.             yield return new WaitForSecondsRealtime(2);
    188.         }
    189.         isManaRegen = false;
    190.     }
    191.  
    192.     //staminaregen
    193.     public void SREGEN()
    194.     {
    195.         if (anim.GetBool("IsRunning") == false)
    196.             if (mCurrentStamValue < Stammax && !isStamRegen)
    197.             {
    198.  
    199.  
    200.                 StartCoroutine(StamREGEN());
    201.  
    202.             }
    203.     }
    204.     IEnumerator StamREGEN()
    205.     {
    206.         isStamRegen = true;
    207.         while (mCurrentStamValue < Stammax)
    208.         {
    209.             SetStam(mCurrentStamValue + StamRegen);
    210.             yield return new WaitForSecondsRealtime(2);
    211.         }
    212.         isStamRegen = false;
    213.     }
    214.     //StamDrain when running
    215.     public bool IsDraining;
    216.     public int stamDrain = 1;
    217.     public void DrainStam()
    218.     {
    219.  
    220.         if (anim.GetFloat("SpeedPercent") > 0.55)
    221.         {
    222.             anim.SetBool("IsRunning", true);
    223.         }
    224.         else
    225.             anim.SetBool("IsRunning", false);
    226.  
    227.         if (anim.GetBool("IsRunning") == true & mCurrentStamValue > 0 & !IsDraining)
    228.         {
    229.  
    230.             StartCoroutine(DrainSTAM());
    231.  
    232.         }
    233.     }
    234.     IEnumerator DrainSTAM()
    235.     {
    236.  
    237.  
    238.  
    239.         while (mCurrentStamValue > 0 && anim.GetBool("IsRunning") == true)
    240.         {
    241.             IsDraining = true;
    242.             isStamRegen = false;
    243.             SetStam(mCurrentStamValue - stamDrain);
    244.             yield return new WaitForSecondsRealtime(1);
    245.             isStamRegen = true;
    246.             IsDraining = false;
    247.  
    248.         }
    249.  
    250.     }
    251.     //end of statbar stuff
    252.  
    253.     void Start()
    254.     {
    255.         anim = GetComponent<Animator>();
    256.         cameraT = Camera.main.transform;
    257.         controller = GetComponent<CharacterController>();
    258.  
    259.     }
    260.  
    261.  
    262.     void Update()
    263.     {
    264.         HPRegen();
    265.         MREGEN();
    266.         SREGEN();
    267.         DrainStam();
    268.         CanRunCheck();
    269.  
    270.         //movement jumping and turning
    271.         Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
    272.         Vector2 inputDir = input.normalized;
    273.  
    274.         if (Input.GetKeyDown(KeyCode.Space) | Input.GetAxisRaw("Jump") > 0)
    275.         {
    276.             Jump();
    277.         }
    278.         if (inputDir != Vector2.zero)
    279.         {
    280.             float targetRotation = Mathf.Atan2(inputDir.x, inputDir.y) * Mathf.Rad2Deg + cameraT.eulerAngles.y;
    281.             transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref turnSmoothVelocity, turnSmoothTime);
    282.         }
    283.      
    284.             bool running = Input.GetKey(KeyCode.LeftShift);
    285.             float speed = ((running) ? runSpeed : walkSpeed) * inputDir.magnitude;
    286.             Vector3 velocity = transform.forward * speed + Vector3.up * velocityY;
    287.  
    288.             velocityY += Time.deltaTime * gravity;
    289.  
    290.             controller.Move(velocity * Time.deltaTime);
    291.             speed = new Vector2(controller.velocity.x, controller.velocity.z).magnitude;
    292.  
    293.  
    294.  
    295.             if (controller.isGrounded)
    296.             {
    297.                 velocityY = 0;
    298.             }
    299.  
    300.             float animationSpeedPercent = ((running) ? speed / runSpeed : speed / walkSpeed * .5f);
    301.             anim.SetFloat("SpeedPercent", animationSpeedPercent);
     
  2. xenonmiii

    xenonmiii

    Joined:
    Aug 2, 2010
    Posts:
    147
    @twn9009 It seems like you have one massive class doing a lot of stuff. I think it would be a good thing to do smaller simpler behaviours, which will do yourself a favour when debugging and maintaining your own code.
    E.g. why not create a generic "Stat" monobehaviour (which is not part of the PlayerController) which is responsible for decrementing the points and regenerating. You can then reuse it for both HP and Stamina and whatever other stats you have.
    Also I'm seeing IsDraining / isStamRegen which you're switching between. Are they mutually exclusive? If they are then one of the is redundant. Also, if you're finding yourself maintaining a lot of booleans, that might be a sign you need an FSM.

    (I suggest you have a look at some principles/good practices of programming to keep you sane in your journey. May I suggest the old book which still holds called The Pragmatic Programmer)
     
    twn9009 likes this.
  3. twn9009

    twn9009

    Joined:
    May 2, 2019
    Posts:
    58
    @xenonmiii thank you very much for you advice, i'm still very new to programming, the reason i currently have everything as one large class is due to my inexperience and that i'm not sure how to inherit from multiple classes, eg, if i have the class inherit from monobehaviour how do i get the character controller, which is set attached to an object so it has to derive from mono, to also get the stuff from stats, and the same from stats to the character controller as i can only inherit from one class at a time (charactercontroller : monobehaviour : stats, doesn't work) thanks for some reading too the book looks very interesting
     
  4. twn9009

    twn9009

    Joined:
    May 2, 2019
    Posts:
    58
    im probably mistaken and just doing things wrong
     
  5. xenonmiii

    xenonmiii

    Joined:
    Aug 2, 2010
    Posts:
    147
    @twn9009 I'm going to try find you some basic tutorials on OOP (object oriented programming).

    You don't need to inherit from multiple base classes (in fact you cannot in C#).
    What you want to have is references other objects.

    I'll try to dig some tutorials which might be helpful for you soon.
     
    twn9009 likes this.
  6. twn9009

    twn9009

    Joined:
    May 2, 2019
    Posts:
    58
    thank you very much you've been more than helpful
     
  7. xenonmiii

    xenonmiii

    Joined:
    Aug 2, 2010
    Posts:
    147
    twn9009 likes this.
  8. twn9009

    twn9009

    Joined:
    May 2, 2019
    Posts:
    58
    thanks again, i've been following video tutorials for games design and using a learning app on my phone for c#, but these tutorials are much better, also the book is great i'm only a few chapters in and im already learning so much about better coding structure and practises , thanks so much
     
    xenonmiii likes this.