Files
Project-M/Assets/_Project/Scripts/Simulation/Combat/Projectile.cs
T
2026-05-31 21:35:12 -07:00

40 lines
1.8 KiB
C#

using Unity.Entities;
using Unity.Mathematics;
using Unity.NetCode;
namespace ProjectM.Simulation
{
/// <summary>
/// Ghost component on the projectile prefab. Drives predicted+server movement and carries the
/// classification key used to reconcile a client's predicted-spawned projectile with the server's
/// authoritative ghost. <see cref="Direction"/> is replicated so the server's auto-targeted aim
/// reconciles the client's raw-aim prediction; <see cref="SpawnId"/> is replicated so it lives in
/// snapshot history for the predicted-spawn classifier. Speed/Damage/Range are baked on the prefab
/// (identical both worlds → deterministic) and not replicated; DistanceTravelled is integrated
/// locally each tick and not replicated.
/// </summary>
public struct Projectile : IComponentData
{
/// <summary>Planar XZ travel direction (world XZ mapped to float2 x,y), normalized.</summary>
[GhostField(Quantization = 1000)] public float2 Direction;
/// <summary>
/// Classification key: (ownerNetId << 16) | absoluteFireCount. Replicated so it is present
/// in snapshot history; the client classifier matches this against its predicted spawn.
/// </summary>
[GhostField] public uint SpawnId;
/// <summary>Travel speed in units/second. Baked on the prefab; not replicated.</summary>
public float Speed;
/// <summary>Damage applied on hit. Baked on the prefab; not replicated.</summary>
public float Damage;
/// <summary>Max travel distance before the server expires the projectile. Baked on the prefab; not replicated.</summary>
public float Range;
/// <summary>Integrated distance travelled (predicted on client + authoritative on server). Not replicated.</summary>
public float DistanceTravelled;
}
}