在NGUI中可以很方便的实现ListView的控件,ListView就好比IOS或Android平台中使用手势上下拖动的控件。在Unity3D中实现ListView的原理无非就两种,第一种是摄像机不动只移动控件,第二种是控件不动只移动摄像机。在官方的Demo中已经有这两种的例子,为了活灵活现的使用listView,MOMO还是决定详细的写一篇文章帮助初学者快速上手listView。
和之前的文章开始一样,我们先创建一个2D的游戏平面。接着给Panel面板绑定游戏组件,Unity导航菜单栏中选择Component->NGUI->Interaction->Grid,它主要设定ListView中每一个item的属性。继续在Unity导航菜单栏中选择Component->NGUI->Interaction->UIDraggablePanel,它主要设定listView的触摸区域以及与拖动条事件等。
如下图所示,我详细说说Panel面板中一些需要注意的属性。
UIGrid(Script):Arrangement 选择Vertical表示这个ListView表示纵向,这里如果选择Horizontal表示该ListView是横向的。
Cell Width:ListView中每一个item的宽度。
Cell Height:listView中每一个item的高度。
UIDraggable Panel(Script):选项中的Scale非常重要,这里设置y = 1 表示ListView只支持纵向的拖动,如果设置X=1表示列表只支持横向的拖动,如果两个都=1表示列表同时支持横向与纵向的拖动。
Horizontal Scroll Bar 与 Vertical Scroll Bar表示横向或纵向的拖动条与listView结合,然而这里我们无需写一行代码,它会自动帮我们计算,将你的ListView与拖动条结合。
再说说最上面的UIPanel(Script) ,我们选择Clipping的类型为SoftClip,这里可设置listView整体的显示区域。如下图所示,整体的显示区域就是紫色框中的区域。橙色框是ListView整体的显示内容,它会依次的排列下去,但是永远只会显示紫色框中的内容。
OK。接着我们看看目前工程的结构。在Hierarchy视图中Anchor下面同级的目录中有Button、Panel、Scroll Bar。Button就是上图中添加列表的按钮,Panel中是通过点击添加列表按钮后自动添加的列表预设。Scroll Bar表示上图中左侧的纵向拖动条。在右侧监测面板视图中,BoxCollider组件必须添加,该组件中Center与Size可设置ListView中的Item的触摸响应区域,这个区域应当与Item的显示区域相当。
还有一个重要的组件就是UIDrag Panel Contents(Script),如果没有它ListView就无法拖动。在Unity导航菜单栏中选择Component->NGUI->Interaction->UIDrag Panel Contents即可。切记 >_<
将预设资源放在Resources文件夹中是为了使用Resource来读取。
下面我们看看动态添加列表的脚本,把脚本绑定在Button上。噢对,这里还有个小插曲,本文中的中文字体需要感谢kuku小妖制作的:字体的下载地址如下:http://game.ceeger.com/forum/read.php?tid=729
Test.cs (为什么又是Test.cs 嚯嚯 上瘾了 改不了了 哇咔咔!!)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Test : MonoBehaviour {
public UIGrid grid;
int count = 0;
void Start()
{
//得到grid对象
grid = GameObject.Find("Panel").GetComponent<UIGrid>();
}
void OnClick ()
{
//克隆预设
GameObject o =(GameObject) Instantiate(Resources.Load("item"));
//为每个预设设置一个独一无二的名称
o.name = "item" + count;
//将新预设放在Panel对象下面
o.transform.parent = GameObject.Find("Panel").transform;
////下面这段代码是因为创建预设时 会自动修改旋转缩放的系数,
//我不知道为什么会自动修改,所以MOMO重新为它赋值
//有知道的朋友麻烦告诉我一下 谢谢!!!
GameObject item = GameObject.Find(o.name);
item.transform.localPosition = new Vector3(0,0,0);
item.transform.localScale= new Vector3(1,1,1);
count ++;
//列表添加后用于刷新listView
grid.repositionNow = true;
}
}
我们在创建一个Button用于动态的删除列表。我们编写脚本Delete.cs绑定上该按钮,原理和添加差不多大家看看哈~~
Delete.cs
using UnityEngine;
using System.Collections;
public class Delete : MonoBehaviour {
public UIGrid grid;
void Start()
{
//得到grid对象
grid = GameObject.Find("Panel").GetComponent<UIGrid>();
}
void OnClick()
{
//通过标签名称找到多有对象,前提是给预设起一个tag,这里我叫它player
GameObject []items = GameObject.FindGameObjectsWithTag("Player");
//当预设数量大于 0时
if(items.Length >0)
{
//删除列表的item
Destroy(items[0]);
//刷新UI
grid.repositionNow = true;
}
}
}
接着我们学习点击某项Item后修改显示的内容,将如下脚本挂在item当中。
item.cs
using UnityEngine;
using System.Collections;
public class item : MonoBehaviour {
void OnClick()
{
//得到item自对象的精灵组建。
//因为得到的组建采取深度优先
//所以我们需要修改数组中元素为1的精灵
//数组中元素为0的精灵是按钮的背景
UISprite ui = GetComponentsInChildren<UISprite>()[1];
//修改头像为女生头像
ui.spriteName = "icon1";
//得到文字对象
UILabel label = GetComponentInChildren<UILabel>();
//修改文字内容
label.text = "若若";
}
}
如下图所示,这里本文的所有知识点,NGUI是不是很给力呢?哇咔咔!啦啦啦!
本节教学下载地址:http://vdisk.weibo.com/s/abXug
祝大家学习愉快,一起学习一起进步哇咔咔~~
- 本文固定链接: https://www.xuanyusong.com/archives/973
- 转载请注明: 雨松MOMO于 雨松MOMO程序研究院 发表





