Unity3D: GridLayout продолжает добавлять 1 элемент под последним элементом, когда count равно 1

Unity3D 2018.2

Итак, у меня есть холст, который деактивируется и повторно активируется по выбору пользователя. У меня есть список, заполненный преобразованиями, в котором я заполнил сетку. У меня также есть другой список для хранения всех изображений, которые будут использоваться для заполнения сетки, поскольку сетка заполняется кнопками, содержащими преобразование. Например, если я нажимаю кнопку и запускаю Debug.Log ("transform.name"), я должен увидеть все свои различные преобразования.

Проблема 1. Каждый раз, когда этот холст включается или отключается, сетка продолжает добавлять 1 элемент под начальным, а после повторного включения / отключения под этим создается другой элемент.

+

Проблема 2: Также не вызывается ни одна из этих созданных кнопок. Может проблема здесь в 1-й проблеме?

Вот код, который у меня есть внутри кнопки, которая у меня есть

public class SatelliteButton : MonoBehaviour {

[SerializeField]
private Image myIcon;

 public void SetIcon(Sprite mySprite)
 {
     myIcon.sprite = mySprite;
 }

 public void OnMouseEnter()
 {
     Debug.Log(transform.name);
 }
}

Вот код для заполнения сетки

public class SatelliteGridControl : MonoBehaviour {

private List<Transform> satelliteListFromPlanet;

[SerializeField]
private GameObject buttonTemplate;
[SerializeField]
private GridLayoutGroup gridGroup;
[SerializeField]
private List<Sprite> iconSprites;

// Use this for initialization
void OnEnable()
{
    getSatellitesInPlanet();
    genInventory();
}

//  Get Satellites
private void getSatellitesInPlanet()
{
    satelliteListFromPlanet = new List<Transform>();

    //  Get current planet
    Transform currentPlanet = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<HandleCamera>().targetToLookAt;

    //  Check inside for satellites
    foreach (Transform satellite in currentPlanet)
    {
        //  Check transform for tag
        if (satellite.CompareTag("Satellite"))
        {
            //  Add each transform from planet to array
            satelliteListFromPlanet.Add(satellite);
        }
    }
}

//  Handle Grid
private void genInventory()
{
    if (satelliteListFromPlanet.Count < 6)
    {
        gridGroup.constraintCount = satelliteListFromPlanet.Count;
    }
    else
    {
        gridGroup.constraintCount = 5;
    }

    foreach (Transform sat in satelliteListFromPlanet)
    {
        GameObject newButton = Instantiate(buttonTemplate) as GameObject;
        newButton.SetActive(true);

        newButton.GetComponent<SatelliteButton>().SetIcon(iconSprites[Random.Range(0, iconSprites.Count)]);
        newButton.transform.SetParent(buttonTemplate.transform.parent, false);
    }
 }
}

Я ценю помощь! Изучение макетов сетки с помощью List ‹>!


person WokerHead    schedule 04.09.2018    source источник


Ответы (2)


В genInventory() вы создаете новую кнопку для каждого Transform в satelliteListFromPlanet. Поскольку добавлен только 1, кажется, что ваш список содержит только 1 элемент.

Но вы никогда не уничтожаете / не удаляете этот экземпляр GameObject, поэтому в следующий раз, когда вы снова включите объект, OnEnable будет вызываться снова, и будут созданы новые префабы.

Решение:

Обязательно храните где-нибудь созданные объекты, например

private List<GameObject> instances = new List<GameObject>();

//....

foreach (Transform sat in satelliteListFromPlanet)
{
    GameObject newButton = Instantiate(buttonTemplate) as GameObject;
    newButton.SetActive(true);

    newButton.GetComponent<SatelliteButton>().SetIcon(iconSprites[Random.Range(0, iconSprites.Count)]);
    newButton.transform.SetParent(buttonTemplate.transform.parent, false);

    instances.Add(newButton);
}

И чем вы можете уничтожить их, отключив объект:

private void OnDisable()
{
    foreach(var instance in instances)
    {
        Destroy(instance);
    }
}
person derHugo    schedule 05.09.2018
comment
спасибо, это исправило начальную проблему элемента, который создавался под начальным, полностью забыл уничтожить его OnDisable. Но когда я нажимаю кнопку, Debug.Log не вызывается? Я неправильно звоню Debug.Log(transform.name);? - person WokerHead; 05.09.2018
comment
Хм, это действительно зависит от того, как выглядят ваши кнопки. OnMouseEnter вызывается не при нажатии, а при наведении курсора на объект , но мне кажется, для этого требуется какой-то компонент Collider. В противном случае, если это настоящий компонент UI.Button, лучше использовать OnClick события, которые вы можете напрямую редактировать в инспекторе или также добавить через скрипт. См. Пример здесь - person derHugo; 05.09.2018

Проблема 1. Каждый раз, когда этот холст включается или отключается, сетка продолжает добавлять 1 элемент под начальным, а после повторного включения / отключения под этим создается другой элемент.

Прямо сейчас вы вызываете getSatellitesInPlanet () в методе OnEnabled () SatelliteGridControl. Этот метод вызывается каждый раз, когда объект становится активным. Если вы хотите вызвать метод только один раз, используйте Start.

Проблема 2: Также не вызывается ни одна из этих созданных кнопок. Может проблема здесь в 1-й проблеме?

Не думаю, что проблемы связаны. Можете ли вы подтвердить, что в префабе buttonTemplate есть элемент Image и включен его RaycastTarget?

Всего один совет: я бы установил тип buttonTemplate на SatelliteButton, а не на GameObject. Таким образом, вы можете создать экземпляр типа SatelliteButton и избежать необходимости вызывать:

newButton.GetComponent<SatelliteButton>()
person Steven Coull    schedule 05.09.2018