Search Unity

Tank game mod

Discussion in 'Scripting' started by marceloiaco, Jan 29, 2017.

  1. marceloiaco

    marceloiaco

    Joined:
    Jan 29, 2017
    Posts:
    3
    Hey guys, I'm trying to develop on top of the Tank game tutorial but I'm having a hard time since it's my first time scripting.

    How can i use a Coroutine to make the tanks have a reload time before being able to shoot again? I'm trying this but it isn't really working idk why.

    These are the extra declarations I made:

    Code (CSharp):
    1. public float m_RechargeTime = 2.0f;
    2. private WaitForSeconds m_WaitShoot;
    3. private bool m_RecentlyFired;
    4.  
    For the shooting i'm starting with:
    Code (CSharp):
    1.  
    2. private void Start()
    3.     {
    4.         m_FireButton = "Fire" + m_PlayerNumber;
    5.  
    6.         m_ChargeSpeed = (m_MaxLaunchForce - m_MinLaunchForce) / m_MaxChargeTime;
    7.         m_WaitShoot = new WaitForSeconds (m_RechargeTime);
    8.  
    9.     }
    10.  
    11. private void Update()
    12.     {
    13.         m_AimSlider.value = m_MinLaunchForce;
    14.  
    15.         StartCoroutine (Shooting ());
    16.  
    17. }
    18.  
    19.     private IEnumerator Shooting()
    20.     {
    21.         while (m_RecentlyFired)
    22.         {
    23.             yield return null;
    24.         }
    25.  
    26.         if(m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired)
    27.         {
    28.             //at max charge, not fired
    29.             m_CurrentLaunchForce = m_MaxLaunchForce;
    30.             Fire ();
    31.         }
    And so on.

    Then, for the Fire function I'm doing this:
    Code (CSharp):
    1. private IEnumerator Fire()
    2.     {
    3.         // Instantiate and launch the shell.
    4.             m_Fired = true;
    5.             Reload();
    6.  
    7.             Rigidbody shellInstance = Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;
    8.  
    9.             shellInstance.velocity = m_FireTransform.forward * m_CurrentLaunchForce;
    10.  
    11.             m_ShootingAudio.Stop ();
    12.             m_ShootingAudio.clip = m_FireClip;
    13.             m_ShootingAudio.Play ();
    14.  
    15.             m_CurrentLaunchForce = m_MinLaunchForce;
    16.          
    17.     }
    18.  
    19.     private IEnumerator Reload()
    20.     {
    21.         m_RecentlyFired = true;
    22.         yield return m_WaitShoot;
    23.         m_RecentlyFired = false;
    24.     }
    It doesn't seem to work however. The bool m_RecentlyFired doesn't seem be to automatically activating. However, If I make it public and manually activate it it will stop the tank from firing, which is good.

    Thanks in advance!
     
  2. marceloiaco

    marceloiaco

    Joined:
    Jan 29, 2017
    Posts:
    3
    Here's the entire code in case anyone needs to see the full picture:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. public class TankShooting : MonoBehaviour
    6. {
    7.     public int m_PlayerNumber = 1;      
    8.     public Rigidbody m_Shell;          
    9.     public Transform m_FireTransform;  
    10.     public Slider m_AimSlider;          
    11.     public AudioSource m_ShootingAudio;
    12.     public AudioClip m_ChargingClip;    
    13.     public AudioClip m_FireClip;        
    14.     public float m_MinLaunchForce = 15f;
    15.     public float m_MaxLaunchForce = 30f;
    16.     public float m_MaxChargeTime = 0.75f;
    17.     public float m_RechargeTime = 2.0f;
    18.     private WaitForSeconds m_WaitShoot;
    19.  
    20.  
    21.     private string m_FireButton;        
    22.     private float m_CurrentLaunchForce;
    23.     private float m_ChargeSpeed;        
    24.     private bool m_Fired;              
    25.     private bool m_RecentlyFired;
    26.  
    27.     private void OnEnable()
    28.     {
    29.         m_CurrentLaunchForce = m_MinLaunchForce;
    30.         m_AimSlider.value = m_MinLaunchForce;
    31.     }
    32.  
    33.  
    34.     private void Start()
    35.     {
    36.         m_FireButton = "Fire" + m_PlayerNumber;
    37.  
    38.         m_ChargeSpeed = (m_MaxLaunchForce - m_MinLaunchForce) / m_MaxChargeTime;
    39.         m_WaitShoot = new WaitForSeconds (m_RechargeTime);
    40.  
    41.     }
    42.  
    43.  
    44.     private void Update()
    45.     {
    46.         // Track the current state of the fire button and make decisions based on the current launch force.
    47.         m_AimSlider.value = m_MinLaunchForce;
    48.  
    49.         StartCoroutine (Shooting ());
    50.  
    51. }
    52.  
    53.     private IEnumerator Shooting()
    54.     {
    55.         while (m_RecentlyFired)
    56.         {
    57.             yield return null;
    58.         }
    59.  
    60.         if(m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired)
    61.         {
    62.             // At max charge, not fired.
    63.             m_CurrentLaunchForce = m_MaxLaunchForce;
    64.             Fire ();
    65.         }
    66.         else if(Input.GetButtonDown(m_FireButton))
    67.         {
    68.             // Have we pressed the fire button for the first time?
    69.             m_Fired = false;
    70.             m_CurrentLaunchForce = m_MinLaunchForce;
    71.  
    72.             m_ShootingAudio.clip = m_ChargingClip;
    73.             m_ShootingAudio.Play();
    74.         }
    75.         else if (Input.GetButton(m_FireButton) && !m_Fired)
    76.         {
    77.             // Holding the fire button, not yet fired
    78.             m_CurrentLaunchForce += m_ChargeSpeed * Time.deltaTime;
    79.  
    80.             m_AimSlider.value = m_CurrentLaunchForce;
    81.         }
    82.         else if (Input.GetButtonUp(m_FireButton) && !m_Fired)
    83.         {
    84.             // Fire button released, not fired yet
    85.             Fire ();
    86.         }
    87.     }
    88.  
    89.  
    90.     private IEnumerator Fire()
    91.     {
    92.         // Instantiate and launch the shell.
    93.             m_Fired = true;
    94.             Reload();
    95.  
    96.             Rigidbody shellInstance = Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;
    97.  
    98.             shellInstance.velocity = m_FireTransform.forward * m_CurrentLaunchForce;
    99.  
    100.             m_ShootingAudio.Stop ();
    101.             m_ShootingAudio.clip = m_FireClip;
    102.             m_ShootingAudio.Play ();
    103.  
    104.             m_CurrentLaunchForce = m_MinLaunchForce;
    105.          
    106.     }
    107.  
    108.     private IEnumerator Reload()
    109.     {
    110.         m_RecentlyFired = true;
    111.         yield return m_WaitShoot;
    112.         m_RecentlyFired = false;
    113.     }
    114. }
     
  3. marceloiaco

    marceloiaco

    Joined:
    Jan 29, 2017
    Posts:
    3
  4. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    You have some logical problems with the code.
    When you start the Coroutine Shooting() from Update(), it will yield until the m_RecentlyFired is false. However, once that happens it will only execute the code after it once. Secondly the Update function is starting a TON of Shooting Coroutines. So Imagine that m_RecentlyFired is true for the next 20 frames. You will end up with 20 Shooting Coroutines all running at the same time and all wiating for m_RecentlyFired to be false. Your better off moving the m_Recently fired check to the Update function and just call Shooting as a regular function

    Secondly Fire is just a regular function not a Coroutine so it doesn't need IEnumerator just void

    Finally Reload is a Coroutine and should be one. So you should call it with StartCoroutine(Reload());
    Here is your code with the previous things changed:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. public class TankShooting : MonoBehaviour
    6. {
    7.     public int m_PlayerNumber = 1;
    8.     public Rigidbody m_Shell;
    9.     public Transform m_FireTransform;
    10.     public Slider m_AimSlider;
    11.     public AudioSource m_ShootingAudio;
    12.     public AudioClip m_ChargingClip;
    13.     public AudioClip m_FireClip;
    14.     public float m_MinLaunchForce = 15f;
    15.     public float m_MaxLaunchForce = 30f;
    16.     public float m_MaxChargeTime = 0.75f;
    17.     public float m_RechargeTime = 2.0f;
    18.     private WaitForSeconds m_WaitShoot;
    19.  
    20.  
    21.     private string m_FireButton;
    22.     private float m_CurrentLaunchForce;
    23.     private float m_ChargeSpeed;
    24.     private bool m_Fired;
    25.     private bool m_RecentlyFired;
    26.  
    27.     private void OnEnable()
    28.     {
    29.         m_CurrentLaunchForce = m_MinLaunchForce;
    30.         m_AimSlider.value = m_MinLaunchForce;
    31.     }
    32.  
    33.  
    34.     private void Start()
    35.     {
    36.         m_FireButton = "Fire" + m_PlayerNumber;
    37.  
    38.         m_ChargeSpeed = (m_MaxLaunchForce - m_MinLaunchForce) / m_MaxChargeTime;
    39.         m_WaitShoot = new WaitForSeconds(m_RechargeTime);
    40.  
    41.     }
    42.  
    43.  
    44.     private void Update()
    45.     {
    46.         // Track the current state of the fire button and make decisions based on the current launch force.
    47.         m_AimSlider.value = m_MinLaunchForce;
    48.         if (!m_RecentlyFired)
    49.             Shooting();
    50.     }
    51.  
    52.     private void Shooting()
    53.     {
    54.         if (m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired)
    55.         {
    56.             // At max charge, not fired.
    57.             m_CurrentLaunchForce = m_MaxLaunchForce;
    58.             Fire();
    59.         }
    60.         else if (Input.GetButtonDown(m_FireButton))
    61.         {
    62.             // Have we pressed the fire button for the first time?
    63.             m_Fired = false;
    64.             m_CurrentLaunchForce = m_MinLaunchForce;
    65.  
    66.             m_ShootingAudio.clip = m_ChargingClip;
    67.             m_ShootingAudio.Play();
    68.         }
    69.         else if (Input.GetButton(m_FireButton) && !m_Fired)
    70.         {
    71.             // Holding the fire button, not yet fired
    72.             m_CurrentLaunchForce += m_ChargeSpeed * Time.deltaTime;
    73.  
    74.             m_AimSlider.value = m_CurrentLaunchForce;
    75.         }
    76.         else if (Input.GetButtonUp(m_FireButton) && !m_Fired)
    77.     `    {
    78.             // Fire button released, not fired yet
    79.             Fire();
    80.         }
    81.     }
    82.  
    83.  
    84.     private void Fire()
    85.     {
    86.         // Instantiate and launch the shell.
    87.         m_Fired = true;
    88.         StartCoroutine(Reload());
    89.  
    90.         Rigidbody shellInstance = Instantiate(m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;
    91.  
    92.         shellInstance.velocity = m_FireTransform.forward * m_CurrentLaunchForce;
    93.  
    94.         m_ShootingAudio.Stop();
    95.         m_ShootingAudio.clip = m_FireClip;
    96.         m_ShootingAudio.Play();
    97.  
    98.         m_CurrentLaunchForce = m_MinLaunchForce;
    99.  
    100.     }
    101.  
    102.     private IEnumerator Reload()
    103.     {
    104.         m_RecentlyFired = true;
    105.         yield return m_WaitShoot;
    106.         m_RecentlyFired = false;
    107.     }
    108. }
     
  5. Bantaru

    Bantaru

    Joined:
    May 11, 2016
    Posts:
    59
    You can do something like so:

    Code (CSharp):
    1. bool ReadyToFire = false;
    2. float ReloadTime = 10;
    3. float ReloadRate = 1;
    4.  
    5. void Update(){
    6. if(!ReadyToFire){
    7. ReloadTime -= Time.deltaTime * RealoadRate;
    8. }
    9. If(ReloadTime <= 0){
    10. ReadyToFire = true;
    11. }
    12. }
    Then all You have to.do is ser ReloadTime to 10 everytime player fire.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    I would go with this way as well @Bantaru ... no need for coroutines for a simple cooldown timer.