如何用unity3d ngui button的Ngui插件的Poplist组件读取后台提取的数据

程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
NGUI研究院之Sprite精灵与精灵动画的使用(二)
NGUI研究院之Sprite精灵与精灵动画的使用(二)
围观52776次
编辑日期: 字体:
学习了几天Unity3D强大的NGUI插件,MOMO觉得NGUI中最大的亮点之一就是Sprite精灵。我们先说说精灵是什么东西?它可以在一张大图中去截取一部分(大图就是整体图像集合,而截取的小图就是一个精灵),然后起一个精灵的名称,使用时通过精灵的名称就能直接绘制,并且精灵还可以播放动画。总之真的非常强大。本节我们学习如何创建自己的精灵文件。
首先我们在Project中创建一个Prefab对象,默认给它Transform变换属性,暂时我们给Prefab对象起名为MySprite。接着给Prefab挂上图像集合组件。在Unity导航菜单栏中选择Component-&NGUI-&UI-&Atlas(图像集合)即可。
常用的属性介绍:
Coordinates :UI坐标单位,用默认Pixels(像素)就行。
Pixel Size:像素的长度单位1。
Add/Delete:添加与删除精灵。
first就是当前精灵的名称,如果已添加了多个精灵都会出现在Sprite下拉列表中。再往下就是设置该精灵在大图的显示区域以及坐标,下图中我们可看到已经在整个大图中框选了一个区域,就是绿色的矩形,矩形中就是当前精灵中的内容。
下面我们将这张图片分为4块完全相等的精灵,接着我们学习在代码中如何控制这些精灵的绘制以及排序。创建脚本Test.cs并且将它挂在刚刚创建的精灵对象身上。
12345678910111213141516171819202122232425
using UnityEngine;using System.Collections;using System.Collections.Generic;&public class Test : MonoBehaviour {& void Start() {&
//得到精灵组件脚本
UISprite ui = gameObject.GetComponent&UISprite&();&
//得到图像集合中精灵的数量
Debug.Log("精灵的数量" + ui.atlas.spriteList.Count);&
//得到图像集合数组中对应角标精灵对象的名称
string name = ui.atlas.spriteList[2].name;&
//设置显示精灵的名称
ui.spriteName = name;&
//设置精灵的深度,数值越大绘制的越靠前
ui.depth = 2; }}
如下图所示,精灵已经在代码中动态的修改完毕,并且设置了它的深度让它靠前显示。如果想修改它的X、Y位置,直接修改Transform即可。Z轴的话修改它的深度就行,不用修改Z轴坐标。
下面我们再来学习一下精灵动画,NGUI已经帮我们封装了专门播放精灵动画的类UISpriteAnimation 专门处理精灵动画。MOMO在网上随便找了一组2D主角的行走动画,按照上面介绍的方法将整个图片导入工程中。如下图所示,这组人物的行走动画我们选区取左移动的4帧。
这里我在强调一下,需要修改修改材质的着色器,让他支持背景透明,对当前材质的着色器我们选择Unlit/TransparentColored。
接着在Hierarchy视图中选择Sprite(NGUI)(刚刚创建的精灵对象),然后在Unity导航菜单栏中选择Component-&NGUI-&UI-&Sprite Animation(帧动画)组件即可。此时直接运行游戏我们就会发现主角已经按照刚刚裁剪的精灵顺序动了起来,这还没有完,我们下面学习在代码中如何动态的控制精灵。
本例我们的目的是使用NGUI在屏幕中创建一个按钮,第一次点击按钮主角播放行走动画,再次点击按钮主角动画将停止。上篇文章中我们已经学习了NGUI中按钮的相应事件,如果想在别的对象或者脚本中监听某个按钮的点击事件那么就可以使用传递消息的方式。NGUI帮我们封装了一次传递消息的类,Unity导航菜单栏中选择NGUI-》Interaction-&ButtonMessage。它的原理也是使用Unity的sendMessage,有兴趣的朋友可以去看看。接着说正题,创建脚本Test.cs挂在刚刚创建的按钮上。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
using UnityEngine;using System.Collections;using System.Collections.Generic;&public class Test : MonoBehaviour {& //播放动画与不播放 bool isPlayAnim = false; //得到精灵对象 GameObject animObj = null;& void Start() {
//得到精灵对象
animObj = GameObject.Find("Sprite");& }& void OnClick ()&&&&{
if(isPlayAnim)
//停止动画
isPlayAnim = false;
//销毁UISpriteAnimation组件
Destroy(animObj.GetComponent&UISpriteAnimation&());&
//动画停止后设置精灵默认的帧
UISprite ui = animObj.GetComponent&UISprite&();
string name = ui.atlas.spriteList[0].name;
ui.spriteName = name;&
//播放播放
isPlayAnim = true;
//加入播放动画组件
animObj.AddComponent("UISpriteAnimation");
//设置播放动画的速度
//1-60之间数值越大播放速度越快
UISpriteAnimation uiAnim = animObj.GetComponent&UISpriteAnimation&();
uiAnim.framesPerSecond = 10;
如下图所示,运行游戏点击按钮。主角开始迈着大步开始行走了,再次点击主角将停止播放行走动画。嚯嚯。最后MOMO祝大家学习愉快啦啦啦!!
本文固定链接:
转载请注明:
MOMO与MO嫂提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
,,,,,
您可能还会对这些文章感兴趣!程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
NGUI研究院之与EasyTouch结合使用(十五)
NGUI研究院之与EasyTouch结合使用(十五)
围观14306次
编辑日期: 字体:
用了EasyTouch插件一段时间了,小问题还是有一些,总体来说用起来还行。这篇文章我就来说说EasyTouch和NGUI的结合。
总体来说触摸屏幕也就三种情况。
1.触摸事件只响应NGUI部分,不响应3D部分。
2.触摸事件只响应3D部分,不响应NGUI部分。
3.触摸事件同时响应。
举个例子,在战斗场景我们希望通过手指滑动来控制摄像机的旋转。但是这时屏幕上可能还有一些UI的按钮,但是我们不希望用户点击UI按钮也影响到了摄像机的旋转。所以此时我们只希望触摸事件在3D部分响应。
1. 如下图所示,这里我增加了一个UISprite,我希望我的手指触摸事件只在UI上响应,不在3D上响应
1234567891011121314151617181920212223242526272829303132333435363738394041
using UnityEngine;using System.Collections;&public class UImomo : MonoBehaviour { //头像 GameObject icon; void Start ()
icon = transform.Find("icon").gameObject;
//添加一个手指滑动的事件。
EasyTouch.On_SwipeEnd += EasyTouch_On_SwipeEnd; }& void OnDestroy() {
//施放一个手指滑动的事件。
EasyTouch.On_SwipeEnd -= EasyTouch_On_SwipeEnd; }& //当手指滑动结束时在这里 void EasyTouch_On_SwipeEnd(Gesture gesture) {
//判断手指是否触摸在NGUI的头像中
if(gesture.IsStartInRect(NGUIObjectToRect(icon)))
//输出手指滑动的方向
Debug.Log(gesture.swipe);
} }& //计算出NGUI某个UISprite或者UITexture或者 UILabel 在屏幕中占的矩形位置。 private&&Rect NGUIObjectToRect(GameObject go) {
Camera camera = NGUITools.FindCameraForLayer(go.layer);
Bounds bounds = NGUIMath.CalculateAbsoluteWidgetBounds(go.transform);
Vector3 min = camera.WorldToScreenPoint(bounds.min);
Vector3 max = camera.WorldToScreenPoint(bounds.max);
return new Rect(min.x, min.y, max.x - min.x, max.y - min.y); }&}
2.我希望手指触摸只响应3D,不响应NGUI 。这里其实更多的运用于游戏的战斗界面,战斗界面的UI一般都集中在屏幕的四个角, 比如头像 小地图 技能 摇杆等等。EasyTouch提供了NGUI模式,可以很方便的解决这个问题,不过它原理也是用射线来判断,所以你要确保需要略过的UI空间有BoxCollider组件。
我们把所有NGUI做的界面放在UI层上面。代码简单的改改,这样EasyTouch就不会在UI层上响应了。
123456789101112131415161718192021222324252627282930
void Start ()
icon = transform.Find("icon").gameObject;
//添加一个手指滑动的事件。
EasyTouch.On_SwipeEnd += EasyTouch_On_SwipeEnd;
//得到UI摄像机
Camera uiCamera = GameObject.Find("UI Root/Camera").GetComponent&Camera&();
if(uiCamera != null)
//启动NGUI模式
EasyTouch.instance.enabledNGuiMode = true;
//把NGUI摄像机加入过滤队列
if(!EasyTouch.instance.nGUICameras.Contains(uiCamera))
EasyTouch.instance.nGUICameras.Add(uiCamera);
//设置需要过滤的UI层
EasyTouch.instance.nGUILayers = (1 && LayerMask.NameToLayer("UI"));
} }& void OnDestroy() {
//施放一个手指滑动的事件。
EasyTouch.On_SwipeEnd -= EasyTouch_On_SwipeEnd;
EasyTouch.instance.enabledNGuiMode = false;
EasyTouch.instance.nGUILayers =0;
EasyTouch.instance.nGUICameras.Clear(); }
最后,我现在用的EasyTouch可能版本比较老,我用的版本是v3.1.1 因为目前项目也比较稳定,所以也不敢升级。EasyTouch这个版本里有一个BUG。就是超过10只手指在屏幕中滑动会出现空指针的错误,后来我看了一下代码,在UpdateTouches 里面做一下判断就好了。
EasyTouch有很强大的事件回调方法,大家可以去它的官网上查一下。不知道现在还有没有更好用的触屏插件,如果你觉得比EasyTouch还好用的话,希望你在下面给我留言,谢谢。
本文固定链接:
转载请注明:
MOMO与MO嫂提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!1867人阅读
屏幕自适应
NGUI可以比较方便的实现屏幕自适应,但是它的官方教程里面针对这个问题没有详细的教程,所以可能在实现的时候会走比较多的弯路。以下是我在开发过程中找到的一个比较方便的实现方法。
1. UIAnchor
这个是用来确定控件在屏幕中的位置,另外有一篇教程专门讲它的功能,所有不会再赘述
2. UIStretch
这个是用来做缩放的组件。老版本的NGUI是集成在UIAnchor上的。新版本的UIStretch提供了4种缩放方式:
Horizontal:只缩放水平方向
Vertical:只缩放垂直方向
Bose:缩放两个方向
:基于高度等比缩放
然后基于这些我自己实现了一个
:基于宽度等比缩放
代码如下:
这段代码添加在Update方法里面。为了能将UIStretch挂在UIPanel上面不出问题,所有将Z轴也缩放了。
自适应流程
1. 创建一个新的UI,将Anchor里面的UIAnchor调整的合适的位置,注意最好将Anchor设置为Bottom。
2. 将调节到默认屏幕大小。比如UI是以960*640分辨率制作的,那么将调整到960。
3. 在Panel上面添加一个UIStretch,模式选择。完成之后你可以看到你的被修改到了当前屏幕的X方向分辨率大小。
4. 将UI控件添加到Panel上,调整位置,在Panel下的所有控件都会以X方向为标准做等比缩放来适应屏幕大小。
5. 添加一张作为背景的图,将UISprite的anchor设置为Bottom,添加之后你可以看到这个sprite可以在不同的分辨率下自适应了。
6. 以上一步添加的背景图作为参照物来摆放页面上的控件,这样不仅仅是大小,位置也同样会按照相同的模式进行等比缩放
7. 可以在第3步创建的Panel下面添加子Panel,子Panel不需要UIStretch(一般用来做Draggable Panel,否则没必要,会增加额外的Draw Call)
8. 如果某一些控件需要定位在屏幕上下左右中的某一角,可以单独给他添加一个UIAnchor,这个时候UIStretch只会缩放这个控件的大小,它的位置由他自己的UIAnchor控制了
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:140393次
积分:1701
积分:1701
排名:第12642名
原创:23篇
转载:38篇
评论:24条
(1)(1)(1)(3)(3)(6)(1)(16)(3)(1)(3)(3)(2)(4)(2)(1)(6)(4)2295人阅读
UICamera-可以添加到任何相机,包含事件系统.
UICamera是每个UI的重要组成部分.它负责发送Camera中所有NGUI的活动.如果场景中仅有一个Camera,要确保它附有UICamera脚本.如果有多个相机,确保至少用来渲染UI的相机有UICamera脚本.当将这个脚本放在主相机上时,在游戏场景中的所有都将有OnClick, OnHover, OnDrag等事件.
Tooltip Delay:设定悬停与对象多少秒才执行OnTooltip事件.
如果使用Orthographic Projection相机,建议将相机的Size的尺寸设置为当前分辨率高度的一半.比如针对iPad的屏幕分辨率,就设置Size为384.另外一种方法是保持Size是1,缩放UI的Root为该值的倒数,比如在iPad上获得完美尺寸你需要设置Root的缩放到1/384或者0..第二种方法比较容易实行,不过物体在场景视图中照比其他物体会比较小.
如果你仍旧不知道怎么设置正交相机的尺寸,那么尝试看看下面这图.
UIAtlas-定义精灵的纹理图
UIAtlas是一个容器,它包含了一堆sprite的坐标信息.如果你不熟悉这个概念.你可以这样认为:使用一张包含很多小贴图的大贴图比用若干张小贴图更有效率.而大贴图中的小的贴图被称作为精灵(sprite),大纹理成为图集(atlas).
你使用NGUI之前都需要创建一个图集(或使用现有的).可以从这里了解图集的做法.当然也可以直接使用UITexture,但它并不能应对所有问题.
Material:是描述绘制本图集的材料.通常推荐用unlit着色器,比如用.Unlit – Transparent Colored为NGUI.
TP Import:用于导入从TexturePacker导出的精灵.只需要拖拽输出的Txt文件和所有精灵即可.
Coordinates:这允许你从基于像素的坐标系切换为基于UV的坐标系.通常都是以像素坐标系制作,但如果你需要重新调整纹理,则要先切换为纹理坐标.
New Sprite:允许已当前选择的精灵为范本创建新的精灵.
Delete:删除所选精灵.
Sprite:可以通过下拉列表选择所有正在使用的精灵.
Edit Name:重命名精灵的名称.
Outer Rect:设置精灵的外边框.
Inner Rect 设置精灵的内边框,如果你不使用UISlicedSprite,可以跳过这个设置.
Padding:微调校正精灵的偏移量
Correction:基础的校正精灵的坐标使用完美整数像素.
Show:检查精灵在图集中的位置.
可以将精灵组织成组创建多个图集.只要图集共享相同的材质,那么控件仍旧会使用很少的DrawCall.
为达到最佳效果,推荐将纹理的wrap模式设置为&Clamp&和将格式设置为&Truecolor&.
将类似的纹理做成一个图集是很好的方式,但是要尽量减少同时使用的图集数量.
如果你是使用Texture Packer工具来创建图集,要在输出设置中选择Unity3D.
如果你是用Photoshop创建图集,你能通过选择工具配合info panel面板来找出精灵的位置和尺寸.
UIFont-字体图集
UIFont可以设置UI所使用的字体数据和材质.可以使用免费的BMFont,或使用更专业的Glyph Designer.一般只做一次字体,保存为一个预设,作为新标签所用的字体.参数:
Import Font:用于导入Glyph Designer.或BMFont输出的FNT(改后缀为TXT)数据.
UIAtlas:用来设置字体纹理所在的图集,根据是否已选定UIAtlas,你会看到一下选项
如果UIAtlas已指定,你可以选择使用字体的精灵.
如果没有指定UIAtlas,你可以选择用来绘制字体的材质.在NGUI中通常用&Unlit&类别下的着色器,如“Unlit – Transparent Colored&.
你可以调整字体在材质纹理内的像素矩形.
快速校正完美像素坐标,四舍五入到最近的像素值.
Spacing:可以调整字符之间的间距.
Show:检查字体在纹理贴图中的位置.
为达到最佳效果,推荐将纹理的wrap模式设置为&Clamp&和将格式设置为&Truecolor&.
可以将多个字体合并为一个图集.这样整个UI使用这些字体,仍旧会保持一个DrawCall.
你可以给字体增加斜角,阴影,描边等效果,只要确保BMFont导出之前你设置好足够的边距和间距就可以了.
UISprite-从图集中画一个精灵
UISprite是第二个不常用的插件(第一个是UITexture),它唯一用途就是绘制地图集的一部分.
Transform:是很重要的一个组件,每个控件都可以通过Transform来进行位置和大小的调整.它也会影响到&Make Pixel-Perfect&.你可以在它和UICamera之间任选一个来进行&完美像素&的调整.
UIAtlas:用来指定所使用的图集.拖拽或者按下左侧的按钮选择最近使用的图集.
Sprite:选择图集中使用的精灵.选择好精灵后.点击一下&Make Pixel-Perfect&会自动为你调整Transform的尺寸.
Depth是避免用Unity的Z排序(效率不好),而且如果你要旋转UI窗口.单纯的通过调整每个控件的Transform的Z轴来排序是不行的.所以要用这个深度来排序.
Color Tint:用来调整色调.
Make Pixel-Perfect:让你快速调整控件的尺寸到实际像素尺寸.
Pivot:选择部件的坐标原点位置.
Preview:预览精灵的纹理.
如果你看到两个控件有闪烁,意味着你设置了同样的Depth导致了重叠,你要调整不同的深度,让它们不重叠.
不要把多个控件混在一起,否则会影响到完美像素这个功能.添加新控件时要注意保持创建新的子对象.
也可以在使用完美像素按钮后再移动组合控件.
Label-用指定的字体绘制一个文本标签
UILabel被用来显示文字.支持多行,只需要用&\n&换行即可.允许用[RrGgBb]来建立彩色文字.
Transform:是很重要的一个组件,每个控件都可以通过Transform来进行位置和大小的调整.它也会影响到&Make Pixel-Perfect&.你可以在它和UICamera之间任选一个来进行&完美像素&的调整.
UIFont:你可以选择用于这个标签的字体.你可以拖拽预设或者按下按钮选择最近使用的字体.
可以通过使用&\n&来决定标签是多行还是单行,同样可以用16进制颜色值来定义彩色文字,以[RrGgBb]开始,以[-]结束.如&Hello [FF0000]World[-]!&,最后的结果是World是红色的文字.
Line Width:用来指定文字行的最大宽度,如果是单行文本则切掉超出的.如多行文本则会根据宽度自动换行.
Multi-line:选择该项后标签达到最大宽度后会自动换行.
Password:勾选后字符将自动转为星号.
Encoding:勾选后会关闭特殊字符处理,一般用于输入框.
Depth:改边标签控件的层级.
Color Tint:更改文本的主色调.
Make Pixel-Perfect: 让你快速调整控件的尺寸到实际像素尺寸.
Pivot:选择部件的坐标原点位置.
Preview:预览精灵的纹理.
如果你看到文本闪烁或看到被其他控件覆盖了.那么就要调整它的深度.
如果遇到复杂字符串(如斜体,标点,括号混合的)需要增加行宽度避免超宽.
用&\n&和颜色,仅一个标签就可以做到下面的效果.
UIPanel-为控件分组,用于管理和优化DrawCalls
UIPanel用来负责创建实际的几何体.不必特别添加UIPanel,只要创建一个控件,它就会自动被添加.你可以创建多个Panel,用于多个菜单.
Normals:显示法线,用来检查UI正反是否正确.
Gizmos:用来显示几何体,可供选取用.
Debug:配合调试检查场景视图的几何体,如果你开启了这个.就应该取消掉上面Gizmos这个选项.
Widgets:会显示有多少个控件在这个Panel上.
Draw Calls:可以看到用了多少个DrawCall,这个越低越好.
Clipping:可以选择你要显示的部分,默认是不进行裁切的.是利用着色器进行裁切的,如果开启这个选项,NGUI将自动切换为有裁切属性的着色器.
如果开启裁切.你可以通过Center和Size来设置裁切盒.单位为像素.
如果选择柔化边缘裁切,将会有40像素的柔化边缘供处理柔化效果.
Material:是只读的,可以看面板用了多少个材质.一个材质将占用一个DrawCall.
默认情况下如果没有UIPanel的话,会被最根的控件创建并作为其父对象.而且最好让你多个控件都用一个父对象,便于管理.
如果Panels下没有控件.你可以放心的删除这个面板.
如果你删除一个存有控件的Panels,它和它下面的控件都会消失,但是当你播放时,所有控件又会重现,因为又自动创建了一个欣的UIPanel.
当没有变化时,几何体不会重建,这意味着如果有个完全静止的UI,不会没帧都去更新几何形状,相反它也会被重用,提高性能.
UIAnchor-能让控件自动配合屏幕尺寸,填充满屏和保持真实像素尺寸的UI.
UIAnchor有多种用途,其中包括在多种分辨率的屏幕的相对定位.
如果你将它放在2D UI的root上,它会自动进行完美像素处理.
如果将它用于一个对象,它将辅助对象在屏幕上的定位,比如侧边或者角落.
比如放在一个精灵上,可以用来将精灵自动填满整个屏幕,比如做个背景.
HUD Camera是用来绘制该对象的相机,通常会自动选择的.
Side:设置锚点,有4个边,4个角和中心供选择.
Half Pixel Offset:让控件有半像素的位移以避免DirectX 9在Windows机器上的一个Bug.
Stretch To Fill:缩放填充,一般做背景时候会使用它.
Depth Offset:用于基于透视相机时调整计算点的深度.
如果对象有UIAnchor这个脚本,它自身的Transform将不接受你的修改,因为它受控于这个脚本.如果你希望添加基于这个锚点的位移,你可以添加一个子对象.比如你希望有个控件始终在屏幕偏移(100,100)这个位置,你应该在层次面板做这样的结构.UI-&Anchor-&Offset-&Widget.
UIAnchor同样可用于非正交相机.
如果UIOrthoCamera附加到相机,用UIAnchor创建的界面将固定尺寸和位置,无论你将屏幕尺寸改成多大.
Events-NGUI强大的事件系统
UIEvents-事件系统
你可以添加下面的方法脚本到控件或者带有碰撞盒的对象,当然也可以赋予给相机,不过需要相机同时有UICamera脚本:
void OnHover (bool isOver):当鼠标移出或者悬停在某个碰撞器上的时候返回布尔值.在触摸设备上不会有作用.
void OnPress (bool isDown):当鼠标或者触摸到碰撞器发生布尔值返回.
void OnSelect (bool selected):当鼠标或者触摸从OnPress发生后的释放将会返回这个布尔值.
void OnClick():和OnSelect的产生条件相同,当点击或触摸碰撞器并且没有发生拖拽时候触发.
void OnDrag (Vector2 delta):当移动鼠标或者触摸按下时候位移超过特定阀值时触发.
void OnDrop (GameObject drag):当鼠标或触摸释放于从发生OnDrag的不同碰撞器伤触发.传递的参数是产生OnDrag的对象.
void OnInput (string text):当一个OnSelect发生后在同一个碰撞器上触发输入.一般只有UIInput用它.
void OnTooltip (bool show):当鼠标悬停超过tooltipDelay时间后触发该命令.触摸设备上不会有作用.
可以用UICamera.lastCamera找到谁发出的事件,可用UICamera.lastHit得到谁接受这个事件,以及用UICamera.lastTouchPosition得到触摸或屏幕的位置
下面的脚本赋予一个碰撞器时,点击这个碰撞器会输出HelloWorld.
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:522349次
积分:6392
积分:6392
排名:第1682名
原创:65篇
转载:349篇
评论:48条
(2)(2)(6)(25)(2)(5)(3)(65)(20)(2)(4)(4)(58)(12)(10)(82)(75)(25)(1)(1)(1)(3)(2)(8)(1)

我要回帖

更多关于 unity3d ngui 安装 的文章

 

随机推荐