Esempio n. 1
0
    protected bool AttackPlayer()
    {
        // FULL SPEED AHEAD
        targetMovementSpeed = 1.0f;

        // Look for player towards the last known position
        // Calculate intercept vector
        Vector3 dir = (playerPos - transform.position).normalized;

        // Find nearest cell with cover from player
        PathNode coverNode;
        Vector3  coverPos;

        if (currentPath == null)
        {
            if (FindCover(out coverNode, out coverPos))
            {
                // Get node position
                Vector3 nodePos = cellGrid.GetCellPos(
                    cellGrid.Grid[(int)coverNode.Position.x, (int)coverNode.Position.y]);

                // Path find to cover (or just the farthest away node if we didn't find cover)
                currentPath = PathFinding.FindPath(currentNode, coverNode);

                // If the path length is 1 (we're already on the cell), move towards hidePos
                if (currentPath.Count == 1)
                {
                    Move((coverPos - transform.position));
                }
            }
            // If we couldn't find any cover, just run away
            else
            {
                Move(-dir);
            }
        }

        // If we can see the player, shoot at it
        if (CanSeeObjectOnLayer(dir, playerLayer, "Player"))
        {
            dir = Quaternion.AngleAxis(Random.Range(-0.5f, 0.5f) * LOOK_PLAYER_JITTER, Vector3.forward) *
                  (playerPos - transform.position).normalized;

            TurnTowards(dir);

            // Shoot once we're facing the right direction
            if (Vector3.Angle(dir, FacingDirection) < 1.0f)
            {
                Fire();
            }
        }
        // Otherwise, look for it
        else
        {
            SwitchState(State.LOOK_FOR_PLAYER);
            return(false);
        }

        return(true);
    }
    protected void SpawnPowerup(GameObject prefab)
    {
        const int MAX_ITERATIONS = 5;

        // Try to spawn a prefab at a random position MAX_ITERATIONS times
        // then give up and mark the powerup as collected
        bool spawned = false;

        for (int i = 0; i < MAX_ITERATIONS; ++i)
        {
            GridCell cell     = openSpaces[UnityEngine.Random.Range(0, openSpaces.Count)];
            Vector3  worldPos = cellGrid.GetCellPos(cell);
            worldPos.z = 0;

            if (!Physics.CheckSphere(worldPos, 0.1f, actors))
            {
                // Spawn powerup
                GameObject powerup = (GameObject)GameObject.Instantiate(prefab, worldPos, Quaternion.identity);

                // Get rid of the "cloned" text in its name
                powerup.name = powerup.name.Substring(0, powerup.name.Length - 7);

                spawned = true;
                powerup.SetActive(true);
                powerups.Add(powerup.GetComponent <Powerup>());
                break;
            }
        }

        // Give up and mark as collected so it'll respawn soon
        if (!spawned)
        {
            GameObject powerup = (GameObject)GameObject.Instantiate(prefab);
            powerups.Add(powerup.GetComponent <Powerup>());
            PowerupCollected(powerup);
        }
    }
    public void Regenerate()
    {
        // Clean up
        Ungenerate();

        // Regenerate maze
        maze.Regenerate();

        // Make the mesh seriously like 5x the resolution of the original maze for destructivity
        hiResGrid = new Cell[maze.Grid.GetLength(0) * MAZE_RESOLUTION,
                                     maze.Grid.GetLength(1) * MAZE_RESOLUTION];

        for (int x = 0; x < maze.Grid.GetLength(0); ++x)
        {
            for (int y = 0; y < maze.Grid.GetLength(1); ++y)
            {
                for (int ix = 0; ix < MAZE_RESOLUTION; ++ix)
                {
                    for (int iy = 0; iy < MAZE_RESOLUTION; ++iy)
                    {
                        Cell oldCell = maze.Grid[x, y];

                        int newX = x * MAZE_RESOLUTION + ix;
                        int newY = y * MAZE_RESOLUTION + iy;

                        Cell newCell = new Cell(oldCell);
                        newCell.position = new Point(newX, newY);

                        hiResGrid[newX, newY] = newCell;
                    }
                }
            }
        }

        // Store a list of empty spaces
        emptySpaces = new List<GridCell>();

        // Copy maze to pathfinding grid
        int width = hiResGrid.GetLength(0);
        int height = hiResGrid.GetLength(1);
        Grid = new GridCell[width, height];
        for (int x = 0; x < width; ++x)
        {
            for (int y = 0; y < height; ++y)
            {
                Grid[x, y] = new GridCell(x, y, hiResGrid[x, y].visited);

                if (Grid[x, y].Accessible)
                    emptySpaces.Add(Grid[x, y]);
            }
        }

        // Create cell grid for pathfinding
        cellGrid = CellGrid;

        // Reset enemy pathfinding data
        NonplayerCharacter.ResetPathfinding();

        // Get list of empty cells
        List<GridCell> emptyCellsCopy = new List<GridCell>(emptySpaces);

        // Pick random deadend for player
        GridCell playerSpawnCell = emptyCellsCopy[Random.Range(0, emptyCellsCopy.Count)];

        // Remove this dead end from the list so that no enemies can spawn there
        emptyCellsCopy.Remove(playerSpawnCell);

        // Spawn the player there
        Vector3 playerPos = cellGrid.GetCellPos(playerSpawnCell);
        playerPos.z = 0;

        GameObject playerObj = ((Component)GameObject.FindObjectOfType(typeof(PlayerCharacter))).gameObject;
        playerObj.transform.position = playerPos;

        // Create enemies and do the same
        enemies = new GameObject("Enemies");
        for (int i = 0; i < enemyCount; ++i)
        {
            // Pick random place for enemy to spawn
            GridCell enemySpawnCell = emptyCellsCopy[Random.Range(0, emptyCellsCopy.Count)];

            Vector3 enemyPos = cellGrid.GetCellPos(enemySpawnCell);
            enemyPos.z = 0;

            GameObject enemy = (GameObject)GameObject.Instantiate(enemyPrefab,
                                                                  enemyPos,
                                                                  Quaternion.identity);
            enemy.GetComponent<NonplayerCharacter>().target = playerObj;

            enemy.transform.parent = enemies.transform;

            // Add a slight force to enemy so they get unstuck if they're overlapping another character
            enemy.rigidbody.AddForce(new Vector3(0.1f, 0.1f));
        }

        // Spawn powerups in maze
        PowerupManager powerupManager = (PowerupManager)GameObject.FindObjectOfType(typeof(PowerupManager));
        powerupManager.SetOpenSpaces(cellGrid, emptySpaces);
        powerupManager.SpawnPowerups();

        // Create mesh for level
        mesh = MeshGenerator.GenerateMesh(hiResGrid);

        // Asign mesh to mesh filter
        GetComponent<MeshFilter>().mesh = mesh;
        GetComponent<MeshCollider>().sharedMesh = mesh;

        // Create lights on walls
        if (wallLightPrefab != null)
        {
            CreateLights();
        }
    }
    public void Regenerate()
    {
        // Clean up
        Ungenerate();

        // Regenerate maze
        maze.Regenerate();

        // Make the mesh seriously like 5x the resolution of the original maze for destructivity
        hiResGrid = new Cell[maze.Grid.GetLength(0) * MAZE_RESOLUTION,
                             maze.Grid.GetLength(1) * MAZE_RESOLUTION];

        for (int x = 0; x < maze.Grid.GetLength(0); ++x)
        {
            for (int y = 0; y < maze.Grid.GetLength(1); ++y)
            {
                for (int ix = 0; ix < MAZE_RESOLUTION; ++ix)
                {
                    for (int iy = 0; iy < MAZE_RESOLUTION; ++iy)
                    {
                        Cell oldCell = maze.Grid[x, y];

                        int newX = x * MAZE_RESOLUTION + ix;
                        int newY = y * MAZE_RESOLUTION + iy;

                        Cell newCell = new Cell(oldCell);
                        newCell.position = new Point(newX, newY);

                        hiResGrid[newX, newY] = newCell;
                    }
                }
            }
        }

        // Store a list of empty spaces
        emptySpaces = new List <GridCell>();

        // Copy maze to pathfinding grid
        int width  = hiResGrid.GetLength(0);
        int height = hiResGrid.GetLength(1);

        Grid = new GridCell[width, height];
        for (int x = 0; x < width; ++x)
        {
            for (int y = 0; y < height; ++y)
            {
                Grid[x, y] = new GridCell(x, y, hiResGrid[x, y].visited);

                if (Grid[x, y].Accessible)
                {
                    emptySpaces.Add(Grid[x, y]);
                }
            }
        }

        // Create cell grid for pathfinding
        cellGrid = CellGrid;

        // Reset enemy pathfinding data
        NonplayerCharacter.ResetPathfinding();

        // Get list of empty cells
        List <GridCell> emptyCellsCopy = new List <GridCell>(emptySpaces);

        // Pick random deadend for player
        GridCell playerSpawnCell = emptyCellsCopy[Random.Range(0, emptyCellsCopy.Count)];

        // Remove this dead end from the list so that no enemies can spawn there
        emptyCellsCopy.Remove(playerSpawnCell);

        // Spawn the player there
        Vector3 playerPos = cellGrid.GetCellPos(playerSpawnCell);

        playerPos.z = 0;

        GameObject playerObj = ((Component)GameObject.FindObjectOfType(typeof(PlayerCharacter))).gameObject;

        playerObj.transform.position = playerPos;

        // Create enemies and do the same
        enemies = new GameObject("Enemies");
        for (int i = 0; i < enemyCount; ++i)
        {
            // Pick random place for enemy to spawn
            GridCell enemySpawnCell = emptyCellsCopy[Random.Range(0, emptyCellsCopy.Count)];

            Vector3 enemyPos = cellGrid.GetCellPos(enemySpawnCell);
            enemyPos.z = 0;

            GameObject enemy = (GameObject)GameObject.Instantiate(enemyPrefab,
                                                                  enemyPos,
                                                                  Quaternion.identity);
            enemy.GetComponent <NonplayerCharacter>().target = playerObj;

            enemy.transform.parent = enemies.transform;

            // Add a slight force to enemy so they get unstuck if they're overlapping another character
            enemy.rigidbody.AddForce(new Vector3(0.1f, 0.1f));
        }

        // Spawn powerups in maze
        PowerupManager powerupManager = (PowerupManager)GameObject.FindObjectOfType(typeof(PowerupManager));

        powerupManager.SetOpenSpaces(cellGrid, emptySpaces);
        powerupManager.SpawnPowerups();

        // Create mesh for level
        mesh = MeshGenerator.GenerateMesh(hiResGrid);

        // Asign mesh to mesh filter
        GetComponent <MeshFilter>().mesh         = mesh;
        GetComponent <MeshCollider>().sharedMesh = mesh;

        // Create lights on walls
        if (wallLightPrefab != null)
        {
            CreateLights();
        }
    }