?举例:根据数据Datas,实例化生成每条数据对应的条目Item,以及对应的页码;
(6条Item为一页)(已略去不相关的代码)
相关关键词:Dictionary,List,Destory,Foreach,While,For
/// <summary>
/// key:同Datas的key,从0开始
/// </summary>
public Dictionary<int, Transform> itemDic = new Dictionary<int, Transform>();
/// <summary>
/// key:从0开始
/// </summary>
public Dictionary<int, Transform> pageDic = new Dictionary<int, Transform>();
public void Inited()
{
if (isInited == false)
{
......
InitInstantiate(itemDic, itemParent);
InitInstantiate(pageDic, pageParent);
......
isInited = true;
}
Debug.LogFormat("更新后{0}的子物体数:{1}", itemParent.name, itemParent.childCount);
Debug.LogFormat("更新后{0}的子物体数:{1}", pageParent.name, pageParent.childCount);
}
//清空字典和父物体下的子物体,然后重新生成指定个数的子物体
private void InitInstantiate(Dictionary<int, Transform> dic, Transform parent)
{
Debug.LogFormat("初始{0}子物体个数:{1}", parent.name, parent.childCount);
//清空dic,parent
dic.Clear();
if (parent.childCount > 0)
{
for (int i = 0; i < parent.childCount; i++)
{
Destroy(parent.GetChild(i).gameObject);
}
}
//更新parent
switch (parent.name)
{
case "ItemContent":
foreach (var itemData in Datas)
{
AddProjectItem(itemData);
}
break;
case "PageContent":
int pageNum = (itemCount / 6) + (itemCount % 6 == 0 ? 0 : 1);
for (int i = 0; i < pageNum; i++)
{
int index = i;
AddPageNum(index);
}
break;
}
}
//生成Item
public void AddProjectItem(KeyValuePair<int, StartProjectData> itemData)
{
Transform item = Instantiate(itemPrefab, itemParent);
......
item.gameObject.SetActive(false);
itemDic.Add(itemData.Key, item);
itemCount++;
//Debug.LogFormat("key值为:{0},对应id为:{1}", itemData.Key, itemData.Value.id);
}
//生成Page
public void AddPageNum(int curPageNum)
{
Transform page = Instantiate(pagePrefab, pageParent);
......
page.gameObject.SetActive(false);
pageBtnDic.Add(curPageNum, page);
pageBtnCount++;
}
public void OnEnable()
{
StartCoroutine("OnOpenPanel");
}
private IEnumerator OnOpenPanel()
{
yield return new WaitUntil(() => isInited);
......
//itemIndex[0,itemCount-1],pageBtnIndex[0,pageBtnCount-1]
......
Debug.LogFormat("{0}的子物体数:{1}", itemParent.name, itemParent.childCount);
Debug.LogFormat("{0}的子物体数:{1}", pageParent.name, pageParent.childCount);
yield break;
}
注:
1、不能在foreach中对List以及Dictionary等进行元素的添加和删除操作;
否则会报错:Collection was modified; enumeration operation may not execute
因为在foreach中删除元素时,每一次删除都会导致集合的大小和元素索引值发生变化,导致在foreach中删除元素会出现异常;
2、Unity里不能使用While循环执行删除,会导致Unity崩溃;
因为在移除的过程中,不会立刻改变childCount的数量,直接导致死循环;
3、可通过for循环,直接使用Destory进行删除子物体,不过记得删除gameObject,而不是transform;
正确:
Destroy(parent.GetChild(i).gameObject);
错误:
Destroy(parent.GetChild(i));
//清空字典和父物体下的子物体
private void DestoryDicChild(Dictionary<int, Transform> dic, Transform parent)
{
Debug.LogFormat("初始{0}子物体个数:{1}", parent.name, parent.childCount);
//清空dic,parent
dic.Clear();
if (parent.childCount > 0)
{
for (int i = 0; i < parent.childCount; i++)
{
Destroy(parent.GetChild(i).gameObject);
}
}
}
4、for循环也并不是同步执行,会存在异步执行的情况
如下,在遍历topBtns,给btn添加对应索引值的方法时,特意申明局部变量num来作为中间值进行赋值操作;
可通过Debug发现,
使用int num=j;ClickTopBtns(num);方法进行赋值索引值;索引值正确赋值;
直接进行ClickTopBtns(j);索引值全部为for循环遍历到最后的 j 值;
public List<Button> topBtns;
public List<Button> leftBtns;
private void Awake()
{
//传的都是正确的Button,但对应的索引值一个有中转,一个直接赋值
for (int j = 0; j < topBtns.Count; j++)
{
int num = j;
topBtns[num].onClick.AddListener(delegate { ClickTopBtns(topBtns[num],num); });
}
for (int i = 0; i < leftBtns.Count; i++)
{
int index = i;
leftBtns[i].onClick.AddListener(delegate { ClickLeftBtn(leftBtns[index],i); });
}
}
private void ClickTopBtns(Button btn,int num)
{
Debug.LogFormat("Top:{0}的索引值:{1}", btn.name, num);
}
private void ClickLeftBtn(Button leftBtn, int index)
{
Debug.LogFormat("Left:{0}的索引值:{1}", leftBtn.name, index);
}
|