//Decide which terrain rule to apply public void UpdateTerrainRule() { if (MoveToNextTerrainRule()) { //If we reach the end but we are looping rules, go back to the first one TerrainRule lastTerrainRule = TerrainRules[TerrainRules.Count - 1]; if (CurrentTerrainRule == lastTerrainRule) { if (LoopRules) { CurrentTerrainRule = TerrainRules[0]; //Track where our rule is starting RuleStartLocation = CurrentLocation; } else { CurrentTerrainRule = null; } } else { CurrentTerrainRule = TerrainRules[GetCurrentTerrainRuleIndex() + 1]; //Track where our rule is starting RuleStartLocation = CurrentLocation; } //Reset this RepeatingPointsAtTop = false; } }
public void PlacePrefabs(TerrainManager tm) { terrainManager = tm; InstantiatePrefabManagerObject(ManagerName); List <PrefabQueue> prefabsToAdd = new List <PrefabQueue>(); for (int i = 0; i < terrainManager.AllFrontTopVerticies.Count(); i++) { Vector3 current = terrainManager.AllFrontTopVerticies[i]; for (int j = 0; j < settings.PrefabRules.Count(); j++) { PrefabRule rule = settings.PrefabRules[j]; //Can't do anything without a prefab if (rule.PrefabToClone == null) { Debug.LogWarning("PrefabToClone required"); break; } //If we haven't started yet, set our initial values if (rule.LastPrefabLocation == Vector3.zero) { rule.LastPrefabLocation = current; } rule.CurrentLocation = current; //Save it because it is randomized and changes every time float repeatDistance = rule.RepeatDistance; if (rule.AddPrefab(repeatDistance)) { //Find the location of the first prefab float nextXLocation = rule.NextPrefabXLocation(repeatDistance); Vector3 nextLocation = FindLocationAlongTerrain(nextXLocation); float angle = FindSlopeAngle(nextLocation.x); //Store a list of the prefabs to add. Only add them if every prefab in this ruleset can be added. //If they can't, add them at the start of the next mesh bool addAllPrefabs = true; prefabsToAdd.Clear(); prefabsToAdd.Add(new PrefabQueue() { location = nextLocation, angle = angle }); if (rule.GroupSize > 1) { float increase = 0; for (int k = 1; k < rule.GroupSize; k++) { //Find the location of the next prefab in this group increase = increase + rule.GroupSpacing; nextLocation = FindLocationAlongTerrain(nextXLocation + increase); //We can't place all prefabs. Break out if (nextLocation == Vector3.zero) { addAllPrefabs = false; break; } else { //Store the location of these prefabs as well angle = FindSlopeAngle(nextXLocation + increase); prefabsToAdd.Add(new PrefabQueue() { location = nextLocation, angle = angle }); } } } //Can we add all the prefabs? Then go ahead and instatiate them if (addAllPrefabs) { for (int k = 0; k < prefabsToAdd.Count(); k++) { PrefabQueue pq = prefabsToAdd[k]; //Determine if this prefab is allowed to be placed on this terrain rule TerrainRule currentRule = tm.VertexGen.CurrentTerrainRule; bool allowedForThisTerrainRule = currentRule.AllowedPrefabs.Where(ap => ap.Allowed && ap.Index == j).Any(); bool meetsDistanceReqs = true; //Determine if this prefab is within the distance rules if (rule.UseMinDistance) { if (pq.location.x < rule.MinDistance) { meetsDistanceReqs = false; } } if (rule.UseMaxDistance) { if (pq.location.x > rule.MaxDistance) { meetsDistanceReqs = false; } } //Only add if it is within the slope limits if (pq.angle >= rule.MinSlope && pq.angle <= rule.MaxSlope && allowedForThisTerrainRule && meetsDistanceReqs) { rule.InstantiatePrefab(pq.location, PrefabManagerObject, Pool, pq.angle); rule.LastPrefabLocation = pq.location; } else { //Just update this so we can keep placing prefabs, but don't actually create the prefab rule.LastPrefabLocation = pq.location; } } } } } } }