public void SpawnObstacles() { List <Cell> freeCells = Cells.FindAll(h => h.IsTaken == false); freeCells = freeCells.OrderBy(h => _rnd.Next()).ToList(); for (int i = 0; i < NumberofObstacles; i++) { var cell = freeCells.ElementAt(0); freeCells.RemoveAt(0); cell.IsTaken = true; var obstacle = ObstaclePrefab.Instantiate().First(); //var cell = Cells.OrderBy(c => Math.Abs((c.Entity.Transform.Position - obstacle.Transform.Position).Length())). First(e => e.IsTaken == false); //cell.IsTaken = true; Vector3 offset = new Vector3(0, 0.5f, 0); obstacle.Transform.Position = cell.Entity.Transform.Position + offset; SceneSystem.SceneInstance.Scene.Entities.Add(obstacle); } }
private bool CanSpawn(int pathIndex, int zIndex, ObstaclePrefab prefab) { //Check if path is raised and if the obstacle isnt raised break if (paths[pathIndex].currentHeight == 1 && !prefab.isRaised) { //Debug.Log("Path was not raised"); return(false); } if (paths[pathIndex].currentHeight == 0 && prefab.isRaised) { //Debug.Log("Obstacle was not raised"); return(false); } //Check if obstacle needs side and is not on side if (prefab.needsSide && paths[pathIndex].currentLane == 1) { //Debug.Log("Object was not on the side"); return(false); } //Checks if obstacle is 3 wide, then if you are on an available offset then if path is currently in the middle lane //if wide and not in middle lane return false if (prefab.needsMiddle && paths[pathIndex].currentLane != 1) { //Debug.Log("Path was not in middle"); return(false); } //if 3 wide, in middle lane but z isnt a multiple of 3 if (prefab.isFullWidth && (zIndex % 3 != 0 || zIndex == 0)) { //Debug.Log("Path was not divisible by 3"); return(false); } //if wide and is currently raised down spawn if (prefab.isFullWidth && paths[pathIndex].currentHeight == 1) { //Debug.Log("Oldheight was Raised"); return(false); } //if 3 wide, in middle lane and z is multiple of 3 if (prefab.isFullWidth) { //test if each tile is available for (int offset = 0; offset < prefab.tiles.Length; offset++) { int localX = offset % 3; int localZOffset = Mathf.FloorToInt(offset / 3); //If out of bounds if (zIndex + localZOffset > sectionLength - 1) { //Debug.Log("Obstacle was out of bounds"); return(false); } //if not available set to false and break loop if (obstacles[localX, zIndex + localZOffset] != TileTypes.Empty) { //Debug.Log("Obstacle was blocked by others"); return(false); } //if last was available set to true and break loop if (offset == prefab.tiles.Length - 1) { return(true); } } } //for each piece of the prefab check if it is in bounds, then check if the space if free for (int localZ = 0; localZ < prefab.tiles.Length; localZ++) { //if not in bounds if (zIndex + localZ > sectionLength - 1) { //Debug.Log("Obstacle was out of bounds"); return(false); } //if obstacle is blocked by other if (obstacles[paths[pathIndex].currentLane, zIndex + localZ] != TileTypes.Empty) { //Debug.Log("Obstacle was blocked by others"); return(false); } //if last position set canSpawn if (localZ == prefab.tiles.Length - 1) { return(true); } } Debug.LogWarning("Returned false because no condition was met"); return(false); }
private int TrySpawnObstacle(int sectionType, int pathIndex, int z, float zOffset, ref bool[] walls) { //foreach prefab in the specified sectionType bool[] canSpawn = new bool[sectionPrefabs[sectionType].prefabs.Length]; foreach (var prefabT in sectionPrefabs[sectionType].prefabs.Select((value, index) => new { value, index })) { canSpawn[prefabT.index] = CanSpawn(pathIndex, z, prefabT.value); } //Select a prefab based on weight int[] weights = new int[canSpawn.Length]; for (int i = 0; i < weights.Length; i++) { weights[i] = sectionPrefabs[sectionType].prefabs[i].weight; } int randomIndex = GetRandomIndex(canSpawn, weights); //If no available index if (randomIndex == int.MaxValue) { return(0); } //Gets the actual WorldObjectType index to spawn the obstacle int actualIndex = GetActualIndex(sectionPrefabs[sectionType].prefabs[randomIndex].name); //Fill the obstacle arrays with the data from the prefab int prefabLength = 0; ObstaclePrefab prefab = sectionPrefabs[sectionType].prefabs[randomIndex]; if (prefab.isFullWidth) { //set walls to true as the spawned prefab includes walls walls[z / 3] = true; //Fill obstacle array with prefab values for (int n = 0; n < prefab.tiles.Length / 3; n++) { for (int m = 0; m < 3; m++) { obstacles[m, z + n] = prefab.tiles[n * 3 + m]; } } //Set prefabLength to skip loop ahead later prefabLength = prefab.tiles.Length / 3; } else { //Fill obstacle array with prefab values for (int m = 0; m < prefab.tiles.Length; m++) { obstacles[paths[pathIndex].currentLane, z + m] = prefab.tiles[m]; } //Set prefabLength to skip loop ahead later prefabLength = prefab.tiles.Length; } //Spawn the obstacle, if fullWidth spawn in middle if (sectionPrefabs[sectionType].prefabs[randomIndex].isFullWidth) { SpawnObject(actualIndex, new Vector3(0, 0, z * pathWidth + zOffset), 0); TrySpawnCollectable(pathIndex, z, zOffset, sectionType); } else { SpawnObject(actualIndex, new Vector3(paths[pathIndex].currentLane * pathWidth - pathWidth, 0, z * pathWidth + zOffset), 0); TrySpawnCollectable(pathIndex, z, zOffset, sectionType); } //override if dragon dont spawn after obstacle but after 2, then it should force turn if (prefab.name == WorldObjectType.Dragon) { prefabLength = int.MaxValue; } return(prefabLength); }