ProjectileGunScript

PHOTO EMBED

Thu Apr 28 2022 14:09:48 GMT+0000 (Coordinated Universal Time)

Saved by @DanDHenshaw

using System;
using UnityEngine;
using TMPro;
using Random = UnityEngine.Random;

public class ProjectileGunScript : MonoBehaviour
{
    private Controls _controls;
    [SerializeField] private Camera _camera;
    private Animator _animator;
    private AudioSource _audioSource;

    [Header("Important")]
    public Transform attackPoint;
    public GameObject projectile;
    
    [Header("Gun Stats")] 
    [SerializeField] private float damage;
    [SerializeField] private float ammo;
    [SerializeField] private float  currentAmmo;
    [SerializeField] private float spread;
    [SerializeField] private float shootForce;
    [SerializeField] private float upwardForce;

    [Header("Visuals & Effects")] 
    [SerializeField] private ParticleSystem muzzleFlash;
    [SerializeField] private AudioClip shootingSound;
    [SerializeField] private AudioClip reloadSound;
    [SerializeField] private TextMeshProUGUI ammoText;
    
    private bool isShooting = false, isReloading = false;

    private void Awake()
    {
        currentAmmo = ammo;
        
        _animator = GetComponent<Animator>();
        _audioSource = GetComponent<AudioSource>();
        
        _controls = new Controls();
        _controls.Player.Shoot.started += _ => Shoot();
        _controls.Player.Reload.started += _ => Reload();
    }

    private void Update()
    {
        ammoText.SetText($"AMMO: {currentAmmo}/{ammo}");
    }

    private void Shoot()
    {
        if (!isReloading && currentAmmo > 0 && !isShooting)
        {
            isShooting = true;

            //Find the exact hit position using a raycast
            Ray ray = _camera.ViewportPointToRay(new Vector3(0.5f, 0.5f,
                0)); //Just a ray through the middle of your current view
            RaycastHit hit;

            //check if ray hits something
            Vector3 targetPoint;
            if (Physics.Raycast(ray, out hit))
                targetPoint = hit.point;
            else
                targetPoint = ray.GetPoint(75); //Just a point far away from the player

            //Calculate direction from attackPoint to targetPoint
            Vector3 directionWithoutSpread = targetPoint - attackPoint.position;

            //Calculate spread
            float x = Random.Range(-spread, spread);
            float y = Random.Range(-spread, spread);

            //Calculate new direction with spread
            Vector3 directionWithSpread = directionWithoutSpread + new Vector3(x, y, 0); //Just add spread to last direction

            //Instantiate bullet/projectile
            GameObject currentBullet =
                Instantiate(projectile, attackPoint.position,
                    Quaternion.identity); //store instantiated bullet in currentBullet
            //Rotate bullet to shoot direction
            currentBullet.transform.forward = directionWithSpread.normalized;

            //Add forces to bullet
            currentBullet.GetComponent<Rigidbody>()
                .AddForce(directionWithSpread.normalized * shootForce, ForceMode.Impulse);
            currentBullet.GetComponent<Rigidbody>().AddForce(_camera.transform.up * upwardForce, ForceMode.Impulse);

            currentBullet.GetComponent<ProjectileScript>().damage = damage;

            //Instantiate muzzle flash, if you have one
            if (muzzleFlash != null)
                muzzleFlash.Play();
            
            _audioSource.clip = shootingSound;
            _audioSource.Play();
            _animator.SetTrigger("Shot");
            Debug.Log("Shot");
            
            currentAmmo--;
        } else if (currentAmmo <= 0)
        {
            Reload();
        }
    }

    private void Reload()
    {
        if (!isShooting && !isReloading)
        {
            isReloading = true;
            
            _audioSource.clip = reloadSound;
            _audioSource.Play();
            _animator.SetTrigger("Reload");
            Debug.Log("Reload");
        }
    }

    public void CanReload()
    {
        isReloading = false;
        currentAmmo = ammo;
    }
    
    public void CanShoot()
    {
        isShooting = false;
    }
    
    private void OnEnable()
    {
        _controls.Enable();
    }

    private void OnDisable()
    {
        _controls.Disable();
    }
}
content_copyCOPY