[UnityUI]NGUI备忘录

零、概念

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中所有的事件监听和回调。

using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour {

    public UIButton button;

	void Start () 
    {
        EventDelegate.Add(button.onClick, DebugInfo);
	}
	
    void DebugInfo()
    {
        Debug.Log("按钮被按下");
    }

}

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

using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour {

    public UIButton button;

	void Start () 
    {
        UIEventListener.Get(button.gameObject).onDrag += Drag;
	}

    void Drag(GameObject go, Vector2 delta)
    {
        Debug.Log("拖拽中");
    }

}

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):

OnHover(isOver)               当鼠标移动到一个碰撞器或者移出一个碰撞器时触发
OnPress(isDown)               当鼠标按键在一个碰撞器上按下时触发
OnSelect(selected)            当鼠标按键在他按下的那个对象上松开时触发
OnClick()                     和OnSelect的触发条件一样,还能通过额外检查鼠标是否还没移开。UICamera.currentTouchID告诉你按下了哪个按钮。
OnDoubleClick()               当在一个短时间内点击两次的时候触发。UICamera.currentTouchID告诉你点下了哪个按钮。
OnDragStart()                 在发送OnDrag()通知之前触发
OnDrag(delta)                 发送到正在被拖动的对象
OnDragOver(draggedObject)     发送给一个对象,当另一个对象被拖到它的区域时
OnDragOut(draggedObject)      发送给一个对象,当另一个对象被拖出它的区域时
OnDragEnd()                   当拖动事件结束时被发送到一个dragged对象
OnInput(text)                 当输入的时候触发(在通过点击选择一个碰撞器之后)
OnTooltip(show)               当鼠标滑过一个collider而且一段时间没移开的时候
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

using UnityEngine;
using System.Collections;

public class NewBehaviourScript : MonoBehaviour {

    public Transform bloodTra;
    public Transform headTra;
    public Camera uiCamera;

    private float dis;

    void Start()
    {
        dis = Vector3.Distance(headTra.position, Camera.main.transform.position);
    }

	void Update ()
    {
        bloodTra.position = CalculatePos();
        bloodTra.localScale = CalculateSca();
	}

    Vector3 CalculatePos()
    {
        Vector3 a = Camera.main.WorldToScreenPoint(headTra.position);
        Vector3 b = uiCamera.ScreenToWorldPoint(a);
        b.z = 0;
        return b;
    }

    //根据距离进行缩放
    Vector3 CalculateSca()
    {
        float a = dis / Vector3.Distance(headTra.position, Camera.main.transform.position);
        return Vector3.one * a;
    }

}


5.判断是否点击到UI

using UnityEngine;
using System.Collections;

public class TestTouch : MonoBehaviour {

    public UILabel label;
    
	void Update () 
    {
        if (Input.GetMouseButtonDown(0) || (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began))
        {
            Debug.Log("touch");
            //需要给UI控件挂上碰撞器
            if (UICamera.isOverUI)
                label.text = "当前触摸在UI上";
            else
                label.text = "当前没有触摸在UI上";
        } 
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值