0
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//[ExecuteInEditMode]
public class InstantiateObjects : MonoBehaviour
{
    public GameObject[] objectsToInstantiate;
    public Terrain terrain;
    public float yOffset = 0.5f;
    public int numberOfObjectsToCreate;
    public bool parent = true;
    public bool randomScale = false;
    public float setRandScaleXMin, setRandScaleXMax;
    public float setTandScaleYMin, setTandScaleYMax;
    public float setTandScaleZMin, setRandScaleZMax;

    private float terrainWidth;
    private float terrainLength;
    private float xTerrainPos;
    private float zTerrainPos;
    private GameObject objInstance;
    private GameObject[] createdObjects;
    private string objname;

    public void Start()
    {
        //Get terrain size
        terrainWidth = terrain.terrainData.size.x;
        terrainLength = terrain.terrainData.size.z;

        //Get terrain position
        xTerrainPos = terrain.transform.position.x;
        zTerrainPos = terrain.transform.position.z;

        for(int i = 0; i < objectsToInstantiate.Length; i++)
        {
            objname = objectsToInstantiate[i].name;
            MyCustomEditor.TagsAndLayers.AddTag(objname);
        }

        generateObjectOnTerrain();
    }

    public void Update()
    {

    }

    public void DestroyObjects()
    {
        UpdateList(true);

        if (createdObjects != null && createdObjects.Length > 0)
        {
            for (int i = 0; i < createdObjects.Length; i++)
            {
                DestroyImmediate(createdObjects[i]);
            }
            createdObjects = new GameObject[0];
        }
    }

    public void generateObjectOnTerrain()
    {
        for (int i = 0; i < objectsToInstantiate.Length; i++)
        {
            //Generate random x,z,y position on the terrain
            float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
            float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);

            float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));

            //Generate random x,y,z scale on the terrain
            float randScaleX = Random.Range(setRandScaleXMin, setRandScaleXMax);
            float randScaleY = Random.Range(setTandScaleYMin, setTandScaleYMax);
            float randScaleZ = Random.Range(setTandScaleYMax, setRandScaleZMax);

            //Apply Offset if needed
            yVal = yVal + yOffset;

            //Generate the Prefab on the generated position        
            objInstance = Instantiate(objectsToInstantiate[i], new Vector3(randX, yVal, randZ), Quaternion.identity);

            if (randomScale == true)
                objInstance.transform.localScale = new Vector3(randScaleX, randScaleY, randScaleZ);

            if (parent)
                objInstance.transform.parent = this.transform;

            objInstance.tag = objname;
        }

        createdObjects = GameObject.FindGameObjectsWithTag(objname);

        if (objname == "Teleportation Booth")
            UpdateList(false);
    }

    private void UpdateList(bool destroy)
    {
        GameObject go = GameObject.Find("Main Camera");
        var list = go.GetComponent<PatrolOverTerrain>().Targets;
        if (destroy == false)
        {
            list.AddRange(createdObjects);
            go.GetComponent<PatrolOverTerrain>().Targets = list;
        }

        if (destroy == true)
        {
            list.Clear();
            go.GetComponent<PatrolOverTerrain>().Targets.Clear();
        }
    }
}

Instead attaching the script to every gameObject I will want to clone I want to use array of objects.

For example let's say I have in the array 2 objects, now I want in the inspector to have under each element its own properties. And when I will set the properties as children for each element it will take effect for the specific element only. Inst

Instead general properties for all the elements to make this properties from Y Offset until the last Set Rand Scale Z Max to be children for each element. So i can set the properties per element.

So I can expand each element and see his properties.

Btw: How can I change the random for example that: Set Rand Scale X Min and Set Rand Scale X Min will be on one line and not two lines ? Like:

Set Rand Scale X Min Max Set Rand Scale Y Min Max Set Rand Scale Z Min Max

1
  • Not sure I get it but have you tried an array of InstantiateObject? Commented May 27, 2017 at 19:36

1 Answer 1

1

Good way to do this would be creating custom class and then making array of instances of that class but it require a bit more lines. If you like to read more about this search ISerializationCallbackReceiver.

Simplest would be probably wrapping your variables in struct like below. You can then "unwrap" them to your classes or not. That depends on what you do want.

using UnityEngine;
using System;

public class InstantiateObjects : MonoBehaviour {

    public ObjectsToInst[] objectsToInstantiate;

    [Serializable]
    public struct ObjectsToInst
    {
        public GameObject objectToInstantiate;
        public Terrain terrain;
        public float yOffset;
        public int numberOfObjectsToCreate;
        public bool parent;
        public bool randomScale;
        public float setRandScaleXMin, setRandScaleXMax;
        public float setTandScaleYMin, setTandScaleYMax;
        public float setTandScaleZMin, setRandScaleZMax;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.