156 lines
4.0 KiB
C#
156 lines
4.0 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class PlayerShooting : MonoBehaviour
|
|
{
|
|
// --- Настройки оружия ---
|
|
public int damagePerShot = 20;
|
|
public float timeBetweenBullets = 0.15f;
|
|
public float range = 100f;
|
|
public float effectsDuration = 0.05f;
|
|
|
|
// --- Боеприпасы и перезарядка ---
|
|
public int maxAmmo = 30;
|
|
private int currentAmmo;
|
|
public float reloadTime = 1.5f;
|
|
private bool isReloading = false;
|
|
|
|
// --- Ссылки на компоненты и объекты ---
|
|
public GameObject muzzleFlashSprite;
|
|
public Text ammoText;
|
|
public AudioClip reloadSound;
|
|
|
|
private float timer;
|
|
private Ray shootRay = new Ray();
|
|
private RaycastHit shootHit;
|
|
private int shootableMask;
|
|
private ParticleSystem gunParticles;
|
|
private LineRenderer gunLine;
|
|
private AudioSource gunAudio;
|
|
private Light gunLight;
|
|
|
|
void Awake()
|
|
{
|
|
shootableMask = LayerMask.GetMask("Shootable");
|
|
gunParticles = GetComponent<ParticleSystem>();
|
|
gunLine = GetComponent<LineRenderer>();
|
|
gunAudio = GetComponent<AudioSource>();
|
|
gunLight = GetComponent<Light>();
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
currentAmmo = maxAmmo;
|
|
UpdateAmmoText();
|
|
|
|
if (gunLight != null) gunLight.enabled = false;
|
|
if (muzzleFlashSprite != null) muzzleFlashSprite.SetActive(false);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
timer += Time.deltaTime;
|
|
|
|
if (Input.GetKeyDown(KeyCode.R) && !isReloading && currentAmmo < maxAmmo)
|
|
{
|
|
StartCoroutine(Reload());
|
|
return;
|
|
}
|
|
|
|
if (isReloading)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (Input.GetButton("Fire1") && timer >= timeBetweenBullets && currentAmmo > 0)
|
|
{
|
|
Shoot();
|
|
}
|
|
else if (Input.GetButtonDown("Fire1") && currentAmmo <= 0)
|
|
{
|
|
// Звук щелчка пустого магазина можно добавить здесь
|
|
}
|
|
}
|
|
|
|
void Shoot()
|
|
{
|
|
timer = 0f;
|
|
|
|
currentAmmo--;
|
|
UpdateAmmoText();
|
|
|
|
gunAudio.Play();
|
|
|
|
gunParticles.Stop();
|
|
gunParticles.Play();
|
|
|
|
StartCoroutine(HandleEffects());
|
|
|
|
shootRay.origin = transform.position;
|
|
shootRay.direction = transform.forward;
|
|
|
|
if (Physics.Raycast(shootRay, out shootHit, range, shootableMask))
|
|
{
|
|
Target target = shootHit.collider.GetComponent<Target>();
|
|
if (target != null)
|
|
{
|
|
target.TakeDamage(damagePerShot);
|
|
}
|
|
gunLine.SetPosition(0, transform.position);
|
|
gunLine.SetPosition(1, shootHit.point);
|
|
}
|
|
else
|
|
{
|
|
gunLine.SetPosition(0, transform.position);
|
|
gunLine.SetPosition(1, shootRay.origin + shootRay.direction * range);
|
|
}
|
|
}
|
|
|
|
IEnumerator HandleEffects()
|
|
{
|
|
gunLight.enabled = true;
|
|
gunLine.enabled = true;
|
|
if (muzzleFlashSprite != null)
|
|
{
|
|
muzzleFlashSprite.SetActive(true);
|
|
muzzleFlashSprite.transform.localRotation = Quaternion.Euler(0, 0, Random.Range(0, 360));
|
|
}
|
|
|
|
yield return new WaitForSeconds(effectsDuration);
|
|
|
|
gunLight.enabled = false;
|
|
gunLine.enabled = false;
|
|
if (muzzleFlashSprite != null)
|
|
{
|
|
muzzleFlashSprite.SetActive(false);
|
|
}
|
|
}
|
|
|
|
IEnumerator Reload()
|
|
{
|
|
isReloading = true;
|
|
|
|
if (reloadSound != null)
|
|
{
|
|
gunAudio.PlayOneShot(reloadSound);
|
|
}
|
|
|
|
if (ammoText != null) ammoText.text = "Перезарядка...";
|
|
|
|
yield return new WaitForSeconds(reloadTime);
|
|
|
|
currentAmmo = maxAmmo;
|
|
UpdateAmmoText();
|
|
isReloading = false;
|
|
}
|
|
|
|
void UpdateAmmoText()
|
|
{
|
|
if (ammoText != null)
|
|
{
|
|
ammoText.text = "Патроны: " + currentAmmo + " / " + maxAmmo;
|
|
}
|
|
}
|
|
}
|