Exemplo n.º 1
0
        public IEnumerator Test1()
        {
            LogAssert.ignoreFailingMessages = true;
            InputMessageModel inputMessageModel = new InputMessageModel()
            {
                X           = 1,
                Y           = 1,
                Angle       = float.NaN,
                TickNumber  = 0,
                UseAbility  = false,
                TickTimeSec = 0
            };
            float     deltaTimeSec = 1f;
            Transform goTransform  = playerEntity.view.gameObject.transform;

            for (int i = 0; i < 50; i++)
            {
                Vector3 startPosition = goTransform.position;
                playerPredictor.Predict(playerEntity.id.value, inputMessageModel, deltaTimeSec);
                Vector3 finalPosition = goTransform.position;
                float   delta         = (finalPosition - startPosition).magnitude;
                string  message       = $"startPosition = {startPosition.x} {startPosition.y} {startPosition.z} | " +
                                        $"finishPosition = {finalPosition.x} {finalPosition.y} {finalPosition.z} " +
                                        $"delta = {delta}";
                Debug.LogWarning(message);
                Assert.IsTrue(delta > 0.01f);
            }

            yield return(null);
        }
Exemplo n.º 2
0
 public void Validate(InputMessageModel model)
 {
     if (Math.Abs(model.TickTimeSec) < 0.001)
     {
         log.Error("Пустое время тика");
     }
 }
        public uint AddInput(InputMessageModel model)
        {
            inputModelValidator.Validate(model);

            uint inputId = inputMessageIdFactory.Create();

            dict.Add(inputId, model);
            return(inputId);
        }
Exemplo n.º 4
0
 /// <summary>
 /// Расставляет все объекты по снимку, применяет ввод к сущности игрока и вызывает тик.
 /// </summary>
 /// <returns></returns>
 public Snapshot Predict(Snapshot snapshot, ushort playerEntityId, InputMessageModel inputMessageModel,
                         float physicsSimulationDuration)
 {
     //откатить физическую сцену к состоянию
     physicsRollbackManager.Rollback(snapshot);
     Predict(playerEntityId, inputMessageModel, physicsSimulationDuration);
     log.Debug("Пересимуляция physicsSimulationDuration = " + physicsSimulationDuration);
     return(snapshotFactory.Create());
 }
 public void Execute()
 {
     try
     {
         ushort            playerEntityId    = PlayerIdStorage.PlayerEntityId;
         float             deltaTime         = Time.deltaTime;
         InputMessageModel inputMessageModel = clientInputMessagesHistory.GetLast();
         //тик
         playerPredictor.Predict(playerEntityId, inputMessageModel, deltaTime);
     }
     catch (Exception e)
     {
         log.Error(e.FullMessage());
     }
 }
Exemplo n.º 6
0
        public void Execute()
        {
            float attackAngle = float.NaN;
            bool  useAbility  = false;

            float x = movementJoystick.Horizontal;
            float y = movementJoystick.Vertical;

            float tolerance = 0.001f;

#if UNITY_EDITOR_WIN
            if (Mathf.Abs(x) < tolerance && Mathf.Abs(y) < tolerance)
            {
                x = Input.GetAxis("Horizontal");
                y = Input.GetAxis("Vertical");
            }
#endif

            if (Math.Abs(attackJoystick.Horizontal) > tolerance && Math.Abs(attackJoystick.Vertical) > tolerance)
            {
                attackAngle = Mathf.Atan2(attackJoystick.Horizontal, attackJoystick.Vertical) * Mathf.Rad2Deg;
                if (attackAngle < 0)
                {
                    attackAngle += 360;
                }
            }

            float matchTime  = matchTimeStorage.GetMatchTime();
            int?  tickNumber = snapshotManager.GetCurrentTickNumber(matchTime);
            if (tickNumber == null)
            {
                throw new Exception($"Этот вызов не должен произойти. matchTime = {matchTime} ");
            }


            InputMessageModel inputMessageModel = new InputMessageModel()
            {
                Angle       = attackAngle,
                X           = x,
                Y           = y,
                UseAbility  = useAbility,
                TickTimeSec = matchTime,
                TickNumber  = tickNumber.Value
            };

            uint lastInputId = clientInputMessagesHistory.AddInput(inputMessageModel);
            lastInputIdStorage.SetLastInputId(lastInputId);
        }
