Network Data Buffer
NetworkDataBuffer
is the cornerstone of the Projectiles Advanced sample. It manages the projectile data buffer and handles the creation, update, and deletion of the visual representations of projectiles. The sample includes two buffer versions (child classes) based on the type of projectiles it can handle: HitscanProjectileBuffer
and KinematicProjectileBuffer
. Projectile buffer components are on the controlling game object (e.g., Agent
, Turret
) and are responsible for updating projectiles for all weapons owned by that object.
💡Note: Difference between hitscan and kinematic projectiles is explained in the Projectiles Types section.
Projectile buffers require projectile prefabs array to correctly pair projectile data to specific prefab. For simplicity projectile buffers have references to prefabs directly in the inspector.
💡Note: Better solution of accessing prefabs array will be game specific but it could be for example a scriptable object with settings data.
Projectile buffers store networked projectile data that are used to calculate trajectories and other behaviors associated with projectiles. Each data instance represents a single projectile fired by the owner (player, turret).
C#
public struct HitscanData : INetworkStruct
{
public byte PrefabIndex;
public byte BarrelIndex;
public Vector3Compressed FirePosition;
public Vector3Compressed FireDirection;
public Vector3Compressed ImpactPosition;
public Vector3Compressed ImpactNormal;
}
C#
[StructLayout(LayoutKind.Explicit)]
public struct KinematicData : INetworkStruct
{
public bool IsFinished { get { return _state.IsBitSet(0); } set { _state.SetBit(0, value); } }
public bool HasStopped { get { return _state.IsBitSet(1); } set { _state.SetBit(1, value); } }
[FieldOffset(0)]
private byte _state;
[FieldOffset(1)]
public byte PrefabIndex;
[FieldOffset(2)]
public byte BarrelIndex;
[FieldOffset(3)]
public int FireTick;
[FieldOffset(7)]
public Vector3Compressed Position;
[FieldOffset(19)]
public Vector3Compressed Velocity;
[FieldOffset(31)]
public Vector3Compressed ImpactPosition;
[FieldOffset(43)]
public Vector3Compressed ImpactNormal;
// Custom projectile data
[FieldOffset(55)]
public AdvancedData Advanced;
[FieldOffset(55)]
public SprayData Spray;
[FieldOffset(55)]
public HomingData Homing;
public struct AdvancedData : INetworkStruct
{
public int MoveStartTick;
public byte BounceCount;
}
public struct SprayData : INetworkStruct
{
public Vector3 InheritedVelocity;
}
public struct HomingData : INetworkStruct
{
public NetworkId Target;
public Vector3Compressed TargetPosition; // Used for position prediction
}
}
Hitscan projectiles require less networked data and are therefore more efficient. The KinematicData
struct, used for kinematic projectiles in this sample, is currently quite large due to the variety of projectile features demonstrated in this project. As multiple different projectile behaviors are showcased, each not using the same data values, the KinematicData
struct utilizes a union of specific projectile data (notice how AdvancedData
, SprayData
and HomingData
overlap).
In actual practice, it is recommended to keep the projectile data structure as minimalistic as possible.
Back to top