Exemplo n.º 1
0
        private static float Heur(PathNode node1, PathNode node2, MovementProperties properties)
        {
            //  Эвристику переделать - это пройденное время + оставшееся
            float angle = Mathf.Abs(Vector3.Angle(node1.Direction, node2.Position - node1.Position)) / properties.rotationAngle;

            //return node1.Distance(node2) + Mathf.Abs(angle);
            return(node1.TimeMoment + 2 * node1.Distance(node2) / properties.maxSpeed + angle * properties.deltaTime);
        }
Exemplo n.º 2
0
    public void GroundCheck(MovementProperties moveProperty)
    {
        moveProperty.isGrounded = Physics2D.OverlapCircle(moveProperty.groundCheck.position, moveProperty.groundRadius, moveProperty.whatIsGround);
        if (moveProperty.isGrounded)               //Resets jumpcount when player touches back down.
        {
            moveProperty.jumpCount = 0;
        }
//		character.anim.SetBool ("Ground", moveProperty.isGrounded);
    }
Exemplo n.º 3
0
        /// <summary>
        /// Get the attached implementations on awake
        /// </summary>
        protected override void Awake()
        {
            base.Awake();

            m_MovementEffects.Init(this);
            m_CurrentMovementProperties = m_Walking;
            m_NewMovementProperties     = m_Walking;
            m_MovementEffects.AdjustTriggerThreshold(m_CurrentMovementProperties.strideLength);
            m_MainCamera = Camera.main;
        }
Exemplo n.º 4
0
        // Changes the current motor state and play events associated with state change
        void ChangeState(MovementProperties newState)
        {
            m_NewMovementProperties = newState;

            if (controllerAdapter.isGrounded)
            {
                m_CurrentMovementProperties = m_NewMovementProperties;
            }

            m_MovementEffects.AdjustTriggerThreshold(newState.strideLength);
        }
Exemplo n.º 5
0
        public MatchSimulationUnit(byte unitId, int xPosition, int yPosition, byte rotation, byte healthPercent, byte frame)
        {
            UnitId        = unitId;
            movementState = new MovementProperties {
                XPosition = xPosition,
                YPosition = yPosition,
                Rotation  = rotation,
                Frame     = frame
            };
            MovementState = new ReactiveProperty <MovementProperties>(movementState);

            HealthPercent = new ReactiveProperty <byte>(healthPercent);

            AbilityActivationSubject = new Subject <MatchSimulation.AbilityActivation>();

            LastConfirmedFrame = frame;
        }
Exemplo n.º 6
0
        public static List <PathNode> GetNeighbours(PathNode node, MovementProperties properties)
        {
            //  Вот тут хардкодить не надо, это должно быть в properties
            //  У нас есть текущая точка, и свойства движения (там скорость, всякое такое)
            //float step = 1f;
            float step = properties.deltaTime * properties.maxSpeed;

            List <PathNode> result = new List <PathNode>();

            NavMeshHit currentArea;

            try
            {
                if (!NavMesh.SamplePosition(node.Position, out currentArea, 2f, NavMesh.AllAreas))
                {
                    return(result);
                }
            }
            catch (Exception e)
            {
                Debug.Log("Shit happens : " + e.Message);
                return(null);
            }

            for (int mult = 0; mult <= 1; ++mult)
            {
                for (int angleStep = -properties.angleSteps; angleStep <= properties.angleSteps; ++angleStep)
                {
                    PathNode next = node.SpawnChildren(step * mult, angleStep * properties.rotationAngle, properties.deltaTime);
                    if (CheckWalkable(next.Position, currentArea.mask))
                    {
                        result.Add(next);
                        Debug.DrawLine(node.Position, next.Position, Color.white, 10f);
                    }
                }
            }
            //Debug.Log("Children spawned : " + result.Count.ToString());

            return(result);
        }
Exemplo n.º 7
0
 // Called on character landing
 void OnLanded()
 {
     m_CurrentMovementProperties = m_NewMovementProperties;
 }
Exemplo n.º 8
0
 /// <summary>
 /// Change state to the new state and adds to previous state stack
 /// </summary>
 /// <param name="newState">The new first person movement properties to be used</param>
 public void EnterNewState(MovementProperties newState)
 {
     ChangeState(newState);
 }
