UGUI技巧

http://www.cnblogs.com/suoluo/p/5427514.html

 

  • Text中的可以单独指定某些文字的颜色,只需将想要变色的文本放在<color=**></color>之间即可,如“吃<color=#ff7a38>橙色物品</color>有机会获得<color=red>红色宝石</color>”,同样适用于NGUI。
  • 两张图片,如头像框,头像在背景图之上,头像会挡住背景的点击事件,要实现全框的点击效果,只需要将头像作为背景的子物体就可以了。当然头像上不能有Button组件。
  • 自带的CanvasGroup组件可以实现屏蔽其下所有UI的点击等事件触发,也可以实现整休改变所有子UI的alpha透明度。
  • RectMask2D,类似Mask,但:

    the limitations of RectMask2D control are:

    • It only works in 2D space
    • It will not properly mask elements that are not coplanar

    The advantages of RectMask2D are:

    • It does not use the stencil buffer
    • No extra draw calls
    • No material changes
    • Fast performance
  •  Content Size Fitter组件:自动改变RectTransfrom的size大小。如Text根据文字内容的长短自动缩放控件本身的大小,如一个ScrollRect下的Grid中的元素超时Rect时拖动无效的原因便是Grid未加上该组件它自身的大小未跟随元素的增多而增大。
    注意自动变化宽高时的方向是根据Pivot的设置,若Pivot在中心时则会上下左右同时都会有缩放,若Pivot在顶部时则大小只会从底部放大或缩小。

  • Grid的使用:若元素(子物体)是大小一样的则优先使用Grid Layout Group组件;若元素是大小不一的则选用Horizontal/Vertical layout Group并配合Layout Element组件。
    通过灵活组合ScrollRect、ContentSizeFitter、GridLayoutGroup、HorizontalLayoutGroup/VerticalLayoutGroup、LayoutElement、可以实现很复杂的动态增删组合UI效果。
    详见UGUI Auto Layout 自动布局http://www.manew.com/thread-95758-1-1.html

  • RectTransform的大小改变时有一个回调函数:OnRectTransformDimensionsChange。当ContentSizeFitter来自动调整RectTransform的大小时并不能立马生效,而是需要到下一帧才能得到正确的大小,此时该回调便有用武之地了。然而该回调的触发确有点奇怪会被触发多次且有时触发的次数还不同,另一解决办法是在获取RectTransform的size时调用LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);不过该接口要5.x版本才能用....

  • RectTransform的几个API说明:
    * public void GetLocalCorners(Vector3[] fourCornersArray):传入4个长度的Vector3数组,得到该RectTransform从左下开始到右下的四个角在父物体下的局部坐标。该坐标与该物体及父物体的中心点及锚点有关,经测试即将该RectTransform的anchoredPosition设置为0(父物体的0位置下)时四个角所在位置。
    * public void GetWorldCorners(Vector3[] fourCornersArray):得到该RectTransform的四个角的世界坐标,不用关心当前及父对象的中心点及锚点的设置。
    * public void SetSizeWithCurrentAnchors(Axis axis, float size):设置RectTransform的宽或高,可以不用关心当前及父对象的中心点及锚点的情况而直接设置宽高。当anchor的四角合一时该函数便跟设置sizeDelta效果一样。
    * public void SetInsetAndSizeFromParentEdge(Edge edge, float inset, float size):设置RectTransform相对父物体的某一边缘的距离和宽高,同样可以不关心当前及父对象的中心点及锚点的情况而直接设置位置和宽高。edge父物体的上下左右某一边,inset为到edge边的距离,size为要将RectTransform设置的宽度或高度,当edge为左右时size为宽度,当edge为上下时size为高度。注意该函数会根据edge改变RectTransform的anchor。
    如:rectTrans.SetInsetAndSizeFromParentEdge (RectTransform.Edge.Top, 200, 400);rt.SetInsetAndSizeFromParentEdge (RectTransform.Edge.Left, 100, 300);该两次调用后rectTrans的高为400,上边距离父物体的上边为200,宽为300,左边距离父物体的左边为100。

  • 当UI和ParticleSystem特效混用时会出现类似NGUI中特效与UI显示层级混乱的问题,如一个特效想要显示在两个UI之间或者一个UI的前面和后面各有一个特效时:
    首先Canvas不能为Overlay,需要指定Camera。
    然后UI1的Canvas的OrderInLayer为1,UI2的Canvas的OrderInLayer为3(可多个Canvas嵌套使用),Particle所在的Canvas的OrderInLayer为2。
    正常认为Particle应该位于两个UI之间了,然而由于Particle默认是位于0层,通过设置之上的Canvas的层是不起作用的,故特效仍显示不了。(针对半透明3D物体(放在Transparent队列),在渲染上是关闭了ZWrite的(使用了Blend就会自动设置ZWrite Off),因此Unity采用了一种简单的手段,将其强制放在缺省的Default Layer的Order in Layer(0)渲染(因此,对其挂Canvas是徒劳的))
    办法1:由于Particle为0层,则让需要显示Particle之下的UI层设置为小于0的负数层级,显示在Particle之上的UI则设置为大于0的层级数。这样做有个问题是当同时有多个Particle,有的要显示在UI之上有的要显示在之下,即Particle需要位于不同层级时有问题。
    办法2:设置Particle的层,在5.3版之后Particle本身Renderer可以直接设置层,但旧版本不行,增加脚本:
    复制代码
     1 public class SetOrder : MonoBehaviour
     2 {
     3     public int order;
     4 
     5     void Awake ()
     6     {
     7         Renderer[] renderers = GetComponentsInChildren<Renderer> ();
     8         for (int i = 0; i < renderers.Length; i++)
     9         {
    10             renderers[i].sortingOrder = order;
    11         }
    12     }
    13 }
    复制代码

    将需要设置Particle层的物体上挂上该脚本即可设置Particle的层了,如此各UI及特效都能自由设置层级关系了。同时多个Particle也可指定为同一个层级然后在代码中设置renderer.material.renderQueue应该也是能调整特效之间的显示层级的,未测试亲可自测。

  • UGUI的Mask组件对Particle不起作用,解决办法:
    创建两个Shader,一个给粒子用,一个给UI Mask 用,两个Shader的内容均采用Build-in Shader的Particle-Additive 和 UI-Default。利用Shader 的 Stencil 功能, 分别对两个Shader加入以下内容:
    //UI Mask 
    Stencil
    {
    Ref 1
    Comp Always
    Pass Replace
    }
    //Paritcle
    Stencil {
    Ref 1
    Comp equal
    }
    之后分别创建相应材质球,将其赋予UIImage 和 想被遮罩的 Particle 即可。 如果看不见效果,调整一下Particle的位置。原文在评论区:http://www.xuanyusong.com/archives/3518
  • 代码中主动调用UI事件以模拟点击按钮等操作:
    1 ExecuteEvents.Execute<IPointerClickHandler>(uiButton.gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.pointerClickHandler);
    2 ExecuteEvents.Execute<ISubmitHandler>(uiButton.gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.submitHandler);
  • 当按钮图片延Y轴旋转180度(即背面在前,镜像翻转)时,按钮点击功能失效!同理推论所有UI元素只要背面在前时其点击等所有事件都会失效。不明白为何UGUI要如此设计,当有两控件只是左右相反时想要共用一张图就会出该问题。解决办法是将点击区域和图片分离,在图片上层放置一个透明图片作为实际按钮,按钮的Target Graphic设置为翻转后的图片即可。
posted @ 2017-11-02 17:47  alps_01  阅读(492)  评论(0编辑  收藏  举报