Advertisement
Guest User

Gun class

a guest
Nov 19th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.53 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class Gun : MonoBehaviour {
  6.  
  7.     // Dependiences
  8.     public GameObject bulletHolePrefab;
  9.     public ParticleSystem muzzleFlash;
  10.     public Transform muzzle;
  11.     public Transform weaponModel;
  12.     private Camera weaponCamera;
  13.  
  14.     // Properties of the gun
  15.     public float damage;
  16.     public int rateOfFire;
  17.     public float maxVerticalRecoil;
  18.     public float verticalRecoilStep;
  19.     public float maxHorizontalRecoil;
  20.     public float horizontalRecoilStep;
  21.     public int magCapacity;
  22.     public int maxAmmo;
  23.     public float reloadingTime;
  24.     public AudioClip shootAudio;
  25.     public Vector3 hipPos;
  26.     public Vector3 sightedPos;
  27.  
  28.     private Transform playerCamera;
  29.     private float fireCooldown;
  30.     private float fireInterval;
  31.     private List<GameObject> bulletHolesList;
  32.  
  33.     [HideInInspector]
  34.     public int ammoInMag;
  35.     [HideInInspector]
  36.     public int ammoLeft;
  37.  
  38.     public float verticalRecoil;
  39.     public float horizontalRecoil;
  40.     private float recoilCooldown;
  41.     private bool isReloading = false;
  42.  
  43.     void Awake()
  44.     {
  45.         // set the right camera and move the weapon to hip pos
  46.         weaponCamera = transform.parent.GetComponent<Camera>();
  47.         weaponModel.localPosition = hipPos;
  48.  
  49.         playerCamera = transform.parent;
  50.  
  51.         //calculate the interval between shots to match the rate of fire
  52.         if (rateOfFire > 1)
  53.             fireInterval = 1f / (rateOfFire / 60);
  54.         else
  55.             fireInterval = 0.1f;
  56.  
  57.         // update the UI and set all the ammo to right values
  58.         UIUpdate();
  59.         ammoInMag = magCapacity;
  60.         ammoLeft = 0;
  61.  
  62.         // zero out the recoil and cooldowns
  63.         fireCooldown = 0;
  64.         recoilCooldown = 0;
  65.     }
  66.    
  67.     void Update () {
  68.  
  69.         //right click = zoom and sighted position, otherwise hip pos
  70.         if(Input.GetKey(KeyCode.Mouse1))
  71.             SightAim();
  72.         else
  73.             HipAim();
  74.  
  75.         //lmb = tries to fire, if weapon is automatic then fires automaticaly
  76.         if (Input.GetButton("Fire1") && rateOfFire > 1)
  77.         {
  78.             TryToFire();
  79.         }
  80.         else if(Input.GetButtonDown("Fire1"))
  81.         {
  82.             TryToFire();
  83.         }
  84.  
  85.         //r = reloads
  86.         if(Input.GetKeyDown(KeyCode.R))
  87.         {
  88.             StartCoroutine(Reload());
  89.         }
  90.  
  91.         //descreases fire cooldown as time passes, manages the right rate of fire
  92.         if(fireCooldown > 0)
  93.         {
  94.             fireCooldown -= Time.deltaTime;
  95.         }
  96.  
  97.         //calculates the recoil descrease
  98.         RecoilChecks();
  99.            
  100.        
  101.     }
  102.  
  103.     void RecoilChecks()
  104.     {
  105.         //the recoil value always decreases
  106.         if (recoilCooldown > 0)
  107.             recoilCooldown -= Time.deltaTime;
  108.  
  109.         //in case of recoil being lower than 0 it goes to zero
  110.         if (recoilCooldown < 0)
  111.             recoilCooldown = 0;
  112.  
  113.         //if you haven't shot in a while and there is vrecoil, decrease it
  114.         if (verticalRecoil > 0 && recoilCooldown == 0)
  115.             verticalRecoil -= (Time.deltaTime / 10f);
  116.  
  117.         //in case of recoil being lower than 0 it goes to zero
  118.         if (verticalRecoil < 0)
  119.             verticalRecoil = 0;
  120.  
  121.         //if you haven't shot in a while and there is hrecoil, decrease it
  122.         if (horizontalRecoil != 0 && recoilCooldown == 0)
  123.         {
  124.             if(horizontalRecoil > 0)
  125.                 horizontalRecoil -= (Time.deltaTime / 10f);
  126.             else
  127.                 horizontalRecoil += (Time.deltaTime / 10f);
  128.         }
  129.  
  130.         //if the hrecoil is very close to 0, set it to 0
  131.         if (Mathf.Abs(horizontalRecoil) < 0.001f)
  132.             horizontalRecoil = 0;
  133.  
  134.         //try to bring the weapon to 0,0,0 (remove the visual recoil)
  135.         if (transform.localRotation != Quaternion.Euler(Vector3.zero))
  136.             transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(Vector3.zero), Time.deltaTime * 2);
  137.            
  138.     }
  139.     void TryToFire()
  140.     {
  141.         //if the weapon is semi automatic or the fire cooldown is zero AND there is any ammo, fire
  142.         if ((fireCooldown <= 0 || rateOfFire == 1) && ammoInMag > 0 && !isReloading)
  143.         {
  144.             //fire, decrease ammo in mag, add fire cooldown and update the UI
  145.             Fire();
  146.             ammoInMag--;
  147.             fireCooldown += fireInterval;
  148.  
  149.             UIUpdate();
  150.         }
  151.  
  152.     }
  153.  
  154.     void Fire()
  155.     {    
  156.         //calculate the shot direction including the recoil
  157.         Vector3 dir = playerCamera.forward + new Vector3(0, verticalRecoil, 0) + (playerCamera.right * horizontalRecoil);
  158.  
  159.         //the direction of the shot is the forward vector modified by the recoil
  160.         Ray ray = new Ray(playerCamera.position, dir);
  161.         RaycastHit hit;
  162.  
  163.         //play the fire sound and instantiate the particle system
  164.         GetComponent<AudioSource>().PlayOneShot(shootAudio, 0.5f);
  165.         Instantiate(muzzleFlash, muzzle.position, muzzle.rotation, muzzle);
  166.  
  167.         //[DEBUG] draw the ray in the preview
  168.         Debug.DrawRay(playerCamera.position, playerCamera.forward * 100, Color.cyan);
  169.  
  170.         //if the raycast hit anything
  171.         if (Physics.Raycast(ray, out hit, 100f))
  172.         {
  173.             //[DEBUG] draw a line between the player and hit point
  174.             Debug.DrawLine(playerCamera.position, hit.point, Color.red);
  175.             //instantiate a bullet hole and inflict weapon's damage on the hit target
  176.             Instantiate(bulletHolePrefab, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal), hit.transform);
  177.             DealDamage(hit);
  178.         }
  179.  
  180.         //recoil using the firing direction
  181.         Recoil(dir);    
  182.     }
  183.  
  184.     void DealDamage(RaycastHit hit)
  185.     {
  186.         //if we hit the enemy, damage it
  187.         if(hit.transform.CompareTag("Enemy"))
  188.         {
  189.             hit.transform.SendMessage("TakeDamage", damage, SendMessageOptions.DontRequireReceiver);
  190.         }
  191.     }
  192.  
  193.     IEnumerator Reload()
  194.     {
  195.         //cant do few reloads at the same time
  196.         if (isReloading || ammoInMag == magCapacity)
  197.             yield break;
  198.  
  199.         //calculate the ammo needed to fill the mag
  200.  
  201.         int ammoNeeded = magCapacity - ammoInMag;
  202.  
  203.         //reloading takes a while
  204.         isReloading = true;
  205.         StartCoroutine(UIManager.instance.Reloading(reloadingTime));
  206.         yield return new WaitForSeconds(reloadingTime);
  207.         isReloading = false;
  208.  
  209.         //if we have more ammo than needed fill the mag and subtract ammo needed
  210.         if(ammoLeft >= ammoNeeded)
  211.         {
  212.             ammoInMag = magCapacity;
  213.             ammoLeft -= ammoNeeded;
  214.         }
  215.         else
  216.         {
  217.             // otherwise add all the ammo to the mag and zero the leftover ammo
  218.             ammoInMag += ammoLeft;
  219.             ammoLeft = 0;
  220.         }
  221.  
  222.         //update the UI
  223.         UIUpdate();        
  224.     }
  225.  
  226.     //in case reload is stopped by switching slots
  227.     public void CancelReload()
  228.     {
  229.         StopCoroutine(Reload());
  230.         isReloading = false;
  231.     }
  232.  
  233.     void Recoil(Vector3 dir)
  234.     {
  235.         //recoil won't decrease until player hasn't shot for the next interval
  236.         recoilCooldown += fireInterval;
  237.  
  238.         //if the vrecoil is below maximum, add more
  239.         if(verticalRecoil <= maxVerticalRecoil)
  240.         {
  241.             verticalRecoil += verticalRecoilStep;
  242.         }
  243.         else
  244.         {
  245.             //otherwise set it to maximum
  246.             verticalRecoil = maxVerticalRecoil;
  247.         }
  248.  
  249.         //if the hrecoil is below maximum, add more
  250.         if (Mathf.Abs(horizontalRecoil) <= maxHorizontalRecoil)
  251.         {
  252.             //the hrecoil is random, but in the range of the step
  253.             float randomRecoil = Random.Range(-horizontalRecoilStep, horizontalRecoilStep);
  254.             horizontalRecoil += randomRecoil;
  255.         }
  256.         else
  257.         {
  258.             //otherwise set it to maximum
  259.             horizontalRecoil = maxHorizontalRecoil;
  260.         }
  261.  
  262.         //play the firing animation and make the model look in the firing direction
  263.         GetComponent<Animator>().SetTrigger("Fire");
  264.         transform.rotation = Quaternion.LookRotation(dir, Vector3.up);
  265.     }
  266.  
  267.     public void UIUpdate()
  268.     {
  269.         //update the ammo UI
  270.         UIManager.instance.UpdateAmmoUI(ammoInMag, ammoLeft);
  271.     }
  272.  
  273.     public void RefillAmmo(int amount)
  274.     {
  275.         //if you want to refill more ammo than you can carry, max it out, otherwise just add it
  276.         if (ammoLeft + amount <= maxAmmo)
  277.             ammoLeft += amount;
  278.         else
  279.             ammoLeft = maxAmmo;
  280.  
  281.         //update the ammo UI
  282.         UIUpdate();
  283.     }
  284.  
  285.     //aim through the sights
  286.     void SightAim()
  287.     {
  288.         //decrease the fov for better visibility
  289.         weaponCamera.fieldOfView = 20;
  290.  
  291.         //smoothly transform to sightpos
  292.         if (Vector3.Distance(weaponModel.localPosition, sightedPos) <= 0.001f)
  293.             weaponModel.localPosition = sightedPos;
  294.         else
  295.             weaponModel.localPosition = Vector3.Lerp(weaponModel.localPosition, sightedPos, Time.deltaTime * 10);
  296.     }
  297.  
  298.     void HipAim()
  299.     {
  300.         //inscrease the fov for normal view
  301.         weaponCamera.fieldOfView = 50;
  302.  
  303.         //smoothly transform to hippos
  304.         if (Vector3.Distance(weaponModel.localPosition, hipPos) <= 0.001f)
  305.             weaponModel.localPosition = hipPos;
  306.         else
  307.             weaponModel.localPosition = Vector3.Lerp(weaponModel.localPosition, hipPos, Time.deltaTime * 10);
  308.     }
  309. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement