如何为gameObject数组中的每个元素添加属性?

时间:2017-05-27 17:16:27

标签: c# unity3d unity5

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();
        }
    }
}

而是将脚本附加到我想要克隆的每个gameObject,我想使用对象数组。

例如,让我说我在数组中有2个对象,现在我想在检查器中让每个元素都有自己的属性。 当我将属性设置为每个元素的子元素时,它将仅对特定元素生效。 Inst

相反,所有元素的一般属性都是从Y偏移量设置此属性,直到最后一个设置兰德标度Z Max为每个元素的子项。 所以我可以设置每个元素的属性。

所以我可以扩展每个元素并查看他的属性。

顺便说一下:如何更改随机数,例如:设置Rand Scale X Min和设置Rand Scale X Min将在一行而不是两行?喜欢:

设置Rand Scale X Min Max 设置Rand Scale Y Min Max 设置Rand Scale Z Min Max

1 个答案:

答案 0 :(得分:1)

这样做的好方法是创建自定义类,然后创建该类的实例数组,但它需要更多的行。如果您想详细了解此搜索ISerializationCallbackReceiver

最简单的可能是将变量包装在struct中,如下所示。然后,您可以将它们“解包”到您的课程中。这取决于你想要的东西。

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;
    }
}