Files
riversong-code-showcase/Source/Riversong/Game/Vfx/ProjectileManagerSystem.cs
2026-05-21 16:04:49 +02:00

61 lines
1.9 KiB
C#

using Cysharp.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.AddressableAssets;
namespace DanieleMarotta.RiversongCodeShowcase
{
[Service(typeof(IProjectileManager))]
public class ProjectileManagerSystem : GameSystem, IProjectileManager
{
private const float ProjectileSpeed = 4;
[InjectService]
private IIntentLogicExecutor _intentLogicExecutor;
public ProjectileManagerSystem(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
public float ComputeProjectileTravelTime(Agent source, Agent target)
{
return math.distance(source.Position, target.Position) / ProjectileSpeed;
}
public void FireProjectile(Agent source, Agent target)
{
_ = FireProjectileAsync(source, target, ComputeProjectileTravelTime(source, target));
}
private async UniTask FireProjectileAsync(Agent source, Agent target, float travelTime)
{
var prefabRef = source.Definition.Projectile;
var projectile = await prefabRef.InstantiateAsync();
var p0 = (Vector3)source.Position;
var p1 = (Vector3)target.Position;
// const float peakHeightPerMeter = 0.1f;
// var peak = Vector3.Distance(p0, p1) * peakHeightPerMeter;
var t = 0f;
while (t < 1)
{
t = Mathf.Clamp01(t + Time.deltaTime / travelTime);
var position = Vector3.Lerp(p0, p1, t);
//position.y += 4 * peak * t * (1 - t);
var rotation = Quaternion.LookRotation((position - projectile.transform.position).normalized);
projectile.transform.SetPositionAndRotation(position, rotation);
await UniTask.NextFrame();
}
Addressables.ReleaseInstance(projectile);
_intentLogicExecutor.CancelRemainingIntents(target);
}
}
}