[UnityUI]NGUI备忘录

来源:互联网 发布:xampp php 5.5 编辑:程序博客网 时间:2024/05/26 09:53

零、概念

1.UISprite与UITexture的区别:http://www.xuanyusong.com/archives/2697

简单地说,UITexture是一张独立的图,不依托于任何图集,这张Texture有自己的材质球和shader,每一个UITexture都将消耗一个DrawCall,一般可以考虑将游戏背景图等大图设置为UITexture;相反,UISprite则依赖于图集。


2.NGUI的字体分为动态字体和静态字体。动态字体就是我们常见的字体文件(一般以.ttf为后缀),而静态字体就是将文字图片做成图集。


3.NGUITools.AddChild()和Instantiate的区别:

NGUITools.AddChild()是对Instantiate的进一步封装,本质上等于:

GameObject a = Instantiate(child);

a.transform.parent = parent.transform;


4.NGUI中的事件委托:

a.EventDelegate:负责NGUI中所有的事件监听和回调。

[csharp] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class Test : MonoBehaviour {  
  5.   
  6.     public UIButton button;  
  7.   
  8.     void Start ()   
  9.     {  
  10.         EventDelegate.Add(button.onClick, DebugInfo);  
  11.     }  
  12.       
  13.     void DebugInfo()  
  14.     {  
  15.         Debug.Log("按钮被按下");  
  16.     }  
  17.   
  18. }  

b.UIEventListener:上面的EventDelegate,是针对UI控件自带的事件设置回调,如果想让按钮接收其他事件(如拖拽),可以使用这个类。因此,这个类更为强大。

[csharp] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class Test : MonoBehaviour {  
  5.   
  6.     public UIButton button;  
  7.   
  8.     void Start ()   
  9.     {  
  10.         UIEventListener.Get(button.gameObject).onDrag += Drag;  
  11.     }  
  12.   
  13.     void Drag(GameObject go, Vector2 delta)  
  14.     {  
  15.         Debug.Log("拖拽中");  
  16.     }  
  17.   
  18. }  

c.UIEventTrigger:和上面的UIEventListener类似,不过上面的是通过代码绑定,而这个是通过界面绑定。



5.NGUI中的UI控件默认使用第九层(即Layer 8),因此,如果将第九层的名字更改,那么UI控件所在的层也会更改。



6.让粒子显示在UI前

在NGUI中,渲染的层级关系是由Depth决定的,但是,最本质的还是由渲染的Render Queue决定的,这是一个Shader中常见的参数。在NGUI中,每一个Panel上也有一个RenderQ的设置项,RenderQ越高的将会越上层显示。

粒子系统的RenderQ一般是3000,所以,如果我们希望粒子处于两个Panel之间,只需要将其中一个Panel的RenderQ改为StartAt模式,将值改为3000以下的值,然后将另一个Panel的RenderQ设为3000以上的值,就可以让粒子在两个Panel之间显示了。

当然,如果只需要让粒子显示在最上层,最简单的方法就是加入一个摄像机,给这个粒子设置一个单独的层,让新加入的摄像机只渲染这个层,将摄像机的Clear Flags设为Depth Only,然后将渲染的Depth值设为最高的即可。

(新建一个粒子,因为UI Root下的Camera的depth默认大于Main Camera,而粒子默认是主摄像机照射的,所以UI会显示在粒子前。可以通过新建一个层,赋值给粒子,那样粒子就不会被主摄像机照射了。)


7.UI事件监听的击穿

如下图,虽然白色的面板遮挡住了下面的button,但是点击时还是会响应,这就是所谓的"击穿"了。


以下提供两种解决方法:

1.给白色的面板添加BoxCollider   2.修改UICamera中的EventMask



一、组件(三大核心:UIRoot、UIPanel和UICamera)

UIRoot(作用是缩放UI):

a.Scaling Style

1.Flexible(旧版本为Pixel-Prefect):是指永远保持像素大小不变,比如一张100*100像素的图片,在500*500分辨率的屏幕上,它是100*100像素;在1000*1000分辨率的屏幕上,它还是100*100像素。这样就会导致分辨率高的屏幕下UI显得小,分辨率低的屏幕下UI显得大,例如前面的例子,分别占1/5和1/10,好处是不会对UI进行缩放,清晰度高。

Minimum Height & Maximum Height:假如设置Minimum Height为720,那么在800 * 600下,UI还是按720那样运行。

2.Constrained(旧版本为FixedSize):使得UI在不同分辨率下能按宽 / 高进行比例缩放。例如,设置Content Height为1000,然后一张100*100的图片在高度为1000的屏幕分辨率下占1/10的高度,那么当UI放到一个分辨率为500*500的屏幕上时,它依然占1/10的高度,只不过图片被缩放为50*50。

3.ConstrainedOnMobiles(旧版本为FixedSizeOnMobiled):Flexible和Constrained的混合,在PC上是Flexible,在移动平台上是Constrained


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

NGUI自适应:

一般来说,我们UIRoot都会选择Constrained的缩放模式,这样可以让UI随着分辨率而自动缩放,保持和屏幕相对的大小比例不变。需要考虑的问题是,不同屏幕的宽高比不一样,此时一般都会以高度为基准而拉伸宽度。主流设备的宽高比一般为4:3和16:9。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


UIPanel

