80 lines
2.7 KiB
C#
80 lines
2.7 KiB
C#
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
namespace _Project.Scripts.PlayerUtils
|
|
{
|
|
public class PlayerCombat : MonoBehaviour
|
|
{
|
|
[Header("Оружие и Стрельба (Projectiles)")]
|
|
[SerializeField] private bool canShoot = true;
|
|
[SerializeField] private LayerMask hitLayers = ~0;
|
|
|
|
[Header("Эффекты (без звука)")]
|
|
[SerializeField] private ParticleSystem muzzleFlash;
|
|
[SerializeField] private GameObject impactPrefab;
|
|
|
|
[Header("Ссылки")]
|
|
[SerializeField] private Transform cameraPosition;
|
|
|
|
private PlayerControls controls;
|
|
private BodyProfile currentProfile;
|
|
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;
|
|
}
|
|
|
|
public void ApplyProfile(BodyProfile profile)
|
|
{
|
|
currentProfile = profile;
|
|
canShoot = profile.canShoot;
|
|
shootTimer = 0f;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (shootTimer > 0f) shootTimer -= Time.unscaledDeltaTime;
|
|
if (!canShoot || currentProfile == null) return;
|
|
|
|
bool isAuto = currentProfile.isAutomatic;
|
|
bool shootPressed = isShootingInput || (Mouse.current != null && (isAuto ? Mouse.current.leftButton.isPressed : Mouse.current.leftButton.wasPressedThisFrame));
|
|
|
|
if (shootPressed && shootTimer <= 0f)
|
|
{
|
|
Shoot();
|
|
if (!isAuto) isShootingInput = false;
|
|
}
|
|
}
|
|
|
|
private void Shoot()
|
|
{
|
|
shootTimer = currentProfile.fireRate;
|
|
|
|
Player.Instance.Sound.PlayShoot();
|
|
if (muzzleFlash != null) muzzleFlash.Play();
|
|
Player.Instance.CameraController.ApplyRecoil(currentProfile.recoilKick);
|
|
|
|
int pellets = Mathf.Max(1, currentProfile.pelletsPerShot);
|
|
float spread = currentProfile.spreadAngle;
|
|
Vector3 spawnPos = cameraPosition.position + cameraPosition.forward * 0.6f - cameraPosition.up * 0.1f;
|
|
|
|
for (int i = 0; i < pellets; i++)
|
|
{
|
|
Vector3 dir = cameraPosition.forward;
|
|
if (spread > 0.01f)
|
|
{
|
|
dir = Quaternion.Euler(
|
|
Random.Range(-spread, spread),
|
|
Random.Range(-spread, spread), 0f) * dir;
|
|
}
|
|
|
|
Projectile.Spawn(spawnPos, dir, currentProfile, true, gameObject, hitLayers, impactPrefab);
|
|
}
|
|
}
|
|
}
|
|
} |