using System; using AOT; using Unity.Assertions; using Unity.Burst; using Unity.Collections.LowLevel.Unsafe; using Unity.Mathematics; using Unity.NetCode; using Unity.Transforms; namespace Unity.MegaCity.Gameplay { /// /// The MegaCity-tuned prediction error function for the component. /// [BurstCompile] public unsafe struct MegaCitySmoothingAction { /// /// The default value for the if the no user data is passed to the function. /// Position is corrected if the prediction error is at least 1 unit (usually mt) and less than 10 unit (usually mt) /// public sealed class DefaultStaticUserParams { internal static readonly SharedStatic maxDist = SharedStatic.GetOrCreate(); internal static readonly SharedStatic delta = SharedStatic.GetOrCreate(); static DefaultStaticUserParams() { maxDist.Data = 20; delta.Data = 0.5f; } class MaxDistKey {} class DeltaKey {} } /// /// Return a the burst compatible function pointer that can be used to register the smoothing action to the /// singleton. /// public static readonly PortableFunctionPointer Action = new(SmoothingAction); [BurstCompile(DisableDirectCall = true)] [MonoPInvokeCallback(typeof(GhostPredictionSmoothing.SmoothingActionDelegate))] private static void SmoothingAction(IntPtr currentData, IntPtr previousData, IntPtr usrData) { ref var trans = ref UnsafeUtility.AsRef((void*)currentData); ref var backup = ref UnsafeUtility.AsRef((void*)previousData); float maxDist = DefaultStaticUserParams.maxDist.Data; float delta = DefaultStaticUserParams.delta.Data; Assert.IsTrue(usrData.ToPointer() == null); var dist = math.distance(trans.Position, backup.Position); if (dist < maxDist && dist > delta && dist > 0) { trans.Position = backup.Position + (trans.Position - backup.Position) * delta / dist; } } } }