Guest User

Untitled

a guest
Jun 20th, 2023
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.71 KB | None | 0 0
  1. using System.Collections;
  2. using UnityEngine;
  3. using TMPro;
  4.  
  5. /// Thanks for downloading my projectile gun script! :D
  6. /// Feel free to use it in any project you like!
  7. ///
  8. /// The code is fully commented but if you still have any questions
  9. /// don't hesitate to write a yt comment
  10. /// or use the #coding-problems channel of my discord server
  11. ///
  12. /// Dave
  13. public class ProjectileGunTutorial : MonoBehaviour
  14. {
  15. //bullet
  16. public GameObject Ammo;
  17. public GameObject bullet;
  18. public Animator animator;
  19. public float damage = 15f;
  20. public Behaviour WS;
  21.  
  22. //bullet force
  23. public float shootForce, upwardForce;
  24.  
  25. //Gun stats
  26. public float timeBetweenShooting, spread, reloadTime, timeBetweenShots;
  27. public int magazineSize, bulletsPerTap;
  28. public bool allowButtonHold;
  29.  
  30. int bulletsLeft, bulletsShot;
  31.  
  32. //Recoil
  33. public Rigidbody playerRb;
  34. public float recoilForce;
  35.  
  36. //bools
  37. bool shooting, readyToShoot, reloading;
  38.  
  39. //Reference
  40. public Camera fpsCam;
  41. public Transform attackPoint;
  42.  
  43. //Graphics
  44. public GameObject muzzleFlash;
  45. public TextMeshProUGUI ammunitionDisplay;
  46.  
  47. //bug fixing :D
  48. public bool allowInvoke = true;
  49.  
  50. private void Awake()
  51. {
  52. //make sure magazine is full
  53. bulletsLeft = magazineSize;
  54. readyToShoot = true;
  55. }
  56.  
  57. private void Update()
  58. {
  59. Ammo.SetActive(true);
  60. MyInput();
  61.  
  62. //Set ammo display, if it exists :D
  63. if (ammunitionDisplay != null)
  64. ammunitionDisplay.SetText(bulletsLeft / bulletsPerTap + " / " + magazineSize / bulletsPerTap);
  65. }
  66.  
  67. private void MyInput()
  68. {
  69. //Check if allowed to hold down button and take corresponding input
  70. if (allowButtonHold)
  71. shooting = Input.GetKey(KeyCode.Mouse0);
  72. else
  73. shooting = Input.GetKeyDown(KeyCode.Mouse0);
  74.  
  75. //Reloading
  76. if (Input.GetKeyDown(KeyCode.R) && bulletsLeft < magazineSize && !reloading)
  77. Reload();
  78.  
  79. //Reload automatically when trying to shoot without ammo
  80.  
  81. //Shooting
  82. if (readyToShoot && shooting && !reloading && bulletsLeft > 0 && Input.GetKey(KeyCode.Mouse0))
  83. {
  84. //Set bullets shot to 0
  85. bulletsShot = 0;
  86. animator.Play("AttackS");
  87. animator.SetTrigger("Attack");
  88. Shoot();
  89. }
  90. else if (!shooting)
  91. {
  92. animator.Play("IdleS");
  93. }
  94. }
  95.  
  96. private void Shoot()
  97. {
  98. bulletsShot = 0;
  99. readyToShoot = false;
  100.  
  101. //Find the exact hit position using a raycast
  102. Ray ray = fpsCam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); //Just a ray through the middle of your current view
  103. RaycastHit hit;
  104.  
  105. //check if ray hits something
  106. Vector3 targetPoint;
  107. if (Physics.Raycast(ray, out hit))
  108. targetPoint = hit.point;
  109. else
  110. targetPoint = ray.GetPoint(75); //Just a point far away from the player
  111.  
  112. //Calculate direction from attackPoint to targetPoint
  113. Vector3 directionWithoutSpread = targetPoint - attackPoint.position;
  114.  
  115. //Calculate spread
  116. float x = Random.Range(-spread, spread);
  117. float y = Random.Range(-spread, spread);
  118.  
  119. //Calculate new direction with spread
  120. Vector3 directionWithSpread = directionWithoutSpread + new Vector3(x, y, 0); //Just add spread to last direction
  121.  
  122. //Instantiate bullet/projectile
  123. GameObject currentBullet = Instantiate(bullet, attackPoint.position, Quaternion.identity);
  124.  
  125. // Attach a script to the bullet to handle destruction
  126. Bullet bulletScript = currentBullet.AddComponent<Bullet>();
  127. bulletScript.lifetime = 5f; // Set the lifetime as desired
  128.  
  129. //Rotate bullet to shoot direction
  130. currentBullet.transform.forward = directionWithSpread.normalized;
  131. currentBullet.transform.Rotate(90.0f, 0.0f, 0.0f, Space.Self);
  132.  
  133. //Add forces to bullet
  134. currentBullet.GetComponent<Rigidbody>().AddForce(directionWithSpread.normalized * shootForce, ForceMode.Impulse);
  135. currentBullet.GetComponent<Rigidbody>().AddForce(fpsCam.transform.up * upwardForce, ForceMode.Impulse);
  136.  
  137. //Instantiate muzzle flash, if you have one
  138. if (muzzleFlash != null)
  139. Instantiate(muzzleFlash, attackPoint.position, Quaternion.identity);
  140.  
  141. bulletsLeft--;
  142. bulletsShot++;
  143.  
  144. //Invoke resetShot function (if not already invoked), with your timeBetweenShooting
  145. if (allowInvoke)
  146. {
  147. Invoke("ResetShot", timeBetweenShooting);
  148. allowInvoke = false;
  149.  
  150. //Add recoil to player (should only be called once)
  151. playerRb.AddForce(-directionWithSpread.normalized * recoilForce, ForceMode.Impulse);
  152. }
  153.  
  154. //if more than one bulletsPerTap make sure to repeat shoot function
  155. if (bulletsShot < bulletsPerTap && bulletsLeft > 0)
  156. {
  157. Invoke("Shoot", timeBetweenShots);
  158. }
  159.  
  160. Target target = hit.transform.GetComponent<Target>();
  161. if (target != null)
  162. {
  163. target.TakeDamage(damage);
  164. }
  165. }
  166.  
  167. private void ResetShot()
  168. {
  169. //Allow shooting and invoking again
  170. readyToShoot = true;
  171. allowInvoke = true;
  172. }
  173.  
  174. private void Reload()
  175. {
  176. reloading = true;
  177. Invoke("ReloadFinished", reloadTime); //Invoke ReloadFinished function with your reloadTime as delay
  178. }
  179.  
  180. private void ReloadFinished()
  181. {
  182. //Fill magazine
  183. bulletsLeft = magazineSize;
  184. reloading = false;
  185. }
  186. }
  187.  
Advertisement
Add Comment
Please, Sign In to add comment