a.Depth:尽量保证一个场景中的Panel不要共用同一个深度,因为这将导致NGUI在渲染时无法以一个DrawCall完成,渲染顺序发生混乱,而此时NGUI会以增加DrawCall的方式来保证渲染顺序不混乱,这样就增大了性能的开销。

b.Clipping:裁剪功能


UICamera:

UICamera脚本实际做的事是发送NGUI事件给所有被它所附加的摄像机所看见的对象。除此之外,它不对UI做任何事情了。实际上,如果你想要你的游戏中的非UI对象能接收NGUI类似OnPress,OnClick等事件,那么你需要做的是附加UICamera脚本到你的Main Camera上。


NGUI回调函数(NGUI中的事件不止适用于UI,还适用于带有碰撞器的GameObject):

[csharp] view plain copy
  1. OnHover(isOver)               当鼠标移动到一个碰撞器或者移出一个碰撞器时触发  
  2. OnPress(isDown)               当鼠标按键在一个碰撞器上按下时触发  
  3. OnSelect(selected)            当鼠标按键在他按下的那个对象上松开时触发  
  4. OnClick()                     和OnSelect的触发条件一样,还能通过额外检查鼠标是否还没移开。UICamera.currentTouchID告诉你按下了哪个按钮。  
  5. OnDoubleClick()               当在一个短时间内点击两次的时候触发。UICamera.currentTouchID告诉你点下了哪个按钮。  
  6. OnDragStart()                 在发送OnDrag()通知之前触发  
  7. OnDrag(delta)                 发送到正在被拖动的对象  
  8. OnDragOver(draggedObject)     发送给一个对象,当另一个对象被拖到它的区域时  
  9. OnDragOut(draggedObject)      发送给一个对象,当另一个对象被拖出它的区域时  
  10. OnDragEnd()                   当拖动事件结束时被发送到一个dragged对象  
  11. OnInput(text)                 当输入的时候触发(在通过点击选择一个碰撞器之后)  
  12. OnTooltip(show)               当鼠标滑过一个collider而且一段时间没移开的时候  
  13. OnKey(KeyCode key)            当按下键盘或控制器的输入  

即要触发NGUI中的事件,需要满足两个条件:

1.物体带有碰撞器

2.照射该物体的相机要挂上UICamera.cs



UI Text List:文本的滑动列表,内容只能通过程序添加

UI Drag Object:使物体可以被拖拽

UI Darg Resize:可以改变拖拽物体的大小


二、功能

0.

播放tween动画:tween的组件.playforward()

下拉菜单中文值的处理:string.trim()

获取当前组件:组件.current

逐字显示:Typewriter Effect



1.滚动视图

a.创建一个Panel,然后创建一个子Scroll View,以及创建一个子Sprite作为背景。

Scroll View绑了两个组件:UIPanel和UIScrollView。其中UIPanel的Clipping被设置为了SoftClip,起到了裁剪的作用;而UIScrollView则是对滚动效果的设置,但此时视图还不能滑动。

b.将内容放在Scroll View下,为背景添加UI Drag Scroll View(并为其ScrollView变量赋值)和Box Collider(注意设置大小)





2.页签

页签和这个单选框功能的区别就是,页签中包含有要显示的内容。当切换开关时,不但要自动将其他开关关闭,并且还要将当前选中的开关所包含的内容显示出来。

在制作页签时,先使用Toggle制作一系列同组的开关(单选框),然后为每一个开关再增加一个ToggleObjects组件,通过ToggleObjects组件来设定每个开关包含的内容。



3.背包系统
物品拖拽:自定义脚本,去继承UIDragDropItem,重写OnDragDropRelease,注意作为接收物品的格子,要有碰撞器;当然,也可以为物品绑定OnDrag事件。


4.Hud

[csharp] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class NewBehaviourScript : MonoBehaviour {  
  5.   
  6.     public Transform bloodTra;  
  7.     public Transform headTra;  
  8.     public Camera uiCamera;  
  9.   
  10.     private float dis;  
  11.   
  12.     void Start()  
  13.     {  
  14.         dis = Vector3.Distance(headTra.position, Camera.main.transform.position);  
  15.     }  
  16.   
  17.     void Update ()  
  18.     {  
  19.         bloodTra.position = CalculatePos();  
  20.         bloodTra.localScale = CalculateSca();  
  21.     }  
  22.   
  23.     Vector3 CalculatePos()  
  24.     {  
  25.         Vector3 a = Camera.main.WorldToScreenPoint(headTra.position);  
  26.         Vector3 b = uiCamera.ScreenToWorldPoint(a);  
  27.         b.z = 0;  
  28.         return b;  
  29.     }  
  30.   
  31.     //根据距离进行缩放  
  32.     Vector3 CalculateSca()  
  33.     {  
  34.         float a = dis / Vector3.Distance(headTra.position, Camera.main.transform.position);  
  35.         return Vector3.one * a;  
  36.     }  
  37.   
  38. }  


5.判断是否点击到UI

[csharp] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class TestTouch : MonoBehaviour {  
  5.   
  6.     public UILabel label;  
  7.       
  8.     void Update ()   
  9.     {  
  10.         if (Input.GetMouseButtonDown(0) || (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began))  
  11.         {  
  12.             Debug.Log("touch");  
  13.             //需要给UI控件挂上碰撞器  
  14.             if (UICamera.isOverUI)  
  15.                 label.text = "当前触摸在UI上";  
  16.             else  
  17.                 label.text = "当前没有触摸在UI上";  
  18.         }   
  19.     }  
  20. }  

原创粉丝点击