bigdogdylan00

SciGun Arena GunScript.cs

Aug 16th, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 16.40 KB | None | 0 0
  1. //Dylan Taylor - Project SciGun
  2. //This script is attached to all gun objects, and gives them their behavior. This script is what tells them how to fire and behave.
  3.  
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using UnityEngine;
  7. using UnityEngine.Networking;
  8.  
  9. public class GunScript : NetworkBehaviour
  10. {
  11.     //It should be noted that all of these assigned values are simply placeholders or default values, and are generally overwritten in Unity itself.
  12.  
  13.     public Animator animator; //The animation controller of the gun.
  14.  
  15.     public GameObject bulletPrefab; //The bullet for the gun to fire
  16.     public GameObject bulletSpawn; //The location for the gun to spawn the bullet
  17.     public GameObject owner; //The player who's in control of this gun.
  18.  
  19.     private int oldFOV; //The camera's Field of View before zooming in/out
  20.     public int primaryFiringMode = 0; //Which firing mode the gun should use
  21.     public int secondaryFiringMode = 3;
  22.     public int numBulletsToBurst = 3; //How many bullets for the gun to bust, if it uses the burst firing mode.
  23.     [SyncVar] //Sync the value of the next variable over the network, with all instances of this object.
  24.     public int totalAmmo = 30; //The amount of ammo that the gun has in total.
  25.     public int MAX_LOADED_AMMO = 12;
  26.     [SyncVar]
  27.     public int loadedAmmo = 0; //How much ammo the gun has loaded
  28.     public int firingPower = 100; //How much physics force to give the bullet as it leaves the gun.
  29.  
  30.     public float zoom = 2f; //The magnification level for weapons that use the zoom feature.
  31.     public float fireDelay = .5f; //How long (in seconds) to wait before allowing the gun to fire again.
  32.     public float accuracy = 2.5f; //An accuracy of 0 means that the gun has no spread.
  33.  
  34.     public Texture gunIcon; //The gun's icon, to show up in the bottom-right corner of the game when the weapon is picked up.
  35.  
  36.     public string gunName = "Weapon"; //Give the weapon a default name, in case it isn't assigned in the inspector.
  37.  
  38.     [SerializeField] //Make the private variable modifiable in the Unity editor itself, while keeping it private
  39.     private AudioSource audioSource; //The gun's audio source, to be used to play gunshot and relaod sounds
  40.  
  41.     [SerializeField]
  42.     private AudioClip primary; //The AudioClip sound for the primary fire. This will be played every time a bullet is fired.
  43.     [SerializeField]
  44.     private AudioClip secondary; //The AudioClip sound for the secondary fire. This will be played every time a bullet is fired.
  45.     [SerializeField]
  46.     private AudioClip reload; //The AudioClip sound for reloading. This will be played when the player reloads.
  47.  
  48.     private bool stillFiring = false; //If this is true, the gun cannot fire as it is in cooldown mode.
  49.     private bool holdingPrimary = false; //The boolean variable to determine if the player is still holding down the primary firing button.
  50.     private bool holdingSecondary = false; //The boolean variable to determine if the player is still holding down the secondary firing button.
  51.  
  52.     private Camera cam; //The local player's camera object
  53.  
  54.     // Use this for initialization
  55.     void Start()
  56.     {
  57.         if (loadedAmmo == 0)
  58.         {
  59.             loadedAmmo = Random.Range(0, MAX_LOADED_AMMO); //Put a random amount of ammo in the magazine to begin with, and remove that number of bullets from totalAmmo. Only do this if loadedAmmo wasn't already assigned.
  60.             totalAmmo -= loadedAmmo;
  61.         }
  62.     }
  63.  
  64.     // Update is called once per frame
  65.     void Update()
  66.     {
  67.         if(cam == null)
  68.         {
  69.             foreach(GameObject c in GameObject.FindGameObjectsWithTag("MainCamera"))
  70.             {
  71.                 if(c.name == "Local Camera")
  72.                 {
  73.                     cam = c.GetComponent<Camera>();
  74.                     oldFOV = (int)cam.fieldOfView;
  75.                 }
  76.             }
  77.         }
  78.     }
  79.  
  80.     public void FirePrimary() //This function gets called when the user clicks the left mouse button.
  81.     {
  82.         if (stillFiring == false)
  83.         {
  84.             if (primaryFiringMode == 0) //Fires a single bullet
  85.             {
  86.                 if (loadedAmmo > 0)
  87.                 {
  88.                     animator.SetBool("Fire0", true); //Tell the animator that we're firing, and tell it if it's primary or secondary
  89.                     CmdFire(0);
  90.                     animator.SetBool("Fire0", false); //Tell the animator that we're done firing, and tell it if it's primary or secondary
  91.                 }
  92.             }
  93.             else if (primaryFiringMode == 1) //Fires numBulletsToBurst bullets in a shotgun-like pattern, with high spread
  94.             {
  95.                 if (loadedAmmo >= numBulletsToBurst)
  96.                 {
  97.                     animator.SetBool("Fire0", true); //Tell the animator that we're firing, and tell it if it's primary or secondary
  98.                     for (int i = 0; i < numBulletsToBurst; i++)
  99.                     {
  100.                         if (loadedAmmo > 0)
  101.                         {
  102.                             CmdFire(0);
  103.                         }
  104.                     }
  105.                     animator.SetBool("Fire0", false);
  106.                 }
  107.             }
  108.             else if (primaryFiringMode == 2) //Burst fire mode
  109.             {
  110.                 if (Input.GetButton("Fire2") && stillFiring == false) //Burst fire
  111.                 {
  112.                     CmdBurst(numBulletsToBurst, 0);
  113.                 }
  114.             }
  115.             else if (primaryFiringMode == 3) //Aim-Down-Sights mode
  116.             {
  117.                 StartCoroutine(ZoomIn());
  118.             }
  119.             else if (primaryFiringMode == 4) //Full-Auto mode
  120.             {
  121.                 holdingPrimary = true;
  122.                 StartCoroutine(FullAuto(0));
  123.             }
  124.  
  125.  
  126.             else
  127.             {
  128.                 Debug.LogError("Primary firing mode " + primaryFiringMode + " has not been defined in GunScript.cs");
  129.             }
  130.         }
  131.     }
  132.  
  133.     public void FireSecondary() //This function gets called when the player clicks the right mouse button.
  134.     {
  135.         if (secondaryFiringMode == 0) //Fires a single bullet
  136.         {
  137.             if (loadedAmmo > 0)
  138.             {
  139.                 animator.SetBool("Fire1", true); //Tell the animator that we're firing, and tell it if it's primary or secondary
  140.                 CmdFire(1);
  141.                 animator.SetBool("Fire1", false);
  142.             }
  143.         }
  144.         else if (secondaryFiringMode == 1) //Fires numBulletsToBurst bullets in a shotgun-like pattern, with high spread
  145.         {
  146.             if (loadedAmmo >= numBulletsToBurst)
  147.             {
  148.                 animator.SetBool("Fire1", true);
  149.                 for (int i = 0; i < numBulletsToBurst; i++)
  150.                 {
  151.                     if (loadedAmmo > 0)
  152.                     {
  153.                         CmdFire(1);
  154.                     }
  155.                 }
  156.                 animator.SetBool("Fire1", false);
  157.             }
  158.         }
  159.         else if (secondaryFiringMode == 2) //Burst fire mode
  160.         {
  161.             if (Input.GetButton("Fire2") && stillFiring == false) //Burst fire
  162.             {
  163.                 CmdBurst(numBulletsToBurst, 1);
  164.             }
  165.         }
  166.         else if (secondaryFiringMode == 3) //Aim-Down-Sights mode
  167.         {
  168.             StartCoroutine(ZoomIn());
  169.         }
  170.         else if (secondaryFiringMode == 4) //Full-Auto mode
  171.         {
  172.             holdingSecondary = true;
  173.             StartCoroutine(FullAuto(1));
  174.         }
  175.  
  176.  
  177.         else
  178.         {
  179.             Debug.LogError("Secondary firing mode " + secondaryFiringMode + " has not been defined in GunScript.cs");
  180.         }
  181.     }
  182.  
  183.     public void Reload() //Tells the animator that the gun should reload. This triggers the reload animation, and this animation will call the RealReload function after it has finished to actually adjust the ammo count.
  184.     {
  185.         stillFiring = true;
  186.         UpPrimary();
  187.         UpSecondary();
  188.         if (loadedAmmo < MAX_LOADED_AMMO && totalAmmo > 0)
  189.         {
  190.             animator.SetTrigger("Reload");
  191.         }
  192.     }
  193.  
  194.     public void RealReload() //This function will transfer as much ammo as it can from totalAmmo to loadedAmmo, without exceding MAX_LOADED_AMMO, and without allowing totalAmmo to become negative.
  195.     {
  196.         if (loadedAmmo < MAX_LOADED_AMMO) //When reloading, check to see if there is enough ammo to fully fill the mag.
  197.         {
  198.             if (totalAmmo > (MAX_LOADED_AMMO - loadedAmmo))
  199.             {
  200.                 totalAmmo -= (MAX_LOADED_AMMO - loadedAmmo); //Subtract the difference between the loaded ammo amount and the max loaded ammo amount
  201.                 loadedAmmo = MAX_LOADED_AMMO; //Fill the mag
  202.             }
  203.             else if (totalAmmo + loadedAmmo <= MAX_LOADED_AMMO)
  204.             {
  205.                 loadedAmmo += totalAmmo; //If there isn't enough in totalAmmo to fill the mag, put all remaining bullets in the mag, and set the totalAmmo to 0.
  206.                 totalAmmo = 0;
  207.             }
  208.             else if (totalAmmo == MAX_LOADED_AMMO) //Otherwise, if there's no loadedAmmo and there's enough to fill the mag, then fill the mag and set totalAmmo to 0.
  209.             {
  210.                 loadedAmmo = MAX_LOADED_AMMO;
  211.                 totalAmmo = 0;
  212.             }
  213.             animator.ResetTrigger("Reload"); //Tell the animator that we're done reloading.
  214.             stillFiring = false;
  215.             UpPrimary();
  216.             UpSecondary();
  217.             Debug.Log("loadedAmmo: " + loadedAmmo);
  218.         }
  219.     }
  220.  
  221.     [Command]
  222.     public void CmdBurst(int numBursts, int c) //Accepts a number of bullets to burst fire, and an int c to tell the gun which sound clip to play (0 = primary fire sound, 1 = secondary fire mode, 2 = reload sound)
  223.     {
  224.         if(!stillFiring) //If the gun isn't currently firing or in its wait period for firing, we're clear to move on
  225.             StartCoroutine(Burst(numBursts, c)); //Start the firing coroutine. This has to be in a coroutine so that the firing method can wait to fire until the wait period for firing again is over.
  226.     }
  227.  
  228.     [Command]
  229.     public void CmdFire(int c) //This is the function that ultimately tells the server to actually fire the gun. Accepts an int parameter to tell it which sound clip to play.
  230.     {
  231.         StartCoroutine(Fire(c));
  232.     }
  233.  
  234.     public IEnumerator Burst(int numBursts, int c) //This will repeatedly call CmdFire(c) numBursts times
  235.     {
  236.         stillFiring = true;
  237.         animator.SetFloat("BurstSpeed", 3); //Tell the animator to play the firing animation at triple-speed
  238.         for (int i = 0; i < numBursts; i++)
  239.         {
  240.             if (loadedAmmo > 0) //Make sure we don't fire more times than our ammo allows for.
  241.             {
  242.                 CmdFire(c);
  243.                 yield return new WaitForSeconds(fireDelay / 3f); //Wait for one-third of the gun's normal fireDelay, then fire another round. This allows the gun to burst fire much more quickly than simply firing normally
  244.             }
  245.             else
  246.             {
  247.                 stillFiring = false;
  248.                 break;
  249.             }
  250.             animator.SetBool("Fire" + c, false);
  251.         }
  252.         yield return new WaitForSeconds(fireDelay / 3);
  253.         animator.SetFloat("BurstSpeed", 1); //Tell the animator to play the firing animation at normal speed
  254.         yield return new WaitForSeconds(fireDelay * (2 / 3));
  255.         animator.SetBool("Fire" + c, false);
  256.         stillFiring = false;
  257.     }
  258.  
  259.     public IEnumerator Fire(int c) //This is the function that occurs locally on the serverside. Accepts an int c to determine which sound clip to play.
  260.     {
  261.         stillFiring = true;
  262.         if (loadedAmmo > 0)
  263.         {
  264.             CmdPlaySound(c);
  265.             loadedAmmo--;
  266.             GameObject bullet = (GameObject)Instantiate(
  267.                 bulletPrefab,
  268.                 bulletSpawn.transform.position,
  269.                 new Quaternion(90, bulletSpawn.transform.rotation.y, bulletSpawn.transform.rotation.z, 0));
  270.             bullet.GetComponent<Rigidbody>().velocity = (bulletSpawn.transform.forward * firingPower) + (bulletSpawn.transform.up * Random.Range(-1 * accuracy, accuracy)) + (bulletSpawn.transform.right * Random.Range(-1 * accuracy, accuracy)); // Add velocity to the bullet, and add a random bit of spread based on the gun's accuracy
  271.             NetworkServer.Spawn(bullet);//Spawn the bullet for all connected players
  272.             bullet.GetComponent<Bullet>().owner = PlayerPrefs.GetString("Player Name");
  273.             bullet.GetComponent<Bullet>().firingPlayer = owner;
  274.             yield return new WaitForSeconds(fireDelay);
  275.             stillFiring = false; //Tell the scripts that we're cleared to fire again
  276.             yield return new WaitForSeconds(2f - fireDelay);
  277.             NetworkServer.Destroy(bullet); //This destroys the bullet after 2 seconds on all connected games, so that someone doesn't fire into the sky and never have the bullet break. If we did this, the game would eventually slow down drastically
  278.         }
  279.     }
  280.    
  281.     [Command]
  282.     public void CmdPlaySound(int c)
  283.     {
  284.         RpcPlaySound(c); //Call the "Play Sound" function on all connected clients.
  285.     }
  286.  
  287.     [ClientRpc] //The server will always call a ClientRPC function. The [ClientRPC] Attribute, along with RpcXXX(), means that this object will have this function called on it in every instance of the connected games.
  288.     public void RpcPlaySound(int c) //Plays "AudioClip c" through the gun's AudioSource component.
  289.     {
  290.         if (c == 0)
  291.             audioSource.PlayOneShot(primary);
  292.         else if (c == 1)
  293.             audioSource.PlayOneShot(secondary);
  294.         else
  295.             audioSource.PlayOneShot(reload);
  296.     }
  297.  
  298.  
  299.     [Command]
  300.     public void CmdAddAmmo(int a) //Used for picking up ammo. This function will be called from the gunControllerScript.
  301.     {
  302.         totalAmmo += a;
  303.     }
  304.  
  305.     public Texture GetGunIcon() //Return the weapon's icon, so that it shows up in the UI for the player.
  306.     {
  307.         return gunIcon;
  308.     }
  309.  
  310.     public string GetName() //Return the assigned name of this object to the gunControllerScript, so that it shows up in the UI for the player.
  311.     {
  312.         return gunName;
  313.     }
  314.  
  315.     public string[] GetAmmo() //returns a string array, with the first element being the loaded ammo and the second element being total remaining ammo. This is done to allow for only one function call from the gunHandler script.
  316.     {
  317.         return new string[2] { loadedAmmo.ToString(), totalAmmo.ToString() };
  318.     }
  319.  
  320.     public IEnumerator ZoomIn() //Zooms the player's camera in, for firing modes that use zoom.
  321.     {
  322.        
  323.         while(cam.fieldOfView > (int)(oldFOV / zoom))
  324.         {
  325.             cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, (int)(oldFOV / zoom), 2);
  326.             yield return new WaitForEndOfFrame(); //We don't actually need a wait function, this is just to satisfy the requirement for a yield return value. I don't want to change this to a void function in case I want to animate via scripting
  327.         }
  328.     }
  329.  
  330.     public IEnumerator ZoomOut() //Zooms the player's camera back to its original Field of View.
  331.     {
  332.         cam.fieldOfView = oldFOV;
  333.         yield return new WaitForEndOfFrame(); //We don't actually need a wait function, this is just to satisfy the requirement for a yield return value. I don't want to change this to a void function in case I want to animate via scripting
  334.     }
  335.  
  336.  
  337.     public void UpPrimary() //This is called when the player lets go of the primary firing button (left mouse button).
  338.     {
  339.         holdingPrimary = false;
  340.         if(primaryFiringMode == 3)
  341.         {
  342.             StartCoroutine(ZoomOut());
  343.         }
  344.     }
  345.  
  346.     public void UpSecondary() //This is called when the player lets go of the secondary firing button (right mouse button).
  347.     {
  348.         holdingSecondary = false;
  349.         if(secondaryFiringMode == 3)
  350.         {
  351.             StartCoroutine(ZoomOut());
  352.         }
  353.     }
  354.  
  355.     public IEnumerator FullAuto(int c) //The coroutine to handle full-auto firing. Accepts an int c to determine which sound clip to play.
  356.     {
  357.         stillFiring = true;
  358.         animator.SetBool("Fire" + c, true);
  359.         while ((holdingPrimary || holdingSecondary) && loadedAmmo > 0)
  360.         {
  361.             CmdFire(c);
  362.             yield return new WaitForSeconds(fireDelay);
  363.         }
  364.         stillFiring = false;
  365.         holdingPrimary = false;
  366.         holdingSecondary = false;
  367.         animator.SetBool("Fire" + c, false);
  368.     }
  369. }
Add Comment
Please, Sign In to add comment