如何在脚本中使用ui按钮和ui切换来创建/销毁另一个脚本上的对象?

时间:2017-05-24 22:17:38

标签: c# unity3d unity5

在Hierarchy中我有一个Canvas,在它下面作为孩子我有一个ui按钮和ui切换。在按钮上,我附加了一个带有onclick事件的脚本。

这个想法是当我点击按钮取决于切换状态false / true决定是否只是创建更多游戏对象或首先销毁所有旧游戏对象并创建新游戏。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GenerateObjectsButton : MonoBehaviour
{
    private InstantiateObjects instantiateobjects;
    private bool toggleOnOf;
    public Toggle toggle;

    private void Start()
    {
        instantiateobjects = new InstantiateObjects();
        toggle.onValueChanged.AddListener((value) =>
            {
                MyListener(value);
            });
    }

    public void MyListener(bool value)
    {
        if (value)
        {
            //do the stuff when the toggle is on
            toggleOnOf = true;
        }
        else
        {
            //do the stuff when the toggle is off
            toggleOnOf = false;
        }
    }

    public void OnButton()
    {
        if (toggleOnOf == false)
        {
            instantiateobjects.generateObjectOnTerrain();
        }
        else
        {
            instantiateobjects.DestroyObjects();
            instantiateobjects.generateObjectOnTerrain();
        }
    }
}

InstantiateObjects脚本:

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

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

    private float terrainWidth;
    private float terrainLength;
    private float xTerrainPos;
    private float zTerrainPos;
    private int numberOfObjectsToCreate;
    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;

        numberOfObjectsToCreate = objectsToInstantiate;

        objname = prefab.name;
        MyCustomEditor.TagsAndLayers.AddTag(objname);

        generateNew = false;
        generateObjectOnTerrain();
    }

    public void Update()
    {

    }

    public void DestroyObjects()
    {
        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; 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(prefab, 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);
    }
}

我现在面临的问题是:

在InstantiateObjects中,当我点击按钮时,我在行上获得了空例外:

createdObjects = GameObject.FindGameObjectsWithTag(objname);

createdObjects为null。除了第一次运行游戏之外,它不是空的,但每次当我点击按钮时它都是空的。

第二个问题是我需要将切换状态更改为false然后单击按钮true单击按钮false单击按钮然后它才会获得DestroyObjects方法。

1 个答案:

答案 0 :(得分:0)

它可能不会更新数组,因为引用是相同的。在每次迭代开始时将数组重置为null,看看是否有效。