public override void OnSimulateBefore(NetworkObj obj) { if (Interpolation.Enabled) { var root = (NetworkState)obj.Root; if (root.Entity.IsOwner) { return; } if (root.Entity.HasControl && !ToController) { return; } var it = root.Frames.GetIterator(); var idx = obj[this]; var value = NetMath.InterpolateFloat(obj.RootState.Frames, idx + 1, obj.RootState.Entity.Frame, Settings.IsAngle); while (it.Next()) { it.val.Values[idx].Float0 = value; } } }
public bool QueueInput(Command cmd) { if (canQueueCommands) { NetAssert.True(HasControl); if (CommandQueue.Count < Core.Config.commandQueueSize) { cmd.ServerFrame = Core.ServerFrame; cmd.Sequence = CommandSequence = NetMath.SeqNext(CommandSequence, Command.SEQ_MASK); } else { NetLog.Error("Input queue for {0} is full", this); return(false); } CommandQueue.AddLast(cmd); return(true); } else { NetLog.Error("You can only queue commands to the host in the 'SimulateController' callback"); return(false); } }
private void ReadInput(Packet packet) { int maxFrame = Core.Frame; int minFrame = maxFrame - (Core.Config.commandDelayAllowed + PingFrames); while (packet.ReadStopMarker()) { NetworkId netId = packet.ReadNetworkId(); EntityProxy proxy = null; if (OutgoingProxiesByNetworkId.ContainsKey(netId)) { proxy = OutgoingProxiesByNetworkId[netId]; } while (packet.ReadStopMarker()) { Command cmd = Factory.NewCommand(packet.ReadTypeId()); cmd.Sequence = packet.ReadUShort(Command.SEQ_BITS); cmd.ServerFrame = packet.ReadIntVB(); cmd.InputObject.Token = packet.ReadToken(); cmd.ReadInput(connection, packet); // no proxy or entity if (!proxy || !proxy.Entity) { continue; } Entity entity = proxy.Entity; // remote is not controller if (ReferenceEquals(entity.Controller, connection) == false) { continue; } // sequence is old if (NetMath.SeqDistance(cmd.Sequence, entity.CommandSequence, Command.SEQ_SHIFT) <= 0) { continue; } // put on command queue entity.CommandQueue.AddLast(cmd); entity.CommandSequence = cmd.Sequence; } } }
private void ReadResult(Packet packet) { while (packet.CanRead()) { if (packet.ReadBool() == false) { break; } NetworkId netId = packet.ReadNetworkId(); EntityProxy proxy = IncommingProxiesByNetworkId[netId]; Entity entity = proxy.Entity; while (packet.CanRead()) { if (packet.ReadBool() == false) { break; } TypeId typeId = packet.ReadTypeId(); ushort sequence = packet.ReadUShort(Command.SEQ_BITS); IMessageRider resultToken = packet.ReadToken(); Command cmd = null; if (entity != null) { var it = entity.CommandQueue.GetIterator(); while (it.Next()) { int dist = NetMath.SeqDistance(it.val.Sequence, sequence, Command.SEQ_SHIFT); if (dist > 0) { break; } if (dist < 0) { it.val.Flags |= CommandFlags.DISPOSE; } if (dist == 0) { cmd = it.val; break; } } } if (cmd) { cmd.ResultObject.Token = resultToken; cmd.Flags |= CommandFlags.CORRECTION_RECEIVED; if (cmd.Meta.SmoothFrames > 0) { cmd.BeginSmoothing(); } cmd.ReadResult(connection, packet); } else { cmd = Factory.NewCommand(typeId); cmd.ReadResult(connection, packet); cmd.Free(); } } // remove all disposable commands if (entity != null) { while ((entity.CommandQueue.Count > 1) && (entity.CommandQueue.First.Flags & CommandFlags.DISPOSE)) { entity.CommandQueue.RemoveFirst().Free(); } } } }
public override void OnSimulateBefore(NetworkObj obj) { var root = (NetworkState)obj.Root; if (root.Entity.IsOwner) { return; } if (root.Entity.HasControl && !ToController) { return; } var nt = obj.Storage.Values[obj[this]].Transform; if (nt != null && nt.Simulate) { var snapped = false; Vector3 pos = Vector3.zero; Quaternion rot = Quaternion.identity; if (Extrapolation.Enabled) { if (PositionEnabled) { pos = NetMath.ExtrapolateVector( /* currentPosition */ GetPosition(nt.Simulate), /* receivedPosition */ obj.Storage.Values[obj[this] + POSITION].Vector3, /* receivedVelocity */ obj.Storage.Values[obj[this] + VELOCITY].Vector3, /* receivedFrame */ obj.RootState.Frames.First.Frame, /* entityFrame */ obj.RootState.Entity.Frame, /* extrapolation */ Extrapolation, /* snapping */ ref snapped ); // clamp position pos = nt.Clamper(obj.RootState.Entity.UnityObject, pos); } if (RotationEnabled) { rot = NetMath.ExtrapolateQuaternion( /* currentRotation */ GetRotation(nt.Simulate), /* receivedRotation */ obj.Storage.Values[obj[this] + ROTATION].Quaternion, /* receivedFrame */ obj.RootState.Frames.First.Frame, /* entityFrame */ obj.RootState.Entity.Frame, /* extrapolation */ Extrapolation ); } } else if (Interpolation.Enabled) { // position if (PositionEnabled) { pos = NetMath.InterpolateVector( obj.RootState.Frames, obj[this] + POSITION, obj.RootState.Entity.Frame, Interpolation.SnapMagnitude, ref snapped ); } // rotation if (RotationEnabled) { rot = NetMath.InterpolateQuaternion( obj.RootState.Frames, obj[this] + ROTATION, obj.RootState.Entity.Frame ); } } else { // always snapped on this snapped = true; // position if (PositionEnabled) { pos = obj.Storage.Values[obj[this] + POSITION].Vector3; } // rotation if (RotationEnabled) { rot = obj.Storage.Values[obj[this] + ROTATION].Quaternion; } } if (PositionEnabled) { SetPosition(nt.Simulate, pos); if (snapped) { nt.RenderDoubleBufferPosition = nt.RenderDoubleBufferPosition.Shift(nt.Simulate.position).Shift(nt.Simulate.position); } } if (RotationEnabled) { SetRotation(nt.Simulate, rot); } } }
public byte[] DuplicateData() { byte[] duplicate = new byte[NetMath.BytesRequired(position)]; Array.Copy(data, 0, duplicate, 0, duplicate.Length); return(duplicate); }