pgiz3/Assets/Scripts/PlayerShooting.cs
2026-03-22 03:00:25 +03:00

162 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using UnityEngine;
using TMPro;
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 TextMeshProUGUI 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 OnEnable()
{
isReloading = false;
UpdateAmmoText();
}
void Awake()
{
shootableMask = LayerMask.GetMask("Shootable");
gunParticles = GetComponent<ParticleSystem>();
gunLine = GetComponent<LineRenderer>();
gunAudio = GetComponent<AudioSource>();
gunLight = GetComponent<Light>();
}
void Start()
{
currentAmmo = maxAmmo;
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 target = shootHit.collider.GetComponentInParent<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;
}
}
}