那个啥,关于NGUI自带的Scroll View (Panel),我在built setting里面选择了android platform,然后点 switch platform,结果整个Drag View就花了,有资料说是shader的问题,我看了下,是clipping那边出错了,不知道momo有没有什么好的解决方案啊?
我没遇见这种错误 .。
////下面这段代码是因为创建预设时 会自动修改旋转缩放的系数,26 //我不知道为什么会自动修改,所以MOMO重新为它赋值27 //有知道的朋友麻烦告诉我一下 谢谢!!!这里我告诉你为啥,用Instantiate是错的,具体应该用nguitools.addchild,你去看看文档就知道了。
////下面这段代码是因为创建预设时 会自动修改旋转缩放的系数,26 //我不知道为什么会自动修改,所以MOMO重新为它赋值27 //有知道的朋友麻烦告诉我一下 谢谢!!!这里我告诉你为啥,用Instantiate是错的,具体应该用nguitools.addchild,你去看看文档就知道了。
每个cell的宽高可以不同吗
雨松大大,我想做个游戏用的仓库背包界面,格子带吸附,物品图标能拖动。有啥经验能指教下呀。。。。
写条件判断, 不过NGUI中有技能图标吸附的例子。 你看看吧
谢谢啊,解决了。目前头疼资源加载问题,就是拖动图标的时候很卡,图标是个动画,在IPHONE上很卡的。还有买了雨松大大的书,看了下全是UNITY自己的东西对于NGUI这种常用的2D界面插件没介绍啊。希望有机会再出一本书系统的介绍下这些很常用很好用的插件。
希望吧 不过现在实在是太忙了 .。
我想动态加载几百上千条,会很卡,有没有好点的解决方案,谢谢。
动态的加载与释放。。
这个UI Draggable Panel 是只有正式版才有么?我的NGUI里面没有这个panel
有的。。。
有的
正式版里才有?还是试用版也有啊??
好吧。在你给的那个连接里有。。
恩德。
教程真不错。很详细易懂,momo已经成为unity界的名人了 支持一下 哈哈。 删除列表的时候发现是跳着删的 ,原来item的位置出现了一个空缺 。有没有好的方法可以删除之后自动排位 ??
删完再刷新一下grid就可以了, grid.repositionNow = true;
o~原来是这样 3q~
我想请问一下 我看官方的Demo的ScollList的示例 为什么当我把SlicedSprite拖给一个物体的时候它就会被放大 尺寸变得很大呢?
就是将SlicedSprite变为某一个物体的子物体时会有问题 比如我做一个空物体叫item 当把它拖放给item 图就会变得特别大
NGUI有时候确实存在BUG 你可以手动的修改一下缩放系数就可以
嘛…第一个为什么不这样写orz…Transform itemParent;GameObject loadObject;void Start(){ …. itemParent = GameObject.Find(“Panel”).transform; loadObject = Resources.Load(“item”) as GameObject;}void OnClick (){ GameObject o = Instantiate(loadObject) as GameObject;o.name = “item” count; o.transform.parent = itemParent; //改变物体的父物体时,本身的世界坐标系没有变 所以要进行以下的操作 o.transform.localPosition = new Vector3(0, 0, 0); o.transform.localScale = new Vector3(1, 1, 1); o.transform.localEulerAngles= new Vector3(1, 1, 1);//加个旋转-,- ……}//因为用Instantiate复制出来的物体首先是在根目录下….创建一个后缀带克隆的对象,(这和右键的DupLicate复制的物体有别)//此时假设它的scale是1,1,1 我们改变父对象之后,本身的缩放是不变,所以必须克隆后改变本地坐标,旋转和缩放才能得到你想要的效果
嘛…第一个为什么不这样写orz…Transform itemParent;GameObject loadObject;void Start(){ …. itemParent = GameObject.Find(“Panel”).transform; loadObject = Resources.Load(“item”) as GameObject;}void OnClick (){ GameObject o = Instantiate(loadObject) as GameObject; o.name = “item” + count; o.transform.parent = itemParent; //改变物体的父物体时,本身的世界坐标系没有变 所以要进行以下的操作 o.transform.localPosition = new Vector3(0, 0, 0); o.transform.localScale = new Vector3(1, 1, 1); o.transform.localEulerAngles= new Vector3(1, 1, 1);//加个旋转-,- ……}//因为用Instantiate复制出来的物体首先是在根目录下….创建一个后缀带克隆的对象,(这和右键的DupLicate复制的物体有别)//此时假设它的scale是1,1,1 我们改变父对象之后,本身的缩放是不变,所以必须克隆后改变本地坐标,旋转和缩放才能得到你想要的效果
旋转应该是o.transform.localEulerAngles= new Vector3(0, 0, 0);
你好,我按照你上面的操作,在对UIPanel面板图中的属性进行对比时发现,图里的属性在我自己建立的里面没有,就是那两个Material。另外,我按照操作来做,并没有出现教程中的效果,没有出现图形。
不知道什么原因,请教!
这个不好说, 因为我没看到你的项目, 你可以自己查看一下API 和这个文章看看自己那里有错疏忽。。 或者截图让我看看效果。
Instantiate后面还有两个参数,都填上就不会改变了,否则按默认的生成。
学习了
换了界面~~
角哥破坏队形……
板凳一下,你就知道,楼下队形
沙发一下!你就知道哇咔咔~~