Aetheria/Assets/Scripts/Gameplay/Weapons/Projectile.cs

123 lines
3.8 KiB
C#
Raw Normal View History

2021-01-05 02:56:17 +00:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
2021-01-05 02:56:17 +00:00
public class Projectile : MonoBehaviour
{
public TrailRenderer Trail;
public float Gravity;
public float Drag = .1f;
2021-01-08 12:44:10 +00:00
public Prototype HitEffect;
2021-01-05 02:56:17 +00:00
public float AirburstDistance;
public float AirburstRange;
public float DirectHitIntensityMultiplier = 1;
2021-01-05 02:56:17 +00:00
private bool _alive;
public Vector3 StartPosition { get; set; }
2021-01-05 02:56:17 +00:00
public Vector3 Velocity { get; set; }
public float ImpactIntensity { get; set; } = 1;
2021-01-05 02:56:17 +00:00
public Entity SourceEntity { get; set; }
2026-06-21 09:37:54 +01:00
public EntityInstance TargetInstance { get; set; }
public float Range { get; set; }
2026-06-21 09:37:54 +01:00
public float YmirWorldTime { get; private set; }
2021-01-05 02:56:17 +00:00
// Start is called before the first frame update
void Start()
{
}
private void OnEnable()
{
_alive = true;
}
// Update is called once per frame
void Update()
{
if (SourceEntity == null) return;
if(_alive)
2021-01-05 02:56:17 +00:00
{
var t = transform;
var position = t.position;
2021-02-06 15:29:04 +00:00
Velocity -= Vector3.up * (Gravity * Time.deltaTime);
2026-06-21 09:37:54 +01:00
Velocity *= Mathf.Max(0, 1 - Drag * Time.deltaTime);
var forward = Velocity.normalized;
t.forward = forward;
2026-06-21 09:37:54 +01:00
if (!AetheriaYmirPhysicsBridge.Instance.TryStepProjectile(this, Time.deltaTime, out var ymirStep))
2021-01-05 02:56:17 +00:00
{
2026-06-21 09:37:54 +01:00
Debug.LogWarning("Ymir projectile step unavailable; projectile killed instead of falling back to Unity physics.");
StartCoroutine(Kill());
return;
}
YmirWorldTime += Time.deltaTime;
Velocity = ymirStep.Velocity;
t.position = ymirStep.Position;
if (ymirStep.HasHit)
{
ApplyYmirHit(ymirStep, forward);
return;
2021-01-05 02:56:17 +00:00
}
2026-06-21 09:37:54 +01:00
var distanceTraveled = (transform.position - StartPosition).magnitude;
if(distanceTraveled > Range)
StartCoroutine(Kill());
if (AirburstRange > 1 && distanceTraveled > AirburstDistance)
{
StartCoroutine(Kill());
2026-06-21 09:37:54 +01:00
if (HitEffect != null)
{
2026-06-21 09:37:54 +01:00
var ht = HitEffect.Instantiate<Transform>();
ht.position = t.position;
}
if (AetheriaYmirPhysicsBridge.Instance.TryOverlapTargetHulls(TargetInstance, t.position, AirburstRange, out var hits))
{
foreach (var hit in hits)
{
2026-06-21 09:37:54 +01:00
var direction = (hit.Hull.transform.position - t.position).normalized;
}
}
}
}
2021-01-05 02:56:17 +00:00
}
2026-06-21 09:37:54 +01:00
private void ApplyYmirHit(AetheriaYmirProjectileStep step, Vector3 forward)
{
var hull = step.Hit.Hull;
if (hull == null || hull.Entity == SourceEntity)
return;
2026-07-08 22:24:32 +01:00
var shieldManager = hull.GetComponentInParent<EntityInstance>()?.Shield;
if (shieldManager != null &&
hull.Entity.Shield != null &&
2026-06-21 09:37:54 +01:00
hull.Entity.Shield.Item.Active.Value)
2026-07-08 22:24:32 +01:00
shieldManager.ShowHit(step.Hit.Point, Mathf.Max(0.01f, ImpactIntensity * DirectHitIntensityMultiplier));
2026-06-21 09:37:54 +01:00
transform.position = step.Hit.Point;
if (HitEffect != null)
{
var ht = HitEffect.Instantiate<Transform>();
ht.SetParent(hull.transform);
ht.position = step.Hit.Point;
}
StartCoroutine(Kill());
}
2021-01-05 02:56:17 +00:00
IEnumerator Kill()
{
_alive = false;
var startTime = Time.time;
var lifetime = Trail.time;
while (Time.time - startTime < lifetime)
yield return null;
GetComponent<Prototype>().ReturnToPool();
}
}