【问题标题】:Unity3D: Error when creating Grid layout with List<Transfrom>Unity3D:使用 List<Transform> 创建网格布局时出错
【发布时间】:2018-09-04 06:39:49
【问题描述】:

Unity3D 2018.2

问题:网格没有被列表填充,没有正确响应 用变换填充的 List 在 List 中至少包含 1 个项目,因此它不应为空。有些东西没有正确转移

我正在尝试在滚动视图中创建一个网格布局,其中充满了包含保存在列表中的变换的按钮

我通过检查通常有 0-25 个子变换的游戏对象获得变换。

一旦它从父游戏对象中获取所有子变换,检查哪个子具有名为“Satellite”的标签。用包含这些特定 gameObject.transforms 的 List 填充网格后。

单击网格中的按钮应该包含转换,例如脚本中的 OnMouseEnter() 如果我使用 Debug.Log(transform.name) 它应该显示它。

这是我正在使用的代码,其中没有错误,网格是空的,所以我没有正确接收转换,但我不知道代码有什么问题。谢谢你的帮助。

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

public class SatelliteGridControl : MonoBehaviour {

private List<Transform> satelliteListFromPlanet;

[SerializeField]
private GameObject buttonTemplate;
[SerializeField]
private GridLayoutGroup gridGroup;
[SerializeField]
private Sprite[] iconSprites;

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

    satelliteListFromPlanet = new List<Transform>();

    for (int i = 1; i <= satelliteListFromPlanet.Count; i++)
    {
        SatTransfrom newSatellite = new SatTransfrom();
        newSatellite.iconSprite = iconSprites[Random.Range(0, iconSprites.Length)];

        satelliteListFromPlanet.Add(newSatellite);
    }

    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 (SatTransfrom sat in satelliteListFromPlanet)
    {
        GameObject newButton = Instantiate(buttonTemplate) as GameObject;
        newButton.SetActive(true);

        newButton.GetComponent<SatelliteButton>().SetIcon(sat.iconSprite);
        newButton.transform.SetParent(buttonTemplate.transform.parent, false);
    }
 }

 public class SatTransfrom : Transform
 {
    public Sprite iconSprite;
 }
}

【问题讨论】:

    标签: list unity3d transform grid-layout


    【解决方案1】:

    OnEnable 中,您首先调用getSatellitesInPlanet 来填充您的列表satelliteListFromPlanet

    但是在你打完电话后就打电话

    satelliteListFromPlanet = new List<Transform>();
    

    这会将您的列表重置为新的空列表。

    比你有一个循环

    for (int i = 1; i <= satelliteListFromPlanet.Count; i++)
    { //... }
    

    但是由于 satelliteListFromPlanet 是一个空列表,此时没有任何反应。

    最后,当您致电 GetInventory 时,您的列表仍然是空的,所以

    foreach (SatTransfrom sat in satelliteListFromPlanet)
    

    因为satelliteListFromPlanet 中没有元素,所以永远不会执行。


    现在到第二个问题:

    你有

    for(int i = 0; i< sateliteLostFromPlanet.Count; i++)
    

    但是在这个循环中你会这样做

    sateliteListFromPlanet.Add(xy);
    

    ... 那么在运行此循环期间您的 List 会发生什么?

    它在每个循环中增大 1 个元素,因此您的循环条件 i &lt; sateliteListFromPlanet.Count总是为真,因为每次执行后,您的列表长 1 个元素,i1 更大!

    结果:您“永远”将越来越多的元素添加到同一个列表中,直到您的设备内存不足。

    【讨论】:

    • 不敢相信我错过了,很简单,它正在清除我的列表,但现在当它运行时,我得到一个“内存不足”错误并且程序保持冻结状态。发生了什么事?
    • 现在我明白了,所以我需要一个单独的 List 来保存 SatTransfrom newSatellite = new SatTransfrom(); 吗?还是我什至需要保留该 List ?
    • 是的,我会使用两个不同的列表。但是我仍然想知道这是否会起作用,因为 Transform 是一个 MonoBehaviour 组件,据我所知,您不能简单地使用 new 创建它......
    • 是的,你是对的。它会说cannot convert Transform to SatTransfrom,所以我有点卡在这里。
    • 这超出了您的问题范围,但是:您为什么需要 SatTransformTransform 继承?您可以简单地将其设为“普通”类 (public class SatTransform { //...}) 并使用 List&lt;SatTransform&gt; 仅保存精灵(或直接使用 List&lt;Sprite&gt;,如果这是唯一要存储的数据)...
    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    相关资源
    最近更新 更多