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();
}
}