public static void GenerateObjectsOnTerrain(Terrain terrain, int quantity, Vector3 start_point, Vector3 dimensions) { //perform a final check on vectors before generating start_point = EvaluateStartingPointAgainstTerrain(start_point, terrain); dimensions = EvaluateDimensionsAgainstTerrain(start_point, dimensions, terrain); for (int i = 0; i < quantity; i++) { //set loop count _loopFailCount = 0; //attempt to get a start vector VectorBoolReturn startVector = StartingVector(start_point, dimensions, terrain); //check if the operation failed if (!startVector.OperationSuccess) { //display a message box detailing to the user what happened EditorUtility.DisplayDialog(StringConstants.Error, startVector.Message + "\nFailed to find start vector on loop " + (i + 1), "OK"); return; } //get all prefans Object[] prefabs = GetPrefabs(StringConstants.BasicPrefabFilePath); //generate the object, start vector modified to adjust for terrain vector GenerateObject(prefabs[0], startVector.Vector); } }
private void GenerationAlgorithm() { //get an array of all the prefabs Object[] prefabs = GlobalMethods.GetPrefabs(StringConstants.BasicPrefabFilePath); //this is possibly a 'type' parameter? along with 'village'? bool creatingCityStreets = true; if (creatingCityStreets) { for (int currentTotalObjects = 0; currentTotalObjects < _maximumNumberOfObjects; currentTotalObjects += 0) { //choose object (this is effectively a 'seed' for the generator) Object obj = prefabs[Random.Range(0, prefabs.Length - 1)]; VectorBoolReturn startVector = GlobalMethods.StartingVector(new Vector3(), _terrainTarget.terrainData.size, _terrainTarget); if (!startVector.OperationSuccess) { DisplayError("Failed to seed environment with initial start vector\n\nLikely an issue with input vector dimensions compared with the Terrain's vertice coordinates"); return; } //initialise a game object variable and instantiate first object GameObject prefab = (GameObject)PrefabUtility.InstantiatePrefab(obj); prefab.transform.position = startVector.Vector; prefab.transform.rotation = Quaternion.Euler(new Vector3(0, Random.Range(0, 360), 0)); if (prefab.tag == "Cylinder") { prefab.transform.rotation = Quaternion.Euler(new Vector3(0f, 0f, 90f)); prefab.transform.Translate(new Vector3(prefab.transform.lossyScale.x / 2, 0f, 0f)); } //save reference to first generated object GameObject previousPrefab = prefab; //starts at 'one' as the 'seed' is the initial object for (int currentSeriesTotal = 1; currentSeriesTotal < _maximumNumberOfObjectInSeries; currentSeriesTotal++) { if (currentTotalObjects + currentSeriesTotal >= _maximumNumberOfObjects) { goto outerloop; } _loopFailCount = 0; //choose new object Object newObject = prefabs[Random.Range(0, prefabs.Length - 1)]; //check if it satisfies restrictions while (!ObjectWithinParameters(previousPrefab, newObject)) { //if it does NOT satisfy restrictions, choose new object again newObject = prefabs[Random.Range(0, prefabs.Length - 1)]; //exit method if loop limit reached, an error has occurred if (++_loopFailCount >= _maxLoopFail) { DisplayError(StringConstants.Error_ContinousLoopError); return; } } //instantiate the new object prefab = (GameObject)PrefabUtility.InstantiatePrefab(newObject); //set the original position prefab.transform.position = previousPrefab.transform.position; //translate the position relative to the previous objects rotation prefab.transform.Translate(NewRelativeObjectPosition(prefab, previousPrefab), previousPrefab.transform); //rotate the new object to line up with others prefab.transform.rotation = previousPrefab.transform.rotation; //save a copy previousPrefab = prefab; }//end of _maxSeriesQuantity currentTotalObjects += _maximumNumberOfObjectInSeries; }//end of _maxObjectQuantity outerloop :;//used to break from nested loop if maximum quantity reached } else { } }
private void ModelPrefabGenerationAlgorithm() { //get all models Object[] models = GlobalMethods.GetPrefabs(StringConstants.ModelPrefabFilePath); int groupCount = 0; //full generation loop for (int currentTotal = 0; currentTotal < /*-1*/ _maximumNumberOfObjects; currentTotal += 0) { //select a random model (generator 'seed') Object obj = models[Random.Range(0, models.Length)]; //give it a starting position VectorBoolReturn startVector = GlobalMethods.StartingVector(new Vector3(), _terrainTarget.terrainData.size, _terrainTarget); if (!startVector.OperationSuccess) { GlobalMethods.DisplayError("Failed to seed environment with initial start vector\n\nLikely an issue with input vector dimensions compared with the Terrain's world vertex coordinates"); return; } //instantiate the 'seed' model and initiate the generator GameObject newModel = PrefabUtility.InstantiatePrefab(obj) as GameObject; newModel.transform.position = startVector.Vector; newModel.transform.rotation = Quaternion.Euler(new Vector3(0, Random.Range(0, 360), 0)); if (!ModelWithinParameters(newModel)) { DestroyImmediate(newModel); goto cancelledseries; } if (newModel.name != StringConstants.LargeIndustrial) { DuplicateNewModel(obj, newModel); } //save a reference of the previously generated object //groupTotal starts at 1 GameObject previousModel = newModel; //null so it isnt instantiated as an empty game object GameObject previousDuplicate = null; //series generation loop for (int seriesQuantity = 1; seriesQuantity < _maximumNumberInSeriesOrCluster; seriesQuantity++) { //check if we have reached the maximum, exit full generation loop if so if (seriesQuantity + currentTotal >= _maximumNumberOfObjects) { goto finishedgeneration; } //continue selecting models to generate in series Object newObject = models[Random.Range(0, models.Length - 1)]; //check if new model fits parameters _loopFailCount = 0; bool loopSuccess = false; do { //exit method if loop limit reached, an error has occurred if (++_loopFailCount > _maxLoopFail) { Debug.Log("model loop parameter failure"); currentTotal += seriesQuantity; groupCount++; goto cancelledseries; } //select and instantiate model newObject = models[Random.Range(0, models.Length - 1)]; newModel = PrefabUtility.InstantiatePrefab(newObject) as GameObject; //initialise the position to match the previous model newModel.transform.position = previousModel.transform.position; //move the object to the new relative position newModel.transform.Translate(NewModelRelativePosition(previousModel, newModel), previousModel.transform); //check whether parameters matched if (ModelWithinParameters(previousModel, newModel)) { loopSuccess = true; //save reference to this model previousModel = newModel; //used to set previousDuplicate to null if required GameObject duplicate = null; //check whether we can generate a duplicate if (newModel.name != StringConstants.LargeIndustrial) { //generate a duplicate duplicate = DuplicateNewModel(newObject, newModel); //check if the duplicate satisfies parameters if (previousDuplicate == null) { if (!ModelWithinParameters(duplicate)) { DestroyImmediate(duplicate); } } else { if (!ModelWithinParameters(previousDuplicate, duplicate)) { DestroyImmediate(duplicate); } } } previousDuplicate = duplicate; //currently doesnt work, left code as is to try in future //RelativeMoveDuplicate(); } else { DestroyImmediate(newModel); } } while (!loopSuccess); }//end of _maximumNumberInSeriesOrCluster loop - series generation loop currentTotal += _maximumNumberInSeriesOrCluster; groupCount++; cancelledseries :; if (groupCount >= _maximumNumberOfGroups) { goto finishedgeneration; } }//end of _maximumNumberOfObjects loop - full generation loop finishedgeneration :; //kill any invisible models foreach (GameObject o in Resources.FindObjectsOfTypeAll(typeof(GameObject))) { if (o.hideFlags == HideFlags.HideInHierarchy) { Debug.Log("found '" + o.name + "'. Destroying..."); DestroyImmediate(o); } } }