Exemplo n.º 9
0
        public PathNode GetGlobalRoute(PathNode target, PathNode position, MovementProperties movementProperties, bool onPlatform)
        {
            NavMeshHit targetArea;

            if (!NavMesh.SamplePosition(target.Position, out targetArea, 1f, NavMesh.AllAreas))
            {
                return(null);
            }

            Vector3 adjustedPosition = new Vector3(position.Position.x, targetArea.position.y, position.Position.z);

            if (target.Distance(adjustedPosition) < movementProperties.epsilon)
            {
                return(null);
            }

            NavMeshHit currentArea;

            if (!NavMesh.SamplePosition(adjustedPosition, out currentArea, 1f, NavMesh.AllAreas) &&
                !(globalPath.Count == 0) &&
                !(globalPath.First().Type == RegionType.Moving))
            {
                return(null);
            }

            if (NavMesh.SamplePosition(adjustedPosition, out _, 1f, NavMesh.AllAreas) &&
                currentArea.mask == targetArea.mask)
            {
                if (targetArea.position.x - currentArea.position.x < 1f &&
                    targetArea.position.z - currentArea.position.z < 1f)
                {
                    return(null);
                }

                globalPath      = new List <Region>();
                target.RegionId = currentArea.mask;
                return(target);
            }

            if (globalPath.Count == 0)
            {
                globalPath = GetPathWithDijkstra(
                    new Region {
                    Index = currentArea.mask, Type = RegionType.Stable
                },
                    new Region {
                    Index = targetArea.mask, Type = RegionType.Stable
                },
                    target.Position);

                Cartographer cartographer     = new Cartographer();
                int          areaMask         = currentArea.mask;
                Vector3      inregionPosition = adjustedPosition;

                for (int i = 0; i < globalPath.Count(); i++)
                {
                    var neighbours     = cartographer.GetNeighbours(areaMask, inregionPosition);
                    var modifiedRegion = neighbours.Find(x => x.Index == globalPath[i].Index);
                    globalPath[i]    = modifiedRegion;
                    inregionPosition = modifiedRegion.PathPoints[0];
                    areaMask         = modifiedRegion.Index;
                }
            }

            if (globalPath.Count != 0)
            {
                var nextRegion = globalPath.First();

                if (currentArea.mask == nextRegion.Index)
                {
                    globalPath.RemoveAt(0);

                    if (globalPath.Count == 0)
                    {
                        return(target);
                    }

                    nextRegion = globalPath.First();
                }

                if (nextRegion.Type == RegionType.Moving &&
                    globalPath.Count > 1 &&
                    globalPath[1].Index == currentArea.mask)
                {
                    globalPath.RemoveAt(0);
                    globalPath.RemoveAt(1);

                    if (globalPath.Count == 0)
                    {
                        return(target);
                    }

                    nextRegion = globalPath.First();
                }

                if (nextRegion.Type == RegionType.Stable)
                {
                    return(calcStableRegionPath(nextRegion, currentArea, adjustedPosition, movementProperties));
                }
                else if (nextRegion.Type == RegionType.Moving)
                {
                    var movingRegion = (MovingRegion)nextRegion;

                    foreach (var exit in movingRegion.ExitPoints)
                    {
                        //ищем точку прыжка на платформу в текущей области
                        NavMeshHit exitHit;
                        if (NavMesh.SamplePosition(exit.transform.position, out exitHit, 20, currentArea.mask))
                        {
                            if (exitHit.mask == currentArea.mask)
                            {
                                if (Math.Abs(exitHit.position.x - adjustedPosition.x) < movementProperties.deltaTime * movementProperties.maxSpeed &&
                                    Math.Abs(exitHit.position.y - adjustedPosition.y) < movementProperties.deltaTime * movementProperties.maxSpeed)
                                {
                                    //Если мы в ней, то ждем платформу
                                    var node = new PathNode(movingRegion.EntryPoint.transform.position);
                                    node.RegionId        = nextRegion.Index;
                                    node.JumpingPosition = true;
                                    return(node);
                                }
                                else
                                {
                                    //Если не в ней, то топаем к ней
                                    var node = new PathNode(exitHit.position);
                                    node.RegionId = currentArea.mask;
                                    return(node);
                                }
                            }
                        }
                    }

                    //Если мы уже на платформе, то идем следующий регион среди выходных точек и ждем, пока доедем
                    //Либо если мы уже на входе в следующий регион, то топаем дальше
                    var entryPointPosition = movingRegion.EntryPoint.transform.position;
                    if (onPlatform)
                    {
                        if (globalPath.Count < 2)
                        {
                            //Мы уже у цели
                            globalPath = new List <Region>();
                            return(null);
                        }

                        var exitRegion = globalPath[1];
                        foreach (var exit in movingRegion.ExitPoints)
                        {
                            NavMeshHit exitHit;
                            if (NavMesh.SamplePosition(exit.transform.position, out exitHit, 20, exitRegion.Index))
                            {
                                //Мы нашли точку выхода в следующую зону
                                //Если мы в ней, то мы успешно прошли платформу
                                if (Math.Abs(exitHit.position.x - adjustedPosition.x) < movementProperties.deltaTime * movementProperties.maxSpeed &&
                                    Math.Abs(exitHit.position.z - adjustedPosition.z) < movementProperties.deltaTime * movementProperties.maxSpeed)
                                {
                                    globalPath.RemoveAt(0);
                                    var node = new PathNode(exitHit.position);
                                    node.RegionId = globalPath.First().Index;
                                    return(node);
                                }
                                //Иначе ждем приближения точки
                                else
                                {
                                    var node = new PathNode(exit.transform.position);
                                    node.RegionId        = nextRegion.Index;
                                    node.JumpingPosition = true;
                                    return(node);
                                }
                            }
                        }
                    }
                }

                return(new PathNode(nextRegion.PathPoints[0]));
            }

            return(null);
        }
