/// <summary>
    /// Вызывается каждый кадр
    /// </summary>
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit hit;
            Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (terrain.GetComponent <Collider>().Raycast(ray, out hit, Mathf.Infinity))
            {
                globalTarget  = new BaseAI.PathNode(hit.point);
                targetUpdated = true;
                Instantiate(DEBUG, globalTarget.Position, Quaternion.identity);
            }
        }

        //  Фрагмент кода, отвечающий за вставание
        var vertical_angle = Vector3.Angle(Vector3.up, transform.up);

        if (vertical_angle > max_angle)
        {
            GetComponent <Rigidbody>().AddForceAtPosition(5 * force * Vector3.up, transform.position + 3.0f * transform.up, ForceMode.Force);
        }
        ;

        if (!walking)
        {
            return;
        }

        //  Собственно движение
        if (MoveBot())
        {
            MoveLegs();
        }
    }
Exemple #2
0
    /// <summary>
    /// Обновление текущей целевой точки - куда вообще двигаться
    /// </summary>
    private bool UpdateCurrentTargetPoint()
    {
        //  Если есть текущая целевая точка
        if (currentTarget != null)
        {
            float distanceToTarget = currentTarget.Distance(transform.position);
            //  Если до текущей целевой точки ещё далеко, то выходим
            if (distanceToTarget >= movementProperties.epsilon || currentTarget.TimeMoment - Time.fixedTime > movementProperties.epsilon)
            {
                return(true);
            }
            //  Иначе удаляем её из маршрута и берём следующую
            Debug.Log("Point reached : " + Time.fixedTime.ToString());
            currentPath.RemoveAt(0);
            if (currentPath.Count > 0)
            {
                //  Берём очередную точку и на выход
                currentTarget = currentPath[0];
                return(true);
            }
            else
            {
                currentTarget = null;
                currentPath   = null;
                //  А вот тут надо будет проверять, есть ли уже построенный маршрут
            }
        }
        else
        if (currentPath != null)
        {
            if (currentPath.Count > 0)
            {
                currentTarget = currentPath[0];
                return(true);
            }
            else
            {
                currentPath = null;
            }
        }

        //  Здесь мы только в том случае, если целевой нет, и текущего пути нет - и то, и другое null
        //  Обращение к plannedPath желательно сделать через блокировку - именно этот список задаётся извне планировщиком
        //  Непонятно, насколько lock затратен, можно ещё булевский флажок добавить, его сначала проверять
        //lock(plannedPath)
        {
            if (plannedPath != null)
            {
                currentPath = plannedPath;
                plannedPath = null;
                if (currentPath.Count > 0)
                {
                    currentTarget = currentPath[0];
                }
            }
        }
        return(currentTarget != null);
    }
    /// <summary>
    /// Обновление текущей целевой точки - куда вообще двигаться
    /// </summary>
    private bool UpdateCurrentTargetPoint()
    {
        if (currentTarget != null)
        {
            if (currentTarget.JumpingPosition)
            {
                currentTarget = globalPlanner.GetGlobalRoute(globalTarget, new BaseAI.PathNode(transform.position), movementProperties, transform.parent != null);
                return(true);
            }

            Vector3 dummyPosition    = new Vector3(transform.position.x, currentTarget.Position.y, transform.position.z);
            float   distanceToTarget = currentTarget.Distance(dummyPosition);
            if (distanceToTarget >= movementProperties.epsilon &&
                transform.parent == null)   //|| currentTarget.TimeMoment - Time.fixedTime > movementProperties.epsilon)
            {
                return(true);
            }
            //Debug.Log("Point reached : " + Time.fixedTime.ToString());
            if (currentPath != null)
            {
                if (currentPath.Count > 0)
                {
                    currentPath.RemoveAt(0);
                }
                if (currentPath.Count > 0)
                {
                    currentTarget = currentPath[0];
                    return(true);
                }
            }
            else
            {
                //currentTarget = null;
                // Если мы сюда пришли, то мы находимся либо в цели, либо на границе регионов, куда нас направил глобальный планировщик
                // Снова дёргаем планировщика, если вернул не null, то
                // 1) смотрим, в той же что и мы зоне вернувшаяся точка
                // 2) если в той же, то скармливает её локалпланнеру и возвращаем этот маршрут
                // 3) если нет, то мы на границе зон. Сразу присваиваем точку из глобального планировщика currentTarget
                var currentPathNode = new BaseAI.PathNode(transform.position);
                var milestone       = globalPlanner.GetGlobalRoute(globalTarget, currentPathNode, movementProperties, transform.parent != null);
                if (transform.parent != null)
                {
                    currentTarget = milestone;
                    return(true);
                }
                if (milestone != null)
                {
                    NavMeshHit currentArea;
                    Vector3    adjustedPosition = new Vector3(transform.position.x, milestone.Position.y, transform.position.z);
                    if (NavMesh.SamplePosition(adjustedPosition, out currentArea, 1f, NavMesh.AllAreas))
                    {
                        if (currentArea.mask == milestone.RegionId)
                        {
                            currentPath = LocalPlanner.GetLocalRoute(milestone, currentPathNode, movementProperties);
                            //Для дебага и прочих шалостей
                            for (int i = 0; i < currentPath.Count; i++)
                            {
                                Instantiate(DEBUG, currentPath[i].Position, Quaternion.identity);
                            }
                        }
                        else
                        {
                            currentTarget = milestone;
                            return(true);
                        }
                    }
                }
                else
                {
                    currentTarget = null;
                }
            }
        }
        else
        if (targetUpdated && globalTarget != null)
        {
            targetUpdated = false;
            var currentPathNode = new BaseAI.PathNode(transform.position);
            //Пример получения майлстоуна от планировщика
            var milestone = globalPlanner.GetGlobalRoute(globalTarget, currentPathNode, movementProperties, transform.parent != null);
            if (milestone != null)
            {
                currentPath = LocalPlanner.GetLocalRoute(milestone, currentPathNode, movementProperties);
                //Для дебага и прочих шалостей
                for (int i = 0; i < currentPath.Count; i++)
                {
                    Instantiate(DEBUG, currentPath[i].Position, Quaternion.identity);
                }
            }
        }
        else if (currentTarget == null)
        {
        }

        if (currentPath != null)
        {
            if (currentPath.Count > 0)
            {
                currentTarget = currentPath[0];
                return(true);
            }
            else
            {
                currentPath = null;
            }
        }

        //  Здесь мы только в том случае, если целевой нет, и текущего пути нет - и то, и другое null
        //  Обращение к plannedPath желательно сделать через блокировку - именно этот список задаётся извне планировщиком
        //  Непонятно, насколько lock затратен, можно ещё булевский флажок добавить, его сначала проверять
        ////lock(plannedPath)
        //{
        //if(plannedPath != null)
        //{
        //    currentPath = plannedPath;
        //    plannedPath = null;
        //    if (currentPath.Count > 0)
        //        currentTarget = currentPath[0];
        //}
        //}
        return(currentTarget != null);
    }
 /// <summary>
 /// Расстояние между точками без учёта времени. Со временем - отдельная история
 /// Если мы рассматриваем расстояние до целевой вершины, то непонятно как учитывать время
 /// </summary>
 /// <param name="other">Точка, до которой высчитываем расстояние</param>
 /// <returns></returns>
 public float Distance(PathNode other)
 {
     return(Vector3.Distance(Position, other.Position));
 }
 /// <summary>
 /// Конструирование вершины на основе родительской (если она указана)
 /// </summary>
 /// <param name="ParentNode">Если существует родительская вершина, то её указываем</param>
 public PathNode(PathNode ParentNode = null)
 {
     Parent = ParentNode;
 }
