Characters

This commit is contained in:
2025-10-05 18:21:16 +02:00
parent b52b3aa830
commit 174a399ee7
77 changed files with 14406 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
using MegaKoop.Game.Combat;
using UnityEngine;
namespace MegaKoop.Game.WeaponSystem
{
public class Projectile : MonoBehaviour
{
[SerializeField] private float hitRadius = 0.05f;
[SerializeField] private LayerMask hitMask = Physics.DefaultRaycastLayers;
[SerializeField] private bool alignToVelocity = true;
private Vector3 direction;
private float speed;
private float damage;
private float lifetime;
private float timeAlive;
private Team sourceTeam;
private GameObject owner;
private Collider[] projectileColliders;
public void Initialize(Vector3 shotDirection, float projectileSpeed, float damageAmount, float projectileLifetime, GameObject projectileOwner, Team ownerTeam, Collider[] ownerColliders, LayerMask mask)
{
direction = shotDirection.sqrMagnitude > 0f ? shotDirection.normalized : transform.forward;
speed = Mathf.Max(0f, projectileSpeed);
damage = Mathf.Max(0f, damageAmount);
lifetime = Mathf.Max(0.01f, projectileLifetime);
owner = projectileOwner;
sourceTeam = ownerTeam;
hitMask = mask;
timeAlive = 0f;
projectileColliders ??= GetComponentsInChildren<Collider>();
if (ownerColliders != null && projectileColliders != null)
{
foreach (Collider ownerCollider in ownerColliders)
{
if (ownerCollider == null)
{
continue;
}
foreach (Collider projectileCollider in projectileColliders)
{
if (projectileCollider == null)
{
continue;
}
Physics.IgnoreCollision(projectileCollider, ownerCollider, true);
}
}
}
}
private void Update()
{
float deltaTime = Time.deltaTime;
Vector3 displacement = direction * speed * deltaTime;
float distance = displacement.magnitude;
if (distance > 0f)
{
if (Physics.SphereCast(transform.position, hitRadius, direction, out RaycastHit hitInfo, distance, hitMask, QueryTriggerInteraction.Ignore))
{
TryHandleHit(hitInfo.collider, hitInfo.point, hitInfo.normal);
return;
}
transform.position += displacement;
}
if (alignToVelocity && distance > 0f)
{
transform.forward = direction;
}
timeAlive += deltaTime;
if (timeAlive >= lifetime)
{
Destroy(gameObject);
}
}
private void OnTriggerEnter(Collider other)
{
TryHandleHit(other, transform.position, -direction);
}
private void TryHandleHit(Collider other, Vector3 hitPoint, Vector3 hitNormal)
{
if (other == null)
{
return;
}
if (owner != null)
{
if (other.transform.IsChildOf(owner.transform))
{
return;
}
}
IDamageable damageable = other.GetComponentInParent<IDamageable>();
if (damageable != null && damageable.IsAlive)
{
bool isFriendly = damageable.Team == sourceTeam && damageable.Team != Team.Neutral;
if (isFriendly)
{
return;
}
if (damage > 0f)
{
var payload = new DamagePayload(damage, hitPoint, hitNormal, owner, sourceTeam, other.gameObject);
damageable.ApplyDamage(payload);
}
}
Destroy(gameObject);
}
}
}