Exemplo n.º 10
0
        private PathNode calcStableRegionPath(Region nextRegion, NavMeshHit currentArea, Vector3 adjustedPosition, MovementProperties movementProperties)
        {
            NavMeshHit moveTo;

            //Ищем ближайшую точку текущего региона, соседствующаю с целевым регионом
            if (NavMesh.SamplePosition(nextRegion.PathPoints[0], out moveTo, 40f, currentArea.mask))
            {
                //Если мы в данный момент находимся близко к найденной точке, то мы на границе
                //В этом случае возвращаем точку из соседнего региона
                if (Math.Abs(moveTo.position.x - adjustedPosition.x) < movementProperties.deltaTime * movementProperties.maxSpeed &&
                    Math.Abs(moveTo.position.z - adjustedPosition.z) < movementProperties.deltaTime * movementProperties.maxSpeed)
                {
                    var node = new PathNode(nextRegion.PathPoints[0]);
                    node.RegionId = nextRegion.Index;
                    return(node);
                }
                //Иначе мы возвращаем ближайшую к цели точку из текущего региона, чтобы скормить локальному планировщику
                else
                {
                    var node = new PathNode(moveTo.position);
                    node.RegionId = currentArea.mask;
                    return(node);
                }
            }
            else
            {
                var node = new PathNode(moveTo.position);
                node.RegionId = currentArea.mask;
                return(node);
            };
        }
Exemplo n.º 11
0
        public static List <PathNode> GetLocalRoute(
            PathNode target,
            PathNode position,
            MovementProperties movementProperties
            )
        {
            Debug.Log("Начато построение пути");

            //  Вот тут вместо equals надо использовать == (как минимум), а лучше измерять расстояние между точками
            //  сравнивая с некоторым epsilon. Хотя может это для каких-то специальных случаев?
            //  if (position.Position.Equals(target.Position)) return new List<PathNode>();
            if (Vector3.Distance(position.Position, target.Position) < movementProperties.epsilon)
            {
                return(new List <PathNode>());
            }

            //HashSet<(Vector3, Vector3)> closed = new HashSet<(Vector3, Vector3)>();
            //HashSet<Vector3> closedDir = new HashSet<Vector3>();
            Priority_Queue.SimplePriorityQueue <PathNode> opened = new Priority_Queue.SimplePriorityQueue <PathNode>();

            //  Тут тоже вопрос - а почему с 0 добавляем? Хотя она же сразу извлекается, не важно
            opened.Enqueue(position, 0);
            int steps = 0;

            //  Посещенные узлы (с некоторым шагом, аналог сетки)
            HashSet <(int, int, int, int)> closed = new HashSet <(int, int, int, int)>();

            closed.Add(position.ToGrid4DPoint(movementProperties.deltaDist, movementProperties.deltaTime));

            PathNode last = opened.First;

            while (opened.Count != 0 && steps < 5000)
            {
                steps++;
                PathNode currentNode = opened.Dequeue();

                last = currentNode;
                //closed.Add(currentNode.ToGrid4DPoint(movementProperties.deltaDist, movementProperties.deltaTime));  //  Для Sample-based список closed не нужен

                //  Тут что-то более сложное
                if (currentNode.EqualsSigma(target, movementProperties.epsilon))
                {
                    Debug.Log("Braked by closest point. Steps : " + steps.ToString());
                    break;
                }

                //  Получаем список соседей
                var neighbours = GetNeighbours(currentNode, movementProperties);
                foreach (var nextNode in neighbours)
                {
                    var discreteNode = nextNode.ToGrid4DPoint(movementProperties.deltaDist, movementProperties.deltaTime);
                    if (!closed.Contains(discreteNode))
                    {
                        nextNode.H = Heur(nextNode, target, movementProperties);
                        opened.Enqueue(nextNode, nextNode.H);
                        closed.Add(discreteNode);
                    }
                }
            }

            if (last.EqualsSigma(target, movementProperties.epsilon) == false)
            {
                Debug.Log("Failed to build a way. Steps : " + steps.ToString());
                return(new List <PathNode>());
            }

            List <PathNode> result = new List <PathNode>();

            //  Восстанавливаем путь от целевой к стартовой
            //  Может, заменить последнюю на целевую, с той же отметкой по времени? Но тогда с поворотом сложновато получается
            var pathElem = last;

            while (pathElem != null)
            {
                result.Add(pathElem);
                pathElem = pathElem.Parent;
            }

            result.Reverse();
            result.RemoveAt(0);
            return(result);
        }