Exemple #6
0
    /// <summary>
    /// Обновление текущей целевой точки - куда вообще двигаться
    /// </summary>
    private bool UpdateCurrentTargetPoint()
    {
        //  Если есть текущая целевая точка
        if (currentTarget != null)
        {
            float distanceToTarget = currentTarget.Distance(transform.position);
            //  Если до текущей целевой точки ещё далеко, то выходим
            if (distanceToTarget >= movementProperties.epsilon || currentTarget.TimeMoment - Time.fixedTime > movementProperties.epsilon)
            {
                return(true);
            }
            //  Иначе удаляем её из маршрута и берём следующую
            //Debug.Log("Point reached : " + Time.fixedTime.ToString());
            currentPath.RemoveAt(0);
            if (currentPath.Count > 0)
            {
                //  Берём очередную точку и на выход
                currentTarget = currentPath[0];
                return(true);
            }
            else
            {
                currentTarget = null;
                currentPath   = null;
                //  А вот тут надо будет проверять, есть ли уже построенный маршрут
            }
        }
        else
        if (currentPath != null)
        {
            if (currentPath.Count > 0)
            {
                currentTarget = currentPath[0];
                return(true);
            }
            else
            {
                currentPath = null;
            }
        }

        //lock(plannedPath)
        {
            if (PlannedPath != null)
            {
                currentPath = PlannedPath;
                PlannedPath = null;
                if (currentPath.Count > 0)
                {
                    currentTarget = currentPath[0];
                }
            }
        }

        var res = currentTarget != null;

        if (walking && !res)
        {
            walking = false;
            if (_localPathPlaner)
            {
                _localPathPlaner.IsWalking = false;
            }
        }
        return(res);
    }