public void Render(ComponentizedEntity entity, IGameContext gameContext, IRenderContext renderContext) { if (!_enabled || _serverOnly) { return; } if (renderContext.IsCurrentRenderPass <IDebugRenderPass>()) { var debugRenderPass = renderContext.GetCurrentRenderPass <IDebugRenderPass>(); var entityTransformSync = _synchronisedData.Select(x => x.Value).FirstOrDefault(x => x.Name == "entity.transform"); if (entityTransformSync != null && debugRenderPass.EnabledLayers.OfType <ServerStateDebugLayer>().Any()) { var lastValueSerialized = entityTransformSync.LastValueFromServer as NetworkTransform; if (lastValueSerialized != null) { var timeMachine = entityTransformSync.TimeMachine; if (timeMachine != null) { var lastValueRelative = lastValueSerialized.DeserializeFromNetwork(); var lastValueAbsolute = DefaultFinalTransform.Create(entity.FinalTransform.ParentObject, new TransformContainer(lastValueRelative)); var clientLocalTickValueRelative = timeMachine.Get(_localTick) as ITransform; var clientLocalTickValueAbsolute = DefaultFinalTransform.Create(entity.FinalTransform.ParentObject, new TransformContainer(clientLocalTickValueRelative)); var clientRewindValueRelative = timeMachine.Get(_localTick - _networkEngine.ClientRenderDelayTicks) as ITransform; var clientRewindValueAbsolute = DefaultFinalTransform.Create(entity.FinalTransform.ParentObject, new TransformContainer(clientRewindValueRelative)); var lastValuePoint = Vector3.Transform(Vector3.Zero, lastValueAbsolute.AbsoluteMatrix); var lastValueUp = Vector3.Transform(Vector3.Up, lastValueAbsolute.AbsoluteMatrix); var lastValueForward = Vector3.Transform(Vector3.Forward, lastValueAbsolute.AbsoluteMatrix); var lastValueLeft = Vector3.Transform(Vector3.Left, lastValueAbsolute.AbsoluteMatrix); var clientLocalTickPoint = Vector3.Transform(Vector3.Zero, clientLocalTickValueAbsolute.AbsoluteMatrix); var clientLocalTickUp = Vector3.Transform(Vector3.Up, clientLocalTickValueAbsolute.AbsoluteMatrix); var clientLocalTickForward = Vector3.Transform(Vector3.Forward, clientLocalTickValueAbsolute.AbsoluteMatrix); var clientLocalTickLeft = Vector3.Transform(Vector3.Left, clientLocalTickValueAbsolute.AbsoluteMatrix); var clientRewindValueTickPoint = Vector3.Transform(Vector3.Zero, clientRewindValueAbsolute.AbsoluteMatrix); var clientRewindValueTickUp = Vector3.Transform(Vector3.Up, clientRewindValueAbsolute.AbsoluteMatrix); var clientRewindValueTickForward = Vector3.Transform(Vector3.Forward, clientRewindValueAbsolute.AbsoluteMatrix); var clientRewindValueTickLeft = Vector3.Transform(Vector3.Left, clientRewindValueAbsolute.AbsoluteMatrix); if (entity.GetType().Name == "CubeEntity") { Console.WriteLine(lastValueSerialized); } // Render the previous and next server states. _debugRenderer.RenderDebugLine(renderContext, lastValuePoint, lastValueUp, Color.Red, Color.Red); _debugRenderer.RenderDebugLine(renderContext, lastValuePoint, lastValueForward, Color.Red, Color.Red); _debugRenderer.RenderDebugLine(renderContext, lastValuePoint, lastValueLeft, Color.Red, Color.Red); _debugRenderer.RenderDebugLine(renderContext, clientLocalTickPoint, clientLocalTickUp, Color.Orange, Color.Orange); _debugRenderer.RenderDebugLine(renderContext, clientLocalTickPoint, clientLocalTickForward, Color.Orange, Color.Orange); _debugRenderer.RenderDebugLine(renderContext, clientLocalTickPoint, clientLocalTickLeft, Color.Orange, Color.Orange); _debugRenderer.RenderDebugLine(renderContext, clientRewindValueTickPoint, clientRewindValueTickUp, Color.Yellow, Color.Yellow); _debugRenderer.RenderDebugLine(renderContext, clientRewindValueTickPoint, clientRewindValueTickForward, Color.Yellow, Color.Yellow); _debugRenderer.RenderDebugLine(renderContext, clientRewindValueTickPoint, clientRewindValueTickLeft, Color.Yellow, Color.Yellow); } } } } }
public void Update(ComponentizedEntity entity, IServerContext serverContext, IUpdateContext updateContext) { if (!_enabled) { return; } _localTick++; _isRunningOnClient = false; if (_uniqueIdentifierForEntity == null) { _uniqueIdentifierForEntity = _uniqueIdentifierAllocator.Allocate(); _networkEngine.RegisterObjectAsNetworkId(_uniqueIdentifierForEntity.Value, entity); } if (_serverOnly) { return; } // Sync the entity to the client if it hasn't been already. foreach (var dispatcher in _networkEngine.CurrentDispatchers) { foreach (var group in dispatcher.ValidClientGroups) { if (ClientAuthoritiveMode != ClientAuthoritiveMode.None && ClientOwnership != null && OnlySendToAuthoritiveClient) { if (ClientOwnership != group) { // This client doesn't own the entity, and this entity is only // synchronised with clients that own it. _consoleHandle.LogDebug("Entity is owned by " + ClientOwnership + ", and target client is " + group + " who doesn't own it, so I'm not syncing it."); continue; } } if (!_clientsEntityIsKnownOn.Contains(group)) { _consoleHandle.LogDebug("Entity is not known to " + group + ", sending creation message."); // Send an entity creation message to the client. var createMessage = new EntityCreateMessage { EntityID = _uniqueIdentifierForEntity.Value, EntityType = entity.GetType().AssemblyQualifiedName, InitialTransform = entity.Transform.SerializeToNetwork(), FrameTick = _localTick, MessageOrder = _messageOrder++, }; _networkEngine.Send( dispatcher, group, createMessage, true); _clientsEntityIsKnownOn.Add(group); } } } PrepareAndTransmitSynchronisation(entity, _localTick, false, ClientAuthoritiveMode); }