77 lines
2.7 KiB
C#
77 lines
2.7 KiB
C#
using UnityEngine;
|
||
using UnityEngine.InputSystem;
|
||
|
||
namespace _Project.Scripts.PlayerUtils
|
||
{
|
||
public class PlayerCombat : MonoBehaviour
|
||
{
|
||
[Header("Оружие и Стрельба (Hitscan)")]
|
||
[SerializeField] private float damage = 25f;
|
||
[SerializeField] private float fireRate = 0.12f;
|
||
[SerializeField] private float weaponRange = 100f;
|
||
[SerializeField] private LayerMask hitLayers = ~0;
|
||
[SerializeField] private bool isAutomatic = true;
|
||
[SerializeField] private float recoilKick = 1.2f;
|
||
|
||
[Header("Эффекты (без звука)")]
|
||
[SerializeField] private ParticleSystem muzzleFlash;
|
||
[SerializeField] private GameObject impactPrefab;
|
||
|
||
[Header("Ссылки")]
|
||
[SerializeField] private Transform cameraPosition;
|
||
|
||
private PlayerControls controls;
|
||
private float shootTimer = 0f;
|
||
private bool isShootingInput = false;
|
||
|
||
private void Start()
|
||
{
|
||
controls = Player.Instance.Controls;
|
||
|
||
controls.Player.Attack.started += _ => isShootingInput = true;
|
||
controls.Player.Attack.canceled += _ => isShootingInput = false;
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
if (shootTimer > 0f) shootTimer -= Time.deltaTime;
|
||
|
||
bool shootPressed = isShootingInput || (Mouse.current != null && (isAutomatic ? Mouse.current.leftButton.isPressed : Mouse.current.leftButton.wasPressedThisFrame));
|
||
|
||
if (shootPressed && shootTimer <= 0f)
|
||
{
|
||
Shoot();
|
||
}
|
||
}
|
||
|
||
private void Shoot()
|
||
{
|
||
shootTimer = fireRate;
|
||
|
||
// ВЫЗОВ ЗВУКА ИЗ НОВОГО МОДУЛЯ
|
||
Player.Instance.Sound.PlayShoot();
|
||
|
||
if (muzzleFlash != null) muzzleFlash.Play();
|
||
Player.Instance.CameraController.ApplyRecoil(recoilKick);
|
||
|
||
Ray ray = new Ray(cameraPosition.position, cameraPosition.forward);
|
||
if (Physics.Raycast(ray, out RaycastHit hit, weaponRange, hitLayers, QueryTriggerInteraction.Ignore))
|
||
{
|
||
if (hit.collider.TryGetComponent<IDamageable>(out var damageable))
|
||
{
|
||
damageable.TakeDamage(damage);
|
||
}
|
||
else if (hit.rigidbody != null)
|
||
{
|
||
hit.rigidbody.AddForceAtPosition(-hit.normal * (damage * 10f), hit.point, ForceMode.Impulse);
|
||
}
|
||
|
||
if (impactPrefab != null)
|
||
{
|
||
GameObject impact = Instantiate(impactPrefab, hit.point + (hit.normal * 0.001f), Quaternion.LookRotation(hit.normal));
|
||
Destroy(impact, 3f);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} |