Пример #1
0
    public List <Tile> FindPath(Vector3 startPos, Vector3 endPos)
    {
        Tile startTile = generator.TileFromWorldPoint(startPos);
        Tile endTile   = generator.TileFromWorldPoint(endPos);

        List <Tile>    openSet   = new List <Tile>();
        HashSet <Tile> closedSet = new HashSet <Tile>();

        openSet.Add(startTile);

        while (openSet.Count > 0)
        {
            Tile currentTile = openSet[0];
            foreach (Tile t in openSet)
            {
                if (t.fScore < currentTile.fScore || t.fScore == currentTile.fScore && t.hScore < currentTile.hScore)
                {
                    currentTile = t;
                }
            }

            openSet.Remove(currentTile);
            closedSet.Add(currentTile);

            if (currentTile == endTile)
            {
                ReconstructPath(startTile, endTile);
                return(path);
            }

            List <Tile> neighbours = generator.GetNeighbours(currentTile);
            foreach (Tile neighbour in neighbours)
            {
                if (neighbour.tileType == TileType.Type.ROCK || closedSet.Contains(neighbour))
                {
                    continue;
                }

                int newGScore = currentTile.gScore + GetDistance(currentTile, neighbour);
                if (newGScore < currentTile.gScore || !openSet.Contains(neighbour))
                {
                    neighbour.gScore = newGScore;
                    neighbour.hScore = GetDistance(neighbour, endTile);
                    neighbour.parent = currentTile;

                    if (!openSet.Contains(neighbour))
                    {
                        openSet.Add(neighbour);
                    }
                }
            }
        }

        return(null);
    }
Пример #2
0
    public override int DoLogic()
    {
        float trueSpeed = btree.btRuntimeBlackboard.blackboard["TrueSpeed"];

        if (hungerManager.closerFood == null || path != null && path.Count == 0)
        {
            path = null;
            btree.btRuntimeParams.boolParams["WanderingEnabled"] = true;
            return((int)Result.FAILURE);
        }

        // Move towards the closest food in the view field if is reachable
        bool targetMoved = false;

        if (path != null)
        {
            Tile closerFoodTile = ground.TileFromWorldPoint(hungerManager.closerFood.transform.position);
            if (closerFoodTile != path[path.Count - 1])
            {
                targetMoved = true;
            }
        }

        if (path == null || targetFood != hungerManager.closerFood || targetMoved)
        {
            // Find a path to the closer food and disable wandering behaviour
            targetFood = hungerManager.closerFood;
            Vector3 closerFoodPos = targetFood.transform.position;
            path         = aStar.FindPath(go.transform.position, closerFoodPos);
            currentIndex = 0;
            if (path.Count <= 0)
            {
                // Already reached destination
                return((int)Result.SUCCESS);
            }
            currentTile = path[currentIndex];
            btree.btRuntimeParams.boolParams["WanderingEnabled"] = false;
        }
        else
        {
            // Actual movement following the path found
            if (go.transform.position == currentTile.tilePosition)
            {
                if (currentTile == path[path.Count - 1])
                {
                    // Destination reached
                    path = null;
                    return((int)Result.SUCCESS);
                }
                else
                {
                    currentIndex++;
                    currentTile = path[currentIndex];
                }
            }
            go.transform.position = Vector3.MoveTowards(go.transform.position, currentTile.tilePosition, trueSpeed * 1.65f * Time.deltaTime);
        }
        // Keep moving
        return((int)Result.FAILURE);
    }
Пример #3
0
    public override int DoLogic()
    {
        // Escape in the opposite direction of the threat incoming
        float trueSpeed  = btree.btRuntimeBlackboard.blackboard["TrueSpeed"];
        float threatDist = btree.btRuntimeBlackboard.blackboard["ThreatDistance"];

        // Check in a range equals to the threat distance to get the direction
        Collider2D threat               = Physics2D.OverlapCircle(go.transform.position, threatDist, LayerMask.GetMask("Dinosaur"));
        Vector3    threatDir            = (threat.transform.position - go.transform.position).normalized;
        Vector3    threatDirRotateLeft  = (Quaternion.Euler(0, 0, 115) * -threatDir).normalized;
        Vector3    threatDirRotateRight = (Quaternion.Euler(0, 0, -115) * -threatDir).normalized;

        Debug.DrawRay(go.transform.position, -threatDir);
        Debug.DrawRay(go.transform.position, threatDir);
        Debug.DrawRay(go.transform.position, threatDirRotateLeft, Color.yellow);
        Debug.DrawRay(go.transform.position, threatDirRotateRight, Color.green);

        if (targetTile != null)
        {
            // Keep moving to the target tile
            if (go.transform.position == currentTile.tilePosition)
            {
                if (currentTile == path[path.Count - 1])
                {
                    // We have reached the safe place
                    path       = null;
                    targetTile = null;
                    btree.btRuntimeParams.boolParams["GoingSafe"] = false;
                    btree.btRuntimeParams.boolParams["Escaping"]  = false;
                }
                else
                {
                    currentIndex++;
                    currentTile = path[currentIndex];
                }
            }
            go.transform.position = Vector3.MoveTowards(go.transform.position, currentTile.tilePosition, trueSpeed * 1.8f * Time.deltaTime);
        }
        else
        {
            // Select a random tile at the opposite direction
            Tile[,] grid = ground.tiles;
            Tile        myTile        = ground.TileFromWorldPoint(go.transform.position);
            List <Tile> selectedTiles = new List <Tile>();
            int         neighbourX;
            int         neighbourY;
            for (int x = -2; x <= 2; x++)
            {
                for (int y = -2; y <= 2; y++)
                {
                    neighbourX = myTile.xPos + x;
                    neighbourY = myTile.yPos + y;
                    if (x == 0 && y == 0 || neighbourX < 0 || neighbourX >= ground.columns || neighbourY < 0 || neighbourY >= ground.rows)
                    {
                        // Avoid our tile and those one that go outside the grid
                        continue;
                    }

                    if (Random.value >= 0.5 && selectedTiles.Count < 5)
                    {
                        selectedTiles.Add(grid[neighbourX, neighbourY]);
                    }
                }
                if (selectedTiles.Count == 5)
                {
                    break;
                }
            }

            while (targetTile == null && selectedTiles.Count > 0)
            {
                targetTile = selectedTiles[selectedTiles.Count - 1];

                if (targetTile.tileType != TileType.Type.ROCK && targetTile.tileType != TileType.Type.HOME)
                {
                    Vector3 tileDir       = (targetTile.tilePosition - go.transform.position).normalized;
                    float   dotThreatTile = Vector3.Dot(-threatDir, tileDir);
                    if (dotThreatTile > Mathf.Cos(Mathf.Deg2Rad * 115))
                    {
                        // Good tile for escaping
                        break;
                    }
                }
                // The tile selected isn't eligible
                targetTile = null;
                selectedTiles.RemoveAt(selectedTiles.Count - 1);
            }

            if (targetTile != null)
            {
                Debug.DrawLine(go.transform.position, targetTile.tilePosition, Color.cyan);

                btree.btRuntimeParams.boolParams["GoingSafe"] = true;
                btree.btRuntimeParams.boolParams["Escaping"]  = true;
                Debug.Log(go.name.ToUpper() + " is escaping!");
                path         = aStar.FindPath(go.transform.position, targetTile.tilePosition);
                currentIndex = 0;
                currentTile  = path[currentIndex];
            }
        }
        // We return always success because we want to save our life
        return((int)Result.SUCCESS);
    }