示例#1
0
    private void ProcessServerState()
    {
        ServerWorldState[] copyServerState = new ServerWorldState[serverStateBuffer.Count];
        serverStateBuffer.CopyTo(copyServerState);
        serverStateBuffer.Clear();
        foreach (ServerWorldState serverState in copyServerState)
        {
            if (GameManager.players.TryGetValue(serverState.clientId, out PlayerManager player))
            {
                CharacterController characterController = player.GetComponent <CharacterController>();
                if (player.id == Client.instance.myId)
                {
                    ClientPlayerState clientStateAtTick = stateBuffer.Find(state => state.tick == serverState.tick);
                    if (clientStateAtTick != null && AreEqualPositionsWithMargin(serverState.position, clientStateAtTick.position))
                    {
                        Debug.Log($"Positions are equal at tick {serverState.tick} - {serverState.position}");
                        continue; // Skip when they're the same
                    }
                    else if (clientStateAtTick != null)
                    {
                        Debug.Log($"Positions at tick {serverState.tick} diverged with server at {serverState.position} and client at {clientStateAtTick.position}");
                    }
                    // Set server position to player
                    ApplyMovementDelta(GetDeltaPosition(serverState.position, player.transform));
                    transform.rotation = serverState.rotation;

                    if (!controller.isGrounded)
                    {
                        // Then take over the yVelocity based on the server
                        yVelocity = serverState.serverYVelocity;
                    }

                    // Remove all states from the buffer these have now been made obsolete by the server
                    stateBuffer.RemoveAll(state => state.tick <= serverState.tick); // fixme clean remove?
                    //PrintBuffer(serverState);
                    for (int i = 0; i < stateBuffer.Count; i++)
                    {
                        // Apply buffered states that haven't been ack
                        ClientPlayerState bufferedState = stateBuffer[i];

                        // Predict based on the new ack state
                        Vector3 predictedDeltaPos = GetMovementVector(bufferedState.inputs);
                        yVelocity = bufferedState.yVelocity;
                        ApplyMovementDelta(predictedDeltaPos);
                    }
                }
                else // This is always a new position packet (because it's form a different player), therefore apply it
                {
                    player.SetPosition(serverState.position);
                }
            }
        }
    }
示例#2
0
        private async Task ListenGameState(Channel channel)
        {
            var mapState    = new ClientMapData();
            var playerState = new ClientPlayerState();
            await mSyncContext.Execute(() => PlayerConnected?.Invoke(playerState), channel.ShutdownToken);

            try
            {
                while (true)
                {
                    try
                    {
                        mGameService = new GameService.GameServiceClient(channel);
                        using (var call = mGameService.ConnectAndListenState(new Empty()))
                            using (var stateStream = call.ResponseStream)
                            {
                                while (await stateStream.MoveNext(channel.ShutdownToken))
                                {
                                    channel.ShutdownToken.ThrowIfCancellationRequested();
                                    var state = stateStream.Current;

                                    if (state.Map != null)
                                    {
                                        mapState.State = new MapState(state.Map);
                                    }

                                    if (state.Player != null)
                                    {
                                        playerState.PlayerState = new PlayerState(state.Player);
                                    }

                                    channel.ShutdownToken.ThrowIfCancellationRequested();

                                    if (!mMapLoaded)
                                    {
                                        mMapLoaded = true;
                                        await mSyncContext.Execute(() =>
                                        {
                                            MapLoaded?.Invoke(mapState);
                                            BaseCreated?.Invoke(state.BasePos.ToUnity());
                                        }, channel.ShutdownToken);

                                        var tChat = ListenChat(mGameService, channel);

                                        var t0 = mWorkerCreationStateListener.ListenCreations(mChannel);
                                        var t1 = mBuildingTemplateCreationStateListener.ListenCreations(mChannel);
                                        var t2 = mCentralBuildingCreationStateListener.ListenCreations(mChannel);
                                        var t3 = mMiningCampCreationListener.ListenCreations(mChannel);
                                        var t4 = mBarrakCreationListener.ListenCreations(mChannel);
                                        var t5 = mRangedWarriorCreationStateListener.ListenCreations(mChannel);
                                        var t6 = mMeeleeWarriorCreationStateListener.ListenCreations(mChannel);
                                    }
                                }
                            }

                        break;
                    }
                    catch (RpcException e)
                    {
                        if (e.Status.StatusCode != StatusCode.Unavailable)
                        {
                            throw;
                        }

                        await Task.Delay(TimeSpan.FromSeconds(0.5));
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                DisconnectedFromServer?.Invoke();
                throw;
            }
        }