Files
OTG_8/Assets/_Scripts/Weapons/WeaponController.cs
T
2026-06-04 23:22:13 +03:00

91 lines
3.0 KiB
C#

using OTGIntegrated.Combat;
using OTGIntegrated.Stats;
using UnityEngine;
namespace OTGIntegrated.Weapons
{
public sealed class WeaponController : MonoBehaviour
{
public Transform attackOrigin;
public LayerMask hitMask = ~0;
[SerializeField] private float meleeRadius = 0.7f;
private readonly Collider[] hits = new Collider[16];
public bool Attack(WeaponData weapon, PlayerStats stats)
{
if (weapon == null || stats == null)
{
return false;
}
Transform origin = attackOrigin != null ? attackOrigin : transform;
Vector3 start = origin.position + Vector3.up * 0.8f;
Vector3 forward = origin.forward;
forward.y = 0f;
forward = forward.sqrMagnitude > 0.001f ? forward.normalized : transform.forward;
float finalDamage = weapon.damage + stats.Damage;
bool critical = Random.value < stats.CriticalChance;
if (critical)
{
finalDamage *= 1.75f;
}
if (weapon.isRanged)
{
if (Physics.Raycast(start, forward, out RaycastHit hit, weapon.range, hitMask, QueryTriggerInteraction.Ignore))
{
return ApplyDamage(hit.collider, finalDamage, critical);
}
return false;
}
Vector3 center = start + forward * Mathf.Max(0.6f, weapon.range * 0.55f);
int count = Physics.OverlapSphereNonAlloc(center, meleeRadius + weapon.range * 0.12f, hits, hitMask, QueryTriggerInteraction.Ignore);
bool damaged = false;
for (int i = 0; i < count; i++)
{
Collider hit = hits[i];
if (hit == null || hit.transform == transform || hit.GetComponentInParent<PlayerStats>() != null)
{
continue;
}
if (ApplyDamage(hit, finalDamage, critical))
{
damaged = true;
break;
}
}
return damaged;
}
private bool ApplyDamage(Collider collider, float amount, bool critical)
{
Damageable damageable = collider.GetComponentInParent<Damageable>();
if (damageable == null || !damageable.IsAlive)
{
return false;
}
damageable.TakeDamage(amount, gameObject);
if (critical)
{
OTGIntegrated.Core.GameEvents.RaiseNotification("Критический удар");
}
return true;
}
private void OnDrawGizmosSelected()
{
Gizmos.color = new Color(1f, 0.45f, 0.1f, 0.25f);
Transform origin = attackOrigin != null ? attackOrigin : transform;
Gizmos.DrawWireSphere(origin.position + origin.forward * 1.3f + Vector3.up * 0.8f, meleeRadius);
}
}
}