Exemplo n.º 7
0
        public void AddMessage(ushort playerTmpId, uint inputMessageId, InputMessageModel inputMessageModel)
        {
            //Если сообщение уже обработано, то оно игнорируется
            if (messagesMetaHistory.TryAddId(playerTmpId, inputMessageId))
            {
                AddMovement(playerTmpId, inputMessageModel.GetVector2(), inputMessageModel.TickNumber);
                if (!float.IsNaN(inputMessageModel.Angle))
                {
                    AddAttack(playerTmpId, inputMessageModel.Angle, inputMessageModel.TickNumber);
                }

                if (inputMessageModel.UseAbility)
                {
                    AddAbility(playerTmpId, inputMessageModel.TickNumber);
                }
            }
        }
Exemplo n.º 8
0
        public void Predict(ushort playerEntityId, InputMessageModel inputMessageModel, float physicsSimulationDuration)
        {
            //взять ввод игрока
            if (inputMessageModel == null)
            {
                log.Debug("Нет ввода");
                return;
            }

            if (physicsSimulationDuration < 0.005f)
            {
                log.Debug("Что за космический fps?");
            }

            // log.Debug("Тик физики "+physicsSimulationDuration);
            //линейное движение игрока
            ServerGameEntity playerEntity     = gameContext.GetEntityWithId(playerEntityId);
            Rigidbody        warshipRigidbody = playerEntity.rigidbody.value;
            Vector3          inputVector      = inputMessageModel.GetVector3();
            float            maxSpeed         = 10f;

            warshipRigidbody.velocity = Vector3.zero;

            if (inputVector.sqrMagnitude > 0.001f)
            {
                // log.Debug("Линейное движение игрока");
                physicsVelocityManager.ApplyVelocity(warshipRigidbody, inputVector, maxSpeed);
            }

            //вращательное движение игрока
            if (!float.IsNaN(inputMessageModel.Angle))
            {
                float angularVelocity = 90;
                physicsRotationManager.ApplyRotation(playerEntity.rigidbody.value, inputMessageModel.Angle,
                                                     angularVelocity, physicsSimulationDuration);
            }

            //todo спавн пуль игрока
            //todo движение пуль игрока

            //симуляция физики
            scene.GetPhysicsScene().Simulate(physicsSimulationDuration);
        }
Exemplo n.º 9
0
        public InputMessageModel GetAverage(List <InputMessageModel> inputMessageModels)
        {
            InputMessageModel result = new InputMessageModel();

            foreach (var model in inputMessageModels)
            {
                result.X          += model.X;
                result.Y          += model.Y;
                result.UseAbility |= model.UseAbility;
            }

            result.X           = result.X / inputMessageModels.Count;
            result.Y           = result.Y / inputMessageModels.Count;
            result.TickNumber  = inputMessageModels.First().TickNumber;
            result.TickTimeSec = inputMessageModels.First().TickTimeSec;
            //todo угол считается не точно
            result.Angle = inputMessageModels.Last().Angle;
            return(result);
        }
Exemplo n.º 10
0
        public List <AverageInputMessageModel> GetAverageInputs(List <KeyValuePair <uint, InputMessageModel> > inputs)
        {
            List <AverageInputMessageModel> result = new List <AverageInputMessageModel>();

            //todo достать из истории тиков сервера
            int clientToServerFrequencyCoefficient = 6;
            var groups = inputs.Split(clientToServerFrequencyCoefficient);
            InputMessageModelUtil inputMessageModelUtil = new InputMessageModelUtil();

            foreach (var group in groups)
            {
                InputMessageModel averageInputModel = inputMessageModelUtil
                                                      .GetAverage(group.Select(pair => pair.Value).ToList());
                KeyValuePair <uint, InputMessageModel> firstInGroup = group.First();
                result.Add(new AverageInputMessageModel()
                {
                    inputMessageModel = averageInputModel,
                    replacedInputsIds = group.Select(item => item.Key).ToList(),
                    inputId           = group.First().Key
                });
            }

            return(result);
        }