本帖最后由 Lucifer_H 于 2014-10-31 09:39 编辑

做 UIGrid 的动态加载是做游戏的装备列表时用到的,装备信息都是从后台发过来的,具体加载的代码如下:

[C#] 纯文本查看 复制代码
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 内容,现在正确的写法如下

[C#] 纯文本查看 复制代码
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 循环来完成删除

[C#] 纯文本查看 复制代码
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 ,他就会自动按照名字的顺序进行排序了,已经过试验,毫无卡顿现象。

代码如下~ 

[C#] 纯文本查看 复制代码
[/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 排序、动态加载与销毁的更多相关文章

  1. 关于Unity3D中Resources动态加载NGUI图片的方法

    在NGUI中有些图片我需要动态进行变更或者加载,怎么办? 首先在项目中创建一个Resources目录,接着把需要的图片放在这里面,可以有子文件夹么?当然可以,文件结构很重要哦~ NGUI加载图片的方法 ...

  2. unity3d Resources.Load动态加载资源

    初步整理并且学习unity3d资源加载方法,预计用时两天完成入门学习Unity3d常用两种加载资源方案:Resources.Load和AssetBundle Resources.Load就是从一个缺省 ...

  3. NGUI学习笔记(四):动态加载UI和NGUI事件

    动态加载UI 我们进入一个场景后,如果将这个场景所有可能用到的UI都直接放在场景中做好,由于要在进入场景时就部署好所有的UI对象,那么当UI对象较多时会碰到的问题是:1.初始化场景会产生非常明显的卡顿 ...

  4. 【Unity3D】Unity3D之 Resources.Load 动态加载资源

    [Unity3D]Unity3D之 Resources.Load 动态加载资源 1.Resources.Load:使用这种方式加载资源,首先需要下Asset目录下创建一个名为Resources的文件夹 ...

  5. 在Unity3D的网络游戏中实现资源动态加载

    用Unity3D制作基于web的网络游戏,不可避免的会用到一个技术-资源动态加载.比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完毕.应该优先加载用户附近的场景资源,在游 ...

  6. Unity3D动态加载外部资源

    最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质上我理解没有什么区别.Resources ...

  7. Unity3d Web3d资源的动态加载

    Unity3d Web3d资源的动态加载 @灰太龙 参考了宣雨松的博客,原文出处http://www.xuanyusong.com/archives/2405,如果涉及到侵权,请通知我! Unity3 ...

  8. Unity3d 动态加载场景物件与缓存池的使用

    聊聊Unity3d动态加载场景物件那些事儿. 众所周知,在策划或美术设计完游戏场景地图后,一个场景中可能会存在成千上万个小的物件,比如石头,木箱子,油桶,栅栏等等等等,这些物件并不是游戏中的道具,仅仅 ...

  9. unity3d动态加载dll的API以及限制

    Unity3D的坑系列:动态加载dll 一.使用限制 现在参与的项目是做MMO手游,目标平台是Android和iOS,iOS平台不能动态加载dll(什么原因找乔布斯去),可以直接忽略,而在Androi ...

随机推荐

  1. Java Socket网络编程Client端详解

    此类实现客户端套接字(也可以就叫“套接字”).套接字是两台机器之间的通信端点. Socket client = new Socket(ip,port);//创建一个流套接字并将其连接到指定 IP 地址 ...

  2. hibernate开发流程

    开发流程,注意:每个hibernate版本在集成的时候是不太一样的.本次使用的是hibernate-distribution-3.6.10.Final-dist 一.开发流程 1)在数据库中创建表,代 ...

  3. sudo配置文件/etc/sudoers格式

    sudo的配置文件 sudoers 一般在 /etc 目录下. 不过不管 sudoers 文件在哪儿,sudo 都提供了一个编辑该文件的命令:visudo 来对该文件进行修改. 讲解sudo配置文件/ ...

  4. Spring Cloud概述

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...

  5. 分享一个mysql 复杂查询的例子

    发布:脚本学堂/MySQL  编辑:thebaby   2013-08-23 09:37:37  [大 中 小] 有关mysql复杂查询的一个例子,正在学习mysql的朋友,可以作为一个参考. 在my ...

  6. line: 1: Syntax error: word unexpected (expecting ")")

    开发板上运行可执行程序报出错误: line1: 1: Syntax error: word unexpected (expecting ")") 解决思路: 1.编译器的问题 用a ...

  7. android bitmap compress

    android的照相功能随着手机硬件的发展,变得越来越强大,能够找出很高分辨率的图片. 有些场景中,需要照相并且上传到服务,但是由于图片的大小太大,那么就上传就会很慢(在有些网络情况下),而且很耗流量 ...

  8. TortoiseGit状态图标不能显示

    一开始网上搜到的办法基本都一样,都试过了,没有效果: 办法一: 注册表中找到 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\ ...

  9. 80X86寄存器介绍

    80X86寄存器介绍  32位CPU所含有的寄存器有: 4个数据寄存器(EAX.EBX.ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP)6个段寄存器(ES.CS ...

  10. IIS网站本机可以访问,局域网其他机器无法访问

    [开始]打开[控制面板],选择[WINDOWS 防火墙],进入 步骤阅读 2 在防火墙界面,选择左侧边栏的[高级设置] 步骤阅读 3 在弹出的高级安全Windows防火墙界面中,选择左侧边栏的[入站规 ...