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);
        }
    }
Esempio n. 2
0
    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
        {
        }
    }
Esempio n. 3
0
    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);
            }
        }
    }