【NGUI】Unity3D UIGrid 排序、动态加载与销毁
本帖最后由 Lucifer_H 于 2014-10-31 09:39 编辑
做 UIGrid 的动态加载是做游戏的装备列表时用到的,装备信息都是从后台发过来的,具体加载的代码如下:
for(int i = 0 ; i < itemData.Item_List.Count; i++) { Data dataMgr = (Data)itemData.Item_List; setGridDataIconImage(dataMgr);}private void setGridDataIconImage(Data Obj){ grid = GameObject.Find("UIGrid").GetComponent<UIGrid>(); atlas = Resources.Load("Equip/Equip_Atlas", typeof(UIAtlas)) as UIAtlas; parent = GameObject.Find("UIGrid"); GameObject o = Resources.Load("EquipItem_prefab")as GameObject; Item item = o.GetComponent<Item>(); if (null == equipStoreObj) { item.isRemoveItem = true; } else{ item.s_item_id = equipStoreObj.store_itemID; item.s_info1 = equipStoreObj.store_info1; item.s_info2 = equipStoreObj.store_info2; m_MainModel.getAtlasNameAndSpriteImageNameFromEquipID(equipStoreObj.info1,ref item.atlasName,ref item.spriteImageName); } item.Equip.MakePixelPerfect(); NGUITools.AddChild(parent, o); //列表添加后用于刷新listView grid.repositionNow = true; grid.maxPerLine = 5; //重设uigrid grid.Reposition();} |
最大的问题出在下面,就是当我需要更新 UIGrid的时候 我需要销毁旧的,加入新的 List 内容,现在正确的写法如下
public void sortLv() { // 销毁现有元素 while (grid.transform.childCount > 0) { DestroyImmediate(grid.transform.GetChild(0).gameObject); } // 加入新元素 for (int i = 0; i < itemData.Item_Equip_Store_List.Count; i++) { EquipDataManager equipTable = itemData.Item_Equip_Store_List; setGridDataIconImage(equipTable); } } |
开始我使用了 for 循环来完成删除
for(int i = 0; i < grid.transform.childCount; i++){ Destroy(grid.transform.GetChild(0).gameObject);} |
这里有两个问题,首先每一次销毁 grid 元素的 List 会自动进行空白缩减,所以 grid.transform.childCount 的值是一直在变的,元素的销毁就会出问题,而上面正确的方式就是因为 由于每一次销毁都自动缩减所以其实 while中的值一直在递减,所以看似是一个死循环,其实这样写才是正确的。
Destroy 和 DestroyImmediate 的区别
API 手册中这样说
DestroyImmediate
Destroys the object obj immediately. It is strongly recommended to use Destroy instead.
立即销毁物体obj,强烈建议使用Destroy代替。
This function should only be used when writing editor code since the delayed destruction will never be invoked in edit mode. In game code it is recommended to use Object.Destroy instead. Destroy is always delayed (but executed within the same frame) Use this function with care since it can destroy assets permanently!
该函数只在写编辑器代码时使用,因为延时的销毁永远不会在编辑模式下调用。在游戏代码推荐使用Object.Destroy代替。销毁总是延迟的(但在同一帧内执行),小心使用该函数,因为它能永久销毁资源。
Destory
The object obj will be destroyed now or if a time is specified t seconds from now. If obj is a Component it will remove the component from the GameObject and destroy it. If obj is a GameObject it will destroy the GameObject, all its components and all transform children of the GameObject. Actual object destruction is always delayed until after the current Update loop, but will always be done before rendering.
物体obj现在被销毁或在指定了t时间过后销毁。如果obj是组件,它将从GameObject销毁组件component。如果obj是GameObject它将销毁GameObject全部它的组件和GameObject全部transform子物体。实际物体的销毁总是延迟到当前更新循环后,但总是渲染之前完成。
虽然API 手册上说 强烈建议使用Destroy代替。但是当我们使用了Destory 程序果断卡死了,可能就是因为 “实际物体的销毁总是延迟到当前更新循环后”,所以导致了该问题,所以这里暂时还是尽量去使用 DestroyImmediate 。
排序:
UIGrid 自身的排序方式就有几种,不过我没有用,因为是要根据例如 装备的各项属性进行排序,其实就是在第一步的加载那里,有一个 读取 List 表,然后将 List 表中的内容 逐一加入到 UIGrid 当中,那么 List表的读取顺序,就是加载的顺序了。
UIGrid 设置排序方式的官方接口 有一个 Custom 方式,貌似要重载方法去重写排序方法,好像有点小麻烦 ~
我们只要在 List 中提前按照我们想要的顺序进行一遍排序(比如用冒泡,快速,归并什么的 算法就自己根据需要决定了),然后直接进行 UIGrid 的加载就是我们想要的顺序了~
上面有些院里解释还不是很清楚,是因为我也没明白的很详细,待完全弄明白了会继续更新的~ 暂时应该是可以帮助到需要用这个知识点的开发者的。
如果有大神 愿意赐教,我不胜感激!!!
初学者一名,只是想把自己遇到的问题的解决方案写上来,自己留个备份,也可以帮助其他初学者。
可能问题过于简单,希望大神勿喷,有错误还请各位指出,十分感谢。
如何消除排序造成的卡顿:
注:排序时候由于 Item 较多,销毁后在将排序好的 List 重新加载会非常卡顿,用户体验十分差;替换元素其实也比较浪费时间和代码量,所以这里我们找到了更为便捷的解决方案。
UIGrid 的默认排序方式就是按照 UIGrid 里面的 Item 名称进行排序,所以比如我要以 Item 的级别进行排序的话, 我们只需要得到 Item控件,然后将 Item 的控件名称修改为 级别名称,然后调用刷新 UIGrid ,他就会自动按照名字的顺序进行排序了,已经过试验,毫无卡顿现象。
代码如下~
[/color][/color][color=#000000]public void sortWeight(){ for (int i = 0; i < itemData.Item_List.Count; i++) { ItemDataManager ItemTable = itemData.Item_List[i]; grid.transform.GetChild(i).GetComponentInChildren<Item>().name = ItemIndex.getItem_weight(grid.transform.GetChild(i).GetComponentInChildren<Item>().item_id).ToString(); } //列表添加后用于刷新listView grid.repositionNow = true; grid.maxPerLine = 5; //重设uigrid grid.sorted = true; grid.Reposition();}[/i][/color][i][color=#FF0000][color=#000] |
jpg 改 rar 
【NGUI】Unity3D UIGrid 排序、动态加载与销毁的更多相关文章
- 关于Unity3D中Resources动态加载NGUI图片的方法
在NGUI中有些图片我需要动态进行变更或者加载,怎么办? 首先在项目中创建一个Resources目录,接着把需要的图片放在这里面,可以有子文件夹么?当然可以,文件结构很重要哦~ NGUI加载图片的方法 ...
- unity3d Resources.Load动态加载资源
初步整理并且学习unity3d资源加载方法,预计用时两天完成入门学习Unity3d常用两种加载资源方案:Resources.Load和AssetBundle Resources.Load就是从一个缺省 ...
- NGUI学习笔记(四):动态加载UI和NGUI事件
动态加载UI 我们进入一个场景后,如果将这个场景所有可能用到的UI都直接放在场景中做好,由于要在进入场景时就部署好所有的UI对象,那么当UI对象较多时会碰到的问题是:1.初始化场景会产生非常明显的卡顿 ...
- 【Unity3D】Unity3D之 Resources.Load 动态加载资源
[Unity3D]Unity3D之 Resources.Load 动态加载资源 1.Resources.Load:使用这种方式加载资源,首先需要下Asset目录下创建一个名为Resources的文件夹 ...
- 在Unity3D的网络游戏中实现资源动态加载
用Unity3D制作基于web的网络游戏,不可避免的会用到一个技术-资源动态加载.比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完毕.应该优先加载用户附近的场景资源,在游 ...
- Unity3D动态加载外部资源
最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质上我理解没有什么区别.Resources ...
- Unity3d Web3d资源的动态加载
Unity3d Web3d资源的动态加载 @灰太龙 参考了宣雨松的博客,原文出处http://www.xuanyusong.com/archives/2405,如果涉及到侵权,请通知我! Unity3 ...
- Unity3d 动态加载场景物件与缓存池的使用
聊聊Unity3d动态加载场景物件那些事儿. 众所周知,在策划或美术设计完游戏场景地图后,一个场景中可能会存在成千上万个小的物件,比如石头,木箱子,油桶,栅栏等等等等,这些物件并不是游戏中的道具,仅仅 ...
- unity3d动态加载dll的API以及限制
Unity3D的坑系列:动态加载dll 一.使用限制 现在参与的项目是做MMO手游,目标平台是Android和iOS,iOS平台不能动态加载dll(什么原因找乔布斯去),可以直接忽略,而在Androi ...
随机推荐
- .net mvc 站点自带简易SSL加密传输 Word报告自动生成(例如 导出数据库结构) 微信小程序:动画(Animation) SignalR 设计理念(一) ASP.NET -- WebForm -- ViewState ASP.NET -- 一般处理程序ashx 常用到的一些js方法,记录一下 CryptoJS与C#AES加解密互转
.net mvc 站点自带简易SSL加密传输 因项目需要,传输数据需要加密,因此有了一些经验,现简易抽出来分享! 请求:前端cryptojs用rsa/aes 或 rsa/des加密,后端.net ...
- NS3网络仿真(6): 总线型网络
快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载.但请保留作者信息 在NS3提供的第一个演示样例first.py中,模拟了一个点对点的网络,接下来的一个演示样例代码模 ...
- numpy 文件存取 npy、npz
转处:http://blog.csdn.net/pipisorry/article/details/39088003 NumPy提供了多种文件操作函数方便我们存取数组内容. 文件存取的格式:二进制和文 ...
- 了解C#文件操作
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...
- getconf命令【一天一个命令】
我们时常需要查询系统相关的信息,比如页面大小,整数大小之类,如果编写程序去计算会比较繁琐,这里有一个很有用的命令,可以用来获取系统相关信息.它就是getconf. $ getconf PAGE_S ...
- shell 基础语法
shell 基础语法 =============================================== 推荐:http://c.biancheng.net/cpp/shell/ ==== ...
- atitit.Windows Server 2003 2008 2012系统的新特性 attilax 总结
atitit.Windows Server 2003 2008 2012系统的新特性 attilax 总结 1. Windows Server 2008 新特性也可以归纳为4个方面. 1 2. 相 ...
- 【Android】16.2 Started Services
分类:C#.Android.VS2015: 创建日期:2016-03-01 一.简介 Started Service是指被同一个应用程序的某个对象显式启动,或者在设备引导时就已经启动了(配置了服务的情 ...
- SpringBoot接口服务处理Whitelabel Error Page
转载请注明来源:http://blog.csdn.net/loongshawn/article/details/50915979 <SpringBoot接口服务处理Whitelabel Erro ...
- Cocos2d-x 3.x 如何编译成安卓程序
1.安装JDK 2.安装eclipse,安卓官方现在不提供eclipse for android,只好自己配置了.首先安装一个eclipse,在Help——Install New SoftWare中安 ...