精华内容
参与话题
问答
  • FairyGUI 教程

    2019-07-06 14:36:57
    近期公司项目中的UI部分使用的是FairyGUIFairyGUI作为第三方插件,它弥补了UGUI中的不足,尤其在UI优化,资源和代码分离这块做的非常好,UI在游戏中经常需要更换,FairyGUI更换UI非常方便。UI自适应这块做的也非常...
  • FairyGUI基本操作和功能实现

    千次阅读 2018-06-01 15:40:51
    fairyGUI界面控件的基本制作和功能实现1.学习地址:官网和泰课在线fairyGUI官网: http://www.fairygui.com/tutorial泰课在线: http://www.taikr.com/cloud/search?q=fairyGUI2.按钮 一般按钮有4个态:(点开按钮...

    fairyGUI界面控件的基本制作和功能实现

    一般按钮有4个态:(点开按钮模块可查看)up/down/over/selectedOver


    按钮的示例代码

    private GButtonbtn_helmet;

    btn_helmet = this.ui.GetChild("btn_helmet")as GButton;

    btn_helmet.onClick.Set((EventContextcontext) =>  {//按钮点击事件添加});

    常用事件:

    onRightClick:右键点击事件

    onRollOver:鼠标悬停事件

    onRollOut:鼠标悬停移出事件

    onDragStart:拖拽事件


    鼠标拖拽cell1按钮的图标至按钮cell上松开鼠标的相应事件:onDrop()



    3遮罩

    问题:遮罩会挡住当前组件的其他图片文本,导致想要实现遮罩外部的图片部分被挡住。

    方案:遮罩需要遮住的部分单独做成一个组件,再放入主组件中


    4.动画和动效

    动画的创建:

    多选要用来制作动画的图片,再点击左上方动画创建按钮       。

    代码调用:

    GMovieClip movie = ui.GetChild("movie").asMovieClip;

    // 从start帧开始,播放到end帧(-1表示结尾),重复times次(0表示无限循环),循环结束后,停止在endAt帧(-1表示参数end

    movie.SetPlaySettings(0,-1,1,-1);


    动效的编辑:

    1.选中动效后出现动效编辑界面

    2.鼠标右键点击出现可编辑选项

    3.选中改变动画用于控制动画播放

      

    动效的调用:

    private Transition t1;

    t1 = ui.GetTransition("t1");

    t1.Play((=>{//动效结束后的回调}));


    5.控制器

    控制器的创建:

    在控制器栏点击         ,控制器也可以与组配合使用


    代码调用:

    private Controller c1;

    c1 = this.ui.GetController("c1");

           c1.selectedIndex = 1;

    //还可以用DOTween.To实现控制器由起始序号到指定序号


    6.普通列表


    代码调用:

    GListlist1 = obj.GetChild("list1").asList;

    list1.RemoveChildrenToPool();

    for (int i = 0; i < cnt; i++)

    {

    GButton item = list1.AddItemFromPool().asButton;

    item.GetChild("t0").text = "" +(i+1);

    }


    7.虚拟列表

    代码调用:

    _list = _mainView.GetChild("mailList").asList;

    _list.SetVirtual();

    //itemRenderer , Callback functionwhen an item is needed to update its look

    _list.itemRenderer = RenderListItem;

    _list.numItems = 1000;

    void RenderListItem(intindex, GObject obj)

    {

    //MailItem继承Gbutton。列表的内容

    MailItem item = (MailItem)obj; 

    item.title =index + " Mail title here";

    }

    /// <summary>

    /// Callback function when an item is needed to update its look.

    /// </summary>

    /// <param name="index">Item index.</param>

    /// <param name="item">Item object.</param>

    public delegate void ListItemRenderer(int index, GObject item);


    8.虚拟循环列表

    代码调用:

    _list = _mainView.GetChild("list").asList;

    _list.SetVirtualAndLoop();

    _list.itemRenderer= RenderListItem;  

    _list.numItems= 5;

    //鼠标滚轮滚动的时候实现中间放大的特效

    _list.scrollPane.onScroll.Add(DoSpecialEffect);

    //根据到中心点的距离改变列表项的大小缩放

    void DoSpecialEffect()

    {

     float midX= _list.scrollPane.posX + _list.viewWidth / 2;

      intcnt= _list.numChildren;         //子项数量从0开始计算

     for (int i = 0; i < cnt; i++)

      {

        GObject obj = _list.GetChildAt(i);

        float dist = Mathf.Abs(midX - obj.x - obj.width / 2);

        if (dist > obj.width) //nointersection 列表项与中心没有交集

          obj.SetScale(1,1);

       else

       {

         float ss= 1 + (1 - dist / obj.width) * 0.24f; //有交集。越往中心越大。

        obj.SetScale(ss, ss);

      }

     }

    // _list.numItems子项数量从1开始计算

    _mainView.GetChild("n3").text = "" +((_list.GetFirstChildInView() + 1) % _list.numItems);

    }


    8.3D界面

    2D界面不同在于设置3D世界坐标:

    //设置层级

    this.SetWindow3DShell(MySelf.Inst.MySceneObject.transform);

    this.SetScale(newVector3(0.0022f, 0.0022f, 0.0022f));

    this.SetLocalPosition(newVector3(0, 0, 0.4f));

    this.SetLocalRotation(newVector3(0, 180, 0));        


    9.图形

    注意图形在不同平台的兼容性,例如圆角和圆形在某些平台是暂时未支持的。
    图形的类型选择为空白时,可以作为占位的用途,这种图形不消耗显示资源



    10.加载3D模型


    举例:

            现在要在UI中放置入一个原生的对象aSprite,则可以在适当位置放入一个空白的图形,假设对象为holder,那么代码里可以这样写:holder.setNativeObject(aSprite),这样就把aSprite放到了holder所在的位置和深度上。

    加载3D模型:

            注意图形不能设置为空白。图形的中心为加载的模型的中心点坐标。


    相关代码:

     _holder.SetNativeObject(newGoWrapper(model));

    model.transform.localPosition = new Vector3(0, 0, 0);

    model.transform.localEulerAngles= new Vector3(0, 180, 0);

    model.transform.localScale = new Vector3(380, 380, 380);

    model.SetGameObjectLayer(LayerMask.NameToLayer("layer_editobj"));


    展开全文
  • FairyGUI 与 Unity 简单入门

    千次阅读 2019-05-23 19:15:51
    最近新项目要使用FairyGUI,好处是方便美术那边拼UI界面给程序这边用。所以对FairyGUI进行了一些简单的了解和试手,官网上也有详细的示例和文档:http://www.fairygui.com/guide/ 本文主要纪录了一个简单的FairyGUI...

    最近新项目要使用FairyGUI,好处是方便美术那边拼UI界面给程序这边用。所以对FairyGUI进行了一些简单的了解和试手,官网上也有详细的示例和文档:http://www.fairygui.com/guide/

    本文主要纪录了一个简单的FairyGUI导出到Unity并在Unity上显示UI界面的过程。本demo简单的绘制了一个登陆界面的UI,如图(丑是丑了点!):

     

    准备工作

    首先下载好编辑器FairyGUI Editor以及对应的unity SDK。下载链接

    然后在unity工程中导入下载好的package包,同时创建一个Resources目录用于存放FairyGUI导出的文件(当然后期需要使用AB包的方式来读取导出文件,这边就不做拓展了)。

     

    绘制UI

    分析

    如图所示,可以分解为两个输入框,两个按钮和若干个文本框。考虑到后期维护,我们可以把例如按钮输入框这种常用的组件放置在一个公共包中(FairyGUI是以包为单位组织资源),供外部的其他包使用(除了公共包,其他包相互之间尽量不发生引用关系)。

    然后再一个新包里面放置我们要绘制的UI界面(研究的还不够深入,目前的想法是一个系统一个包,例如背包系统,商城系统,个人信息系统等。每个包里包含若干个UI界面)

     

    绘制公共组件

    我们打开编辑器创建一个新的空工程,然后创建一个新的包CommonPackage

    按钮

    创建好CommonPackage后,我们可以先从外部拖动一些要使用到的图片资源到这个目录下,用于做按钮的背景图,然后我们在上方工具栏 资源->新建按钮,创建一个公用的按钮ConfirmBtn,如图

    具体的一些设置这里就不累赘了,官方文档里面讲解的很详细。同时再制作一个CancelBtn,做取消按钮。

    输入框

    接着我们要制作一个输入框,根据文档我们知道,当文本组件的属性设置为输入文本的时候,该文本可以变成一个输入框。

    但是只是一个简单的文本组件,是没有边框背景色等属性。因此我们需要对其优化一下下。

    首先我们新建一个组件Input,大小为200*40。为其添加一个同等大小的 "图形",用于做输入框的底图和边框。然后再添加一个"文本",设置为输入文本,作为输入框,如图

    此时还存在一个问题,就是当组件缩放的时候,组件和文本的大小并不会跟着缩放,因此我们要为其添加关联。

    容器组件即为父控件,含义类似于,高度和宽度保持和父控件一致,这样我们就可以随意的缩放Input了。关联有很多的选项,详情请见关联系统

    设置导出

    最后我们要将新建的三个组件ConfirmBtn,CancelBtn,Input,右键->设置为导出,否则的话,当将其拖到其他包的UI使用时,会提示"无法拖入其他包的未导出资源"的错误。(图片资源不用设置导出,即使发布的时候,也会自动生成导出)

     

    绘制界面

    首先新建一个包LoginPackage,添加背景图,然后创建一个组件LoginPanel,大小为960*540。首先将资源目录中的背景图直接拖到组件中,记得要设置关联属性,使背景图可以自适应。然后将CommonPackage包中的按钮输入框直接拖进去,然后添加一些文本等等即可。

     

    发布

    UI都做好之后,点击工具栏的 文件->发布设置,编辑全局设置中,路径选择我们的Unity工程的Resources目录,点击全部发布即可(不用生成代码)。生成的文件如下:

    _fui.byte文件及每个包对应的发布文件,_atlas0为按钮的两张背景图的图集,_atlas_ko9o1为界面的背景图。优化策略为,UI的一些小图,设置到图集当中,背景等大图单独导出。“单独(NPOT)”表示这张图片按原大小直接输出。注意:在Unity中,非2的幂大小的纹理不支持压缩格式,只能为RGBA或RGBA。详情见文档

     

    Unity展示

    首先在场景中创建一个GameObject,命名为UIRoot,Layer选UI,Position为(0,0,0),为其添加组件UIContentScaler用于适配,如图

    然后新建一个脚本Launch.cs,挂在UIRoot上

    using FairyGUI;
    using UnityEngine;
    
    public class Launch : MonoBehaviour
    {
        GComponent m_root;
        GTextInput m_inputAccount;
        GTextInput m_inputPwd;
        GButton m_confirmBtn;
        GButton m_cancelBtn;
    
        void Start()
        {
            //加载包
            UIPackage.AddPackage("CommonPackage");
            UIPackage.AddPackage("LoginPackage");
    
            //创建UIPanel
            UIPanel panel = gameObject.AddComponent<UIPanel>();
            panel.packageName = "LoginPackage";
            panel.componentName = "LoginPanel";
            //设置renderMode的方式
            panel.container.renderMode = RenderMode.ScreenSpaceOverlay;
            //设置fairyBatching的方式
            panel.container.fairyBatching = true;
            //设置sortingOrder的方式
            panel.SetSortingOrder(1, true);
            //设置hitTestMode的方式
            panel.SetHitTestMode(HitTestMode.Default);
            panel.fitScreen = FitScreen.FitSize;
            //最后,创建出UI
            panel.CreateUI();
    
            //根据FairyGUI中设置的名称找到对应的组件(注意输入框的查找)
            m_root = panel.ui;
            m_inputAccount = m_root.GetChild("InputAccount").asCom.GetChild("Input").asTextInput;
            m_inputPwd = m_root.GetChild("InputPwd").asCom.GetChild("Input").asTextInput;
            m_confirmBtn = m_root.GetChild("ConfirmBtn").asButton;
            m_cancelBtn = m_root.GetChild("CancelBtn").asButton;
    
            //密码框显示*号
            m_inputPwd.displayAsPassword = true;
    
            //添加点击事件
            m_confirmBtn.onClick.Add(OnClickConfirm);
        }
    
        void OnClickConfirm()
        {
            Debug.Log("account:" + m_inputAccount.text + "     pwd:" + m_inputPwd.text);
        }
    }
    

    因为创建UIPanel的时候,FairyGUI会自动创建一个Stage Camera用于渲染UI界面。所以我们将原场景的Main Camera删除,或者剔除UI层的渲染。

    大功告成,运行即可!

     

    展开全文
  • FairyGUI学习摘录

    千次阅读 2017-01-04 21:35:18
    素材管理 可以直接将图片(Gif)、声音(mp3)、动画、文字等素材从资源浏览器拖动到库中。 资源Url UIPackage.getItemURL(“包名“,“资源名”) AudioClip clip = (AudioClip)UIPackage.GetItemAsset(“包名称”,...

    素材管理
    可以直接将图片(Gif)、声音(mp3)、动画、文字等素材从资源浏览器拖动到库中。
    资源Url

    UIPackage.getItemURL(“包名“,“资源名”)
    AudioClip clip = (AudioClip)UIPackage.GetItemAsset(“包名称”,”声音名称”);

    菜单”编辑”->“创建位图字体”,(输入字符,显示对应图片)
    多信息文本(GRichTextField)支持链接和图文混排。
    用例: aTextField.text = “请去找王大锤abcdefgh’”;

    列表 (GList)
    AddChild : 增加一个项目。
    AddChildAt :在指定的位置增加一个项目。
    RemoveChild : 删除一个项目。
    RemoveChildAt : 删除一个指定位置的项目。
    RemoveChildren : 删除一个范围内的项目,或者全部删除。
    GList内建了对象池。
    使用对象池后的方法:
    AddItemFromPool : 从池里取出(如果有)或者新建一个对象,添加到列表中
    GetFromPool : 从池里取出(如果有)或者新建一个对象
    ReturnToPool : 将对象返回池里
    RemoveChildToPool : 删除一个列表项目,并将对象返回池里
    RemoveChildToPoolAt : 删除一个指定位置的项目,并将对象返回池里
    RemoveChildrenToPool:删除一个范围内的项目,或者全部删除,并将删除的对象都返回池里
    添加对象时不使用池,对象池将不断增大。
    正确的做法:从池中创建对象。即使用AddItemFromPool或GetFromPool。

    虚拟列表 GList.SetVirtual
    使用GList.numItems设定列表项目的数量。注意与GList.numChildren区分,后者是当前列表容器的显示对象数量。
    但要注意显示对象和列表项目的数量在数量上和顺序上都是不一致的,也就是GetChildAt(0)获得的显示对象并不等于列表的第一条项目。
    列表滚动到目标位置(第500个),调用GList.AddSelection(500)
    虚拟列表只能通过numItems改变列表项目的数量,不允许使用AddChild或RemoveChild增删对象。例如如果要清空列表,必须要通过设置numItems=0,而不是RemoveChildren。
    循环列表 GList.SetVirtualAndLoop()。

    GList.ensureBoundsCorrect()通知GList立刻重排。(手动触发重新排列)

    装载器 GLoader
    运行时设置装载器内容的方式是:
    aLoader.url = “ui://xxxxx”;
    aLoader.url = “demo/aimage”; //这里加载的是路径为Assets/Resources/demo/aimage的一个贴图
    例如,你希望从AssetBundle中获取资源,那么你可以扩展GLoader。首先编写你的Loader类,例如:

    这是一个egret中使用到的自定义loader,使用getResByUrl这个API加载外部资源。
    然后我们就可以用fairygui.UIObjectFactory.setLoaderExtension(MyGLoader);注册我们要使用的Loader类。注册完成后,游戏中所有装载器都是由MyGLoader实例化产生。
    组件
    点击穿透 默认情况下,组件的矩形区域将拦截点击,勾选后,点击事件可以穿透组件中没有内容的空白区域。
    控制器 Controller
    Controller c1 = aComponent.GetController(“c1”)
    c1.selectedIndex = 1;//1是页面索引

    c1.selectedPage = ‘pageName’;//pageName就是页面名称

    说明:
    对所有参与的页面,元件将分别保存不同的坐标值;对所有没有参与的页面,元件将保存同一个坐标值。
    缓动功能 (位移的插值?)
    按钮控制器 Button
    单选组(RadioGroup)
    在程序中,要获得或设置哪个按钮被选中也非常简单,使用控制器的selectedIndex或者selectedPage就可以了。

    设置关联 ( 类似锚点,相对位置的设置 )

    这里有一个垂直中线的关联,下面会说明,暂且不表。置可以看到,在文本内容发生变化时,文本的中线位置没有发生变化,位所以问号图标的置不变;但文本的右侧位发生了变化,所以叹号图标随之发生了移动,保持了与文本右侧的距离。
    在代码中设置关联
    (比如浏览器窗口被玩家拖大拖小),组件依然保持在右侧位置,那么可以这样调用:
    aComoponet.addRelation(GRoot.inst, RelationType.Right_Right);

    又例如希望一个动态添加到舞台的组件始终保持满屏大小,可以这样调用
    aComoponet.setSize(GRoot.inst.width, GRoot.inst.height);
    aComoponet.addRelation(GRoot.inst, RelationType.Size);

    RelationType.Size相当于RelationType.Width_Width和RelationType.Height_Height的组合。这里强调一下,使组件变为满屏大小这个操作必须由你完成,也就是上面代码中的setSize调用。关联并不能完整这项任务,因为关联是不管元件当前的大小的,它只会在目标变化时保持两者大小的差别。

    A:和容器组件”垂直中线“关联
    B:和容器组件”右->右”关联
    C:和容器组件“右->右”,”底->底“关联
    D:和容器组件”底->底”,“垂直中线%”关联
    E:和容器组件“底->底”关联
    然后运行时把这个界面设置为满屏就可以了。
    aComponent.SetSize(GRoot.inst.width, GRoot.inst.height);
    aComoponet.addRelation(GRoot.inst, RelationType.Size);//当屏幕改变时仍然保持全屏

    FairyGUI教程:(九)组件的扩展
    FairyGUI提供的控件有:
    图片(GImage)、动画(GMovieClip)、图形(GGraph)、文本(GTextField)、多信息文本(GRichTextFIeld)、列表(GList)、装载器(GLoader)、组件(GComponent)。这些都是非常基础的控件,他们是UI制作中的最小粒度。但仅靠这些基础控件是不足以制作出各种复杂的UI界面的。我们通过”扩展“功能,从组件(GComponent)中扩展出来以下这些复合组件:按钮(GButton),标签(GLabel),下拉框(GComboBox),进度条(GProgressBar),滑动条(GSlider),滚动条(GScrollbar)。

    可以看到有六种“扩展”选择。组件可以随意在这些“扩展”中切换。选择哪种“扩展”,组件就有了哪个扩展的属性和行为特性。
    指定统一点击音效
    如果希望游戏中所有按钮的点击都有声音反馈,你并不需要每个按钮都设置一次声音属性,因为在游戏中可以使用代码UIConfig.buttonSound=’xxx’为所有按钮设置一个点击声音。
    滚动条
    运行时使用的滚动条需要通过以下代码设置:
    UIConfig.horizontalScrollBar = ‘xxx’;
    UIConfig.verticalScrollBar = ‘yyy’;
    这里xxx和yyy就是滚动条资源的url。
    UIConfig.defaultScrollBarDisplay = ScrollBarDisplayType.Auto; // 设置为,滚动时显示滚动条

    9、自定义扩展
    当基础组件、扩展组件都不能满足你的需求时,你可以编写自定义的扩展。使用API UIObjectFactory.setPackageItemExtension完成定义。例如:
    UIObjectFactory.setPackageItemExtension(UIPackage.getItemURL(“包名“,”组件A”), MyComponent );
    public class MyComponent extends GComponent
    {
    override protected function constructFromXML(xml:XML):void
    {
    super.constructFromXML(xml);
    //在这里继续你的初始化
    }
    }
    这样就为组件A指定了一个实现类MyComponent 。以后所有组件A创建出来的对象(包括在编辑器里使用的组件A)都为MyComponent 类型。例如:
    var obj:MyComponent = UIPackage.createObject(“包名“, ”组件A”) as MyComponent ;
    注意:如果组件A只是一个普通的组件,没有定义“扩展”,那么基类是GComponent,如上例所示;如果组件A的扩展是按钮,那么MyComponent的基类应该为GButton,如果扩展是进度条,那么基类应该为GProgressBar,等等。这个不要弄错。

    控制器Tween效果
    动效的播放在代码中启动,例如:
    someComponent.GetTransition(“peng”).Play();
    Play有多种原型,例如可以重复播放一定次数,可以在播放结束时回调等。要中途停止动效的播放,可以调用:
    someComponent.GetTransition(“peng”).Stop();
    Stop方法也可以带参数,原型是
    public void Stop(bool setToComplete, bool processCallback);
    setToComplete表示是否将组件的状态设置到播放完成的状态,如果否,组件的状态就会停留在当前时间。processCallback是否调用Play设定的播放完成回调函数。

    注意:UI动效播放完毕后,组件的状态将停留在最后一帧,而不是回到第一帧,如果你希望动效播放完后组件的状态复原到播放前,你可以最后添加一帧重新设置组件的状态。

    高级用法:
    public void SetValue(string label, params object[] aParams)
    改变指定帧的数值,例如某帧Label为aa,这帧是设置某个元件的XY值的,那么调用setValue(aa, 100,200)就可以将原来此帧设置XY的数值改为100,200。
    public void SetHook(string label, TransitionHook callback)
    可以设定运行到某帧时发生一个调用。

    多国语言支持
    2、运行时动态加载语言文件。这种方法相对比较灵活。
    Unity代码片段:
    string fileContent; //自行载入语言文件,这里假设已载入到此变量
    FairyGUI.Utils.XML xml = new FairyGUI.Utils.XML(fileContent);
    UIPackage.SetStringsSource(xml);

    (十二)UI适配策略 (分辨率 设置)
    GRoot.inst.setContentScaleFactor(设计分辨率宽度,设计分辨率高度,适配策略);
    someComponent.setSize(GRoot.inst.width, GRoot.inst.height);// 满屏

    GRoot是FairyGUI的根组件,它的大小与屏幕分辨率的关系为
    GRoot.inst.width = 屏幕宽度/GRoot.contentScaleFactor;
    GRoot.inst.height = 屏幕高度/GRoot.contentScaleFactor;

    (十三)显示架构API
    FairyGUI在原生的渲染引擎上封装了一层显示对象结构。
    基础类显示对象:
    GObject:显示对象的基类。
    GGraph:图形对象。对应于编辑器中显示的一个图形。
    GImage:图片对象。对应于编辑器中显示的一个图片。
    GMovieClip:动画对象。对应于编辑器中显示的一个动画。
    GLoader:装载器对象。对应于编辑器中显示的一个装载器。
    GTextField:文本对象。对应于编辑器中显示的一个文本。
    GRichTextField:多媒体文本。对应于编辑器中显示的一个多媒体文本。
    GTextInput:输入文本对象。对应于编辑器中显示的一个文本,且文本类型被设置为“输入”。
    容器类显示对象:
    GComponent:组件对象。对应于编辑器中创建的一个组件。
    GList:列表对象。对应于编辑器中显示的一个列表。
    容器的扩展:
    GLabel:标签对象。当一个组件的扩展为“标签”时,即为此类型。
    GButton:按钮对象。当一个组件的扩展为“按钮”时,即为此类型。
    GComboBox:组合框对象。当一个组件的扩展为“组合框”时,即为此类型。
    GScrollBar:滚动条对象。当一个组件的扩展为“滚动条”时,即为此类型。
    GProgressBar:进度条对象。当一个组件的扩展为“进度条”时,即为此类型。
    GSlider:滑动条对象。当一个组件的扩展为“滑动条”时,即为此类型。
    FairyGUI和Flash/Cocos类似,采用树状的结构组织显示对象。容器可以包含一个或多个基础显示对象,也可以包含容器。这个树状结构称为显示列表。如下图:

    处于最前面的且元件范围包含点击位置的元件将捕获鼠标或触摸事件,并且开始冒泡传递(请参考事件系统 Flash/Starling/Egret/Unity)
    对于组件(GComponent),宽度x高度的范围内点击检测都是有效的,无论这个范围内是否有子元件。举个例子说明。组件A和组件B分别为:

    将B先添加进舞台,然后再添加A到舞台,也就是说,A显示B的前面,效果如下图:

    可以看到,虽然A在B的上面,但红色方块是可见的,因为A在此区域并没有内容。当点击图中绿色点的位置时,点击事件将在A上面触发,而B是点击不了的。这是因为在A的范围内,点击是不能穿透的。
    如果希望A能被穿透应该怎样?可以通过GComponent.opaque属性设定。当设定为false时,这个组件将能被穿透。例如A.opaque=false,这时,只有点击4个白块时,A才接收到点击事件,如果点击绿色点位置,B将接收到点击事件。这个特性在设计一些全屏界面时尤其要注意。也可以在编辑器里直接设定:

    滚动支持
    你可以在编辑器里很方便的对一个组件添加滚动特性。如果一个组件在编辑器里设置为滚动,我们可以通过GComponent.scrollPane获得滚动控制对象。
    ScrollPane提供了多个API访问和控制滚动:
    ScrollPane.percX/ScrollPane.percY:获得或设置当前滚动的位置,以百分比来计算,取值范围是0-1。如果希望滚动条从当前值到设置值有一个动态变化的过程,可以使用ScrollPane.setPercX和ScrollPane.setPercY,这两个API提供了一个是否使用缓动的参数。
    ScrollPane.posX/ScrollPane.posY:获得或设置当前滚动的位置,以像素来计算。取值范围决定于当前显示的内容大小与视口大小的差别。例如,一个垂直滚动的组件,如果视口大小为100像素,实际内容大小为300像素,那么posY的取值范围是0~200像素,当posY=200时,滚动条滚动到最下方。posX/posY与percX/percY不同在于,除非开发者自己设置或者用户拖动滚动条,percX/percY是不变的,举个例子,当前某滚动容器的percX=0.1, posX=100,如果往容器里添加一定内容后,内容的宽度增大,percX的值仍将保持不变,依然是0.1,但posX的值会发生相应的改变。所以如果希望容器内增删内容后滚动条不发生滚动,可以先记录posX/posY的位置,添加完之后再设置posX/posY为此前记录的位置。
    ScrollPane.scrollToView:调整滚动位置,使指定的元件出现在视口内。
    窗口系统
    窗口使用前首先要设置窗口中需要显示的内容,这通常是在编辑器里制作好的,可以直接使用Window.contentPane进行设置。建议把设置contentPane等初始化操作放置到Window.onInit方法中。
    另外,FairyGUI还提供了一套机制用于窗口动态创建。动态创建是指初始时仅指定窗口需要使用的资源,等窗口需要显示时才实际开始构建窗口的内容。首先需要在窗口的构造函数中调用Window.addUISource。这个方法需要一个IUISource类型的参数,而IUISource是一个接口,用户需要自行实现载入相关UI包的逻辑。当窗口第一次显示之前,IUISource的加载方法将会被调用,并等待载入完成后才返回执行Window.OnInit,然后窗口才会显示。
    调用Window.show显示窗口的流程:

    如果你需要窗口显示时播放动画效果,那么覆盖doShowAnimation编写你的动画代码,并且在动画结束后调用onShown。
    覆盖onShown编写其他需要在窗口显示时处理的业务逻辑。
    调用Window.hide隐藏窗口的流程:

    如果你需要窗口隐藏时播放动画效果,那么覆盖doHideAnimation编写你的动画代码,并且在动画结束时调用Window.hideImmediately(注意不是直接调用onHide!)。
    覆盖onHide编写其他需要在窗口隐藏时处理的业务逻辑。
    通常窗口会包括一个可用于拖动的标题栏,关闭按钮等。我们在编辑器创建窗口组件时,可以为它创建一个名称为frame的组件,frame组件的扩展应该选择为“标签”,这样外部组件能够为其设置图标和标题属性。frame组件中约定的内容还包括:
    closeButton:一个名称为closeButton的按钮将自动作为窗口的关闭按钮。
    dragArea:一个名称为dragArea的图形(类型设置为空白)将自动作为窗口的检测拖动区域,当用户在此区域内按住并拖动时,窗口随之被拖动。
    contentArea:一个名称为contentArea的图形(类型设置为空白)将作为窗口的主要内容区域,这个区域只用于Window.showModalWait。当调用Window.showModalWait时,窗口会被锁定,如果设定了contentArea,则只锁定contentArea指定的区域,否则锁定整个窗口。如果你希望窗口在modalWait状态下依然能够拖动和关闭,那么就不要让contentArea覆盖标题栏区域。
    注意以上的约定均为可选,是否含有组件frame,或者组件frame里是否含有约定的功能组件,并不会影响窗口的正常显示和关闭。
    Popup管理
    在UI系统中我们经常需要一些弹出一些组件,这些组件在用户点击空白地方的情况下就会自动消失,又或者由开发者控制消失。GRoot提供了几个API管理这些Popup组件。
    GRoot.showPopup:弹出一个组件,如果指定了目标,则会调整弹出的位置到目标的下方,形成一个下拉的效果。同时提供了参数可以用来指定是向上弹出或者向下弹出。
    GRoot.hidePopup: 默认情况下,用户点击空白地方就会自动关闭弹出的组件。也可以调用此API手工关闭。不指定参数时,所有当前的弹出都关闭。
    FairyGUI会根据组件的大小自动计算弹出位置,以确保组件显示不会超出屏幕。

    (十五)事件系统:Unity
    发表回复
    Unity平台参考了Flash的事件机制,设计了自己独特的事件系统。EventDispatcher是事件分发的中心,GObject就是一个EventDispatcher。每个事件类型都对应一个EventListener,接收事件并调用处理函数。例如需要编写某个元件单击的处理逻辑:
    aObject.onClick.Add(aCallback);
    void aCallback()
    {
    //some logic
    }
    事件回调函数
    每个事件可以注册一个或多个回调函数。函数原型为:
    public delegate void EventCallback0();
    public delegate void EventCallback1(EventContext context);
    函数可以不带参数或带一个参数。
    EventContext
    EventContext是回调函数的参数类型。
    EventContext.sender:获得事件的分发者。
    EventContext.initiator:获得事件的发起者。一般来说,事件的分发者和发起者是相同的,但如果事件已发生冒泡,则可能不相同。参考下面冒泡的描述。
    EventContext.type:事件类型。
    EventContext.inputEvent:如果事件是键盘/触摸/鼠标事件,通过访问inputEvent对象可以获得这类事件的相关数据。
    EventContext.data:事件的数据。根据事件不同,可以有不同的含义。
    事件冒泡和事件捕获
    一些特殊的事件,比如鼠标/触摸事件,具备向父组件传递的特性,这个传递过程叫做冒泡。例如当手指接触A元件时,A元件触发TouchBegin事件,然后A元件的父组件B触发TouchBegin事件,然后B的父组件C也触发TouchBegin事件,以此类推,直到舞台根部。这个设计保证了所有关联的显示对象都有机会处理触摸事件,而不只是最顶端的显示对象。
    冒泡过程可以被打断,通过调用EventContext.StopPropagation()可以使冒泡停止向父组件推进。
    从上面的冒泡过程可以看出,事件处理的顺序应该是:A’s listeners->B’s listeners->C’s listeners,这里还有一种机制可以让链路上任意一个对象可以提前处理事件,这就是事件捕获。事件捕获是反向的,例如在上面的例子中,就是C先捕获事件,然后是B,再到A。所以所有事件处理的完整顺序应该是:
    C’s capture listeners->B’s capture listeners->A’s capture listeners->A’s listeners->B’s listeners->C’s listeners
    捕获传递链是不能中止的,冒泡传递链可以通过StopPropagation中止。
    事件捕获的设计可以使父元件优于子元件和孙子元件检查事件。
    并非所有事件都有冒泡设计,请参考下面关于各个事件的说明。并非只有冒泡事件才有捕获设计。在非冒泡事件中,capture的回调优于普通回调,仅此而已,可以作为一个优先级特性来使用。
    InputEvent
    对键盘事件和鼠标/触摸事件,可以通过EventContext.inputEvent获得此类事件的相关数据。InputEvent.x/InputEvent.y:鼠标或手指的位置;这是舞台坐标,因为UI可能因为自适配发生了缩放,所以如果要转成UI元件中的坐标,要使用GObject.GlobalToLocal转换。
    InputEvent.keyCode:按键代码;
    InputEvent.modifiers:参考UnityEngine.EventModifiers。
    InputEvent.mouseWheelDelta:鼠标滚轮滚动值。
    InputEvent.touchId:拖动使用手指;在PC平台,该值为0,没有意义。
    InputEvent.isDoubleClick:是否双击。
    EventListener
    EventListener.Add/EventListener.Remove:添加或删除一个回调,回调函数可以带一个参数或者不带参数。参数的类型是object,它的实际含义随不同事件不同而不同;
    EventListener.AddCapture/EventListener.RemoveCapture:添加或删除一个捕获期回调。
    事件类型
    GObject.onClick:单击。冒泡事件。事件数据为InputEvent对象。
    GObject.onRightClick:右键单击。冒泡事件。事件数据为InputEvent对象。
    GObject.onTouchBegin:鼠标或手指按下。冒泡事件。事件数据为InputEvent对象。
    GObject.onTouchEnd:鼠标或手指释放。冒泡事件。事件数据为InputEvent对象。
    GObject.onRollOver:鼠标移入元件。事件数据为InputEvent对象。
    GObject.onRollOut:鼠标移出元件。事件数据为InputEvent对象。
    GObject.onAddedToStage:元件被添加到舞台。无事件数据。
    GObject.onRemovedFromStage:元件从舞台移出。无事件数据。
    GObject.onKeyDown:元件接收到按键事件。只有获得焦点的情况下才能接收按键事件。冒泡事件。事件数据为InputEvent对象。
    GObject.onClickLink:文本中的链接被点击。事件数据为href值,字符串类型。
    GObject.onPositionChanged:元件的位置改变。无事件数据。
    GObject.onSizeChanged:元件的大小改变。无事件数据。
    GObject.onDragStart/GObject.onDragEnd:拖动是指玩家按住元件拖动然后释放的过程。注意只有设置了GObject.draggable属性的元件才会触发拖动事件。拖动过程中可以获得两个通知:开始和结束。当onDragStart中,调用EventContext.PreventDefault()可以立刻取消拖动。无事件数据。
    GTextField.onFocusIn/GTextField.onFocusOut:只有输入类型的文本才会触发这个事件。当输入文本获得焦点时,在移动设备上会弹出小键盘。无事件数据。
    GTextField.onChanged:只有输入类型的文本才会触发这个事件。无事件数据。
    GMovieClip.onPlayEnd:动画设定的播放次数已经播放完毕。无事件数据。
    GList.onClickItem:当GList容器内的元件被点击时触发的事件类型;事件数据为当前点击的GObject对象。
    GComponent.onScroll:如果容器是滚动类型容器,则滚动发生时产生该事件。
    GComponent.onDrop:注意要和普通拖动区别,一个元件被拖动并释放后并不会触发Drop事件。Drop事件需配合DragDropManager使用。当DragDropManager拖动的图标在某个元件上释放时,这个元件就会触发onDrop。事件数据为DragDropManager.StartDrag中传递的source值。
    GButton.onChanged:当单选或者多选按钮选中状态改变时会触发该事件(只有在用户点击后状态改变才会触发,如果是程序改变不会触发)。无事件数据。
    GComboBox.onChanged:当用户从下拉列表中选择一项时触发该事件。无事件数据。
    GSlider.onChanged:当用户拖动滑块改变Slider的值时触发该事件。无事件数据。
    Controller.onChanged:当控制器页面改变会触发该事件(改变selectedIndex会触发该事件,setSelectedIndex则不会)。无事件数据。

    (十八)在Unity项目中使用FairyGUI
    1. 使用UIPanel
    只需3步就可以使用将编辑器中制作好的界面放入到Unity的场景中。第一步,从GameObject菜单中选择FairyGUI->UIPanel:

    第二步,在Inspector里点击PackageName或者ComponentName,将弹出选择组件的窗口:

    第三步:这个窗口里列出了所有工程里能找到的UI包,选择一个包和组件,然后点击OK。

    可以看到,UI组件的内容显示出来了。(注意:Unity4版本目前不支持显示内容,只能显示线框)
    如果UI包修改了,或者其他一些情况导致UIPanel显示不正常,可以使用下面的菜单刷新:

    当运行后,获得UIPanel的UI的方式是:
    UIPanel panel = gameObject.GetComponent();
    GComponent view = panel.ui;
    与其他UIPackage.CreateObject创建出来的界面不同,UIPanel在GameObjec销毁时(手动销毁或者过场景等)时会一并销毁。
    UIPane只保存了UI包的名称和组件的名称,它不对纹理或其他资源产生任何引用,也就是UI使用的资源不会包含在场景数据中。
    在编辑状态下,无论UI组件引用了哪些UI包的资源,包括放置在Resources目录下的和不放置在Resources下的,都能够正确显示。但当运行后,UIPanel只能自动载入放置在Resources目录或其子目录下的UI包,也只会载入自身所在的UI包,其他情况的UI包(例如引用到的UI包或打包到AssetBundle的UI包)不能自动载入。你需要在UIPanel创建前使用UIPackage.AddPackage准备好这类UI包。UIPanel在Start事件或者第一次访问UIPanel.ui属性时创建UI界面,你仍然有机会在Awake里完成这些操作。
    下面是UIPanel的一些属性说明:
    Render Mode: 有三种:
    Screen Space Overlay (默认值),表示这个UI在屏幕空间显示,这时Transform的Scale将被锁定,而且不建议修改Transform中的其他内容(让他们保持为0)。如果要修改面板在屏幕上的位置,使用UI Transform(参考下面关于UI Transform的说明)。
    Screen Space Camera 表示这个UI在屏幕空间显示,但不使用FairyGUI默认的正交相机,而是使用指定的正交相机。
    World Space 表示这个UI在世界空间显示,由透视相机渲染。默认的使用场景的主相机,如果不是,那么设置Render Camera。当使用这种模式时,使用Transfrom修改UI在世界空间中的位置、缩放、旋转。但你仍然可以使用UI Transform。
    注意:Render Mode只定义了FairyGUI对待这个UI的方式,通常是坐标相关的操作(如点击检测等),但和渲染无关。UI由哪个相机渲染是由GameObject的layer决定的。所以如果发现UI没有显示出来,可以检查一下GameObject的layer是否正确。例如如果是Screen Space,GameObject应该在UI层,如果是WorldSpace,则是在Default层或者其他自定义的层次。
    Render Camera:当Render Mode是Screen Space Camera或者World Space时可以设置。如果不设置,默认为场景的主相机。
    Sorting Order:调整UIPanel的显示顺序。越大的显示在越前面。
    Fairy Batching:是否启用Fairy Batching。关于Fairy Batching请参考下面的说明。切换这个值,可以在编辑模式下实时看到DrawCall的变化(切换后点击一下Game,Stat里显示的内容才会更新),这可以使你更加容易决定是否启用这项技术。
    Touch Disabled:勾选后,将关闭点击检测。当这个UI没有可交互的内容时可以勾选以提高点击检测时的性能。例如头顶血条这些类型的UI,就可以勾选。
    UI Transform:当Render Mode是Screen Space时可以使用这里的设置调整UI在屏幕上的位置。你仍然可以调整Transform改变UI的位置,但我不建议你这样做,因为Transform中的坐标位置是没有经过不同分辨率自适应的调整的。当Render Mode是World Space时,建议使用Transform设置UI的位置,你仍然可以调整UI Transform改变UI的位置,但调整的效果可能不那么直观。同时你可以使用Scene视图中下图所示的原点调整UI Transform的位置属性:

    Fit Screen:这里可以设置UIPanel适配屏幕。
    Fit Size:UI将铺满屏幕。
    Fit Width And Set Middle:UI将横向铺满屏幕,然后上下居中。
    Fit Height And Set Center:UI将纵向铺满屏幕,然后左右居中。
    这里提供的选项不多,因为FairyGUI推荐的是在FairyGUI编辑器中整体设计,而不是在Unity里摆放小元件。例如如果需要不同的UI在屏幕上的各个位置布局,你应该在FairyGUI编辑器中创建一个全屏大小的组件,然后在里面放置各个子组件,再用关联控制布局;最后将这个全屏组件放置到Unity,将Fit Screen设置为Fit Size即可。错误的做法是把各个子组件放置到Unity里再布局。
    HitTest Mode:这里可以设置UIPanel处理鼠标或触摸事件的方式。
    Default: 这是默认的方式。FairyGUI会用内置的机制检测鼠标或触摸动作,不使用射线,UIPanel也不需要创建碰撞体,效能比较高。
    Raycast: 在这种方式下,UIPanel将自动创建碰撞体,并且使用射线方式进行点击检测。这种方式适合于UIPanel还需要和其他3D对象互动的情况。
    2. 动态载入UI界面
    在很多情况下,你并不需要将UI界面放到场景中。使用代码载入编辑器制作好的界面也非常简单:
    GComponent view = UIPackage.CreateObject(“包名”, “组件名”) as GComponent
    动态载入的界面不会自动销毁,例如一个背包窗口,你并不需要在每次过场景都销毁。如果要销毁界面,调用Dispose方法即可,例如
    view.Dispose();
    也可以动态创建UIPanel为任意游戏对象挂接UI界面,方法为:
    UIPanel panel = yourGameObject.AddComponent();
    panel.packageName = “包名”;
    panel.componentName = “组件名”;
    panel.CreateUI();
    UIPanel的生命周期将和yourGameObject保持一致。再次提醒,注意yourGameObject的layer。
    3. 载入UI包
    Unity项目载入UI包有以下几种方式,开发者可以根据项目需要选择其中一种或者多种混搭使用:
    1)将打包后的文件直接发布到Unity的Resources目录或者其子目录下,

    然后在代码中调用UIPackage.AddPackage(“demo”), demo就是发布时填写的文件名。如果在子目录下,调用UIPackage.AddPacakge(“路径/demo”)即可。
    2)将发布后的文件打包为两个AssetBundle,即定义文件和资源各打包为一个bundle(desc_bundle+res_bundle)。这样做的好处是一般UI的更新都是修改元件位置什么的,不涉及图片资源的更新,那么只需要重新打包和推送desc_bundle就行了,不需要让玩家更新通常体积比较大的res_bouble,节省流量。打包程序由开发者按照自己熟悉的方式自行实现。以demo为例,请遵循以下规则打包:
    a)demo.bytes单独打包为desc_bundle;
    b)其他资源(demo@atlas0.png等),打包到res_bundle(在此例中就是atlas0和sprites)
    然后在代码中调用UIPackage.AddPackage(desc_bundle, res_bundle)。bundle的载入由开发者自行实现。
    3)将发布后的文件打包为一个AssetBundle。打包程序由开发者按照自己熟悉的方式自行实现。以demo为例,将demo.bytes和其他资源(demo@atlas0.png等),都放入bundle。然后在代码中调用UIPackage.AddPackage(bundle, bundle)。bundle的载入由开发者自行实现。
    在使用AssetBundle的载入方案中,将由FairyGUI接管bundle并负责bundle资源的释放。
    4. UI适配
    可以通过两种方式设置UI自适应,第一种方式是在游戏的启动创建里任意对象挂一个FairyGUI/UIContentScaler组件:

    这里选项的含义可以参考教程里关于UI适配的说明。
    另外一种方式是通过代码,可以参考教程里关于UI适配的说明。
    5.图集的处理
    FairyGUI编辑器发布到Unity的资源通常包含一个或多个UI图集,以demo工程为例,这里demo@atlas0.png就是一个图集

    图集是由UI编辑器自动生成的,但在Unity里可以改变图集的属性,常用的设置有:
    1)Generate Mip Maps
    不勾选。UI不使用Mip Maps功能。
    2)Filter Mode
    使用Bilinear,这样图像在缩放时能产生比较平滑的过渡效果,副作用是会产生一定的模糊。而且单色的图像缩放会产生不必要的渐变边缘。而使用Point,则图像在缩放时会块状化。

    一般UI图集使用Bilinear即可。你也可以在UI编辑器里将图片安排到不同图集,然后每个图集设置不同的Filter Mode以满足特殊需求。
    3)Max Size
    一般设置到2048。
    4)Format
    UI图集一般都是PNG格式,并带有透明通道。同时,UI对画质的要求比较高,所以建议选择AutoMatic TrueColor。但TrueColor有一个最大的问题是文件大,而且占用内存较高,例如1024×1024的图集,将占用4MB的内存,2048×2048则达到16MB。
    如果对内存使用比较敏感,也可以选用压缩格式,即AutoMatic Compressed。在桌面平台上即相同于DXT5,在Android平台上相当于ETC1,在IPhone平台则为PVRTC。这些格式能够大大降低内存占用,也因为它们是显卡直接支持的格式,所以Unity在载入时省去了解码位图的步骤,能够加快载入速度。但它们都是属于有损压缩,在显示质量上肯定不如TrueColor,特别是图集颜色十分丰富,或者有颜色渐变时,失真会比较厉害。特别重要的是,ETC1是不支持透明通道的,PVRTC对透明通道的支持也比较弱,所以并不适合带透明通道的图集。FairyGUI提供了ETC1/PVRTC+A的解决方案。首先,在发布时勾选“为Alpha通道创建单独的贴图”,如下图:

    这样,就产生了两个不含透明通道的贴图,一张去除了原图透明通道的贴图,和一张将原贴图透明通道数值转换为等价灰度的贴图。这两张贴图都可以设置为Automatic Compressed。(一定要注意,不能再将主贴图设置为True Color)

    FairyGUI提供了特制的着色器处理两张贴图的合并。开发者并不需要编写额外的代码就可以使用这项技术。
    TIPS
    你可以将本身就不含透明通道的位图(例如一些大型的背景图)安排到一张图集上。如果一张图集内的所有图片都不包含透明通道,那么最终输出的图集也不包含透明通道。不含透明通道的图集可以选用Automatic 16bits格式。
    6. 字体的处理
    FairyGUI使用Unity的动态字体技术渲染文字。只需以下几个简单的步骤就可以完成设置:
    1)拷贝一个字体文件到项目的Resources目录或Resources/Fonts目录。字体文件可以随意使用一个,例如arial.ttf,或simhei.ttf等,这个ttf是什么字体并不影响最终显示字体的选择。
    2)在Unity中点击字体文件,在inspector中修改字体属性

    注意在Font Names中填写的是字体名称,标准的字体名称可以从这里找到: 中文字体的英文名称对照表。例如Droid Sans Fallback是Android平台支持中文的内置默认字体之一。多个字体用逗号隔开,Unity会使用第一个在系统中能找到的字体。
    3)设置UIConfig.defaultFont=”字体文件名称”即可,注意这里使用的是文件名称,也就是说,如果放置在Resources目录的是arial.ttf,则UIConfig.defaultFont=”arial”,不需要带.ttf后缀。
    因为我们没有勾选Include Font Data,所以无论这个字体文件有多大,最终并不会包含在我们的发布包中,也就是说不会增大发行包的体积。Unity会在实际运行的系统中查找与Font Names匹配的第一个字体,并使用此字体进行动态渲染。
    如果你是在Unity5.x平台开发,除了上述方式外,得益于Unity5.x引入的新的字体管理API,也可以不放置字体文件到Resources目录,你只需要直接设置UIConfig.defaultFont=”字体名称“即可,同样,多个字体名称用逗号隔开。例如:UIConfig.defaultFont=”Droid Sans Fallback, LTHYSZK, Helvetica-Bold, Microsoft YaHei, SimHei”;
    4)如果你的界面使用了多种字体,比如对单独的文字设置了字体:

    这里用到了“黑体”这个名字的字体,这是与UIConfig.defaultFont里设置的不同的字体,我们也需要注册这种字体。方法是,首先做好上面1)和2),假如字体文件名称是HeiTi.ttf,然后
    FontManager.RegisterFont(“黑体”, FontManager.GetFont(“HeiTi”));
    RegisterFont的第一个参数对应编辑器里使用的字体名称;第二个参数,是Unity中放入的字体文件资源。如果文件带路径,这也需要把路径填上。
    5)当你使用部分字体的粗体效果时,你会发现粗体的效果在Unity中的显示不正确,这是因为有些字体不带粗体效果的,这时候Unity就会用拉宽来实现,就像变扁了。fairygui可以用额外的mesh来解决粗体的显示。方法是:
    FontManager.GetFont(“字体路径”).customFold = true;
    这里字体路径与UIConfig.default里设置的内容应该完全一样。
    6)某些字体,unity渲染有粗体效果,但当设置成斜体时,粗体效果又丢失(例如雅黑)。fairygui在这种情况取消unity默认渲染粗体的效果,改为增加额外的面渲染粗体。激活这个功能的方法是
    FontManager.GetFont(“字体路径”).customBoldAndItalic = true;
    如果已经设置了customBold,不需要再设置customBoldAndItalic。
    备注1
    动态字体要求玩家的运行系统环境中有你设定的字体,如果没有,实际使用的字体可能并不是你想要的效果。因此,你可以选择嵌入整个字体文件。方法是把你要用的字体文件放到Resources目录,并把Include Font Data勾选,这样整个字体文件就会包含到最终的发布包中,坏处就是会大大增加发行包的体积。
    备注2
    在实际游戏制作过程中发现在桌面平台下Unity对中文字体的渲染稍显模糊和暗淡,因此FairyGUI使用了特制的着色器解决了这个问题。以下是Unity默认的字体渲染效果和FairyGUI的字体渲染效果的比较:

    可以看见经过FairyGUI的特殊处理,中文文字更清晰更亮。
    只有在桌面平台下FairyGUI才会开启这种技术,移动平台永远不会开启,因为在高DPI情况下,字体默认的渲染效果已经非常漂亮。
    另外,如果你不喜欢这种显示效果,或者你使用的是全英文的文字,也可以手动把这种技术关闭:UIConfig.renderingTextBrighterOnDesktop = false;
    7 在UI中穿插其他3D对象
    FairyGUI底层使用Renderer.sortingOrder来决定对象的渲染顺序,利用这个特性,我们可以很容易的将UI对象与其他3D对象(例如例子)安排在一起。FairyGUI提供了封装类GoWrapper,可以直接包装其他GameObject插入到UI层次中。如下图,一个粒子特效被安排到了UI之间。

    又例如,一个3D模型穿插在UI中间

    详细实现方法可以参考FairyGUI-unity包中的Assets/FairyGUI/Examples/Particles和Assets/FairyGUI/Examples/Model。
    8. 与RenderTexture配合
    在UI上展现3D内容的另一种方式是使用RenderTexture,特别是需要进行剪裁的情况下(如果不需要剪裁,推荐直接放置3D内容,免除RenderTexture性能消耗。参考6. 在UI中穿插其他3D对象)。在FairyGUI中,可以将Image.texture设置为一个RenderTexture,然后就可以像使用普通图片一样使用这个RenderTexture了,可以出现在任何地方,包括滚动容器。特别地,FairyGUI还能支持将RenderTexture所在位置的背景图片影射到RenderTexture渲染相机的背景上,这样就不用担心透贴的问题了。如下图,NPC使用RenderTexture渲染到UI窗口中。

    详细实现方法可以参考FairyGUI-unity包中的Assets/FairyGUI/Examples/RenderTexture。
    9. Drawcall优化
    在Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call(DC)。Draw Call次数是一项非常重要的性能指标。UI系统一般包含数量众多的物体,有效控制DC是衡量一个UI系统是否实用的关键因素,特别是在移动设备上。
    我们先来看看NGUI是怎么做的,NGUI把UIPanel中的Widget按depth排序,然后将相同材质的Widget进行Mesh合并,例如使用相同图集的图片,或者文字。Mesh合并的优点是合并后这些Widget就只产生一个DC。但这个合并过程需要计算所有Widget坐标相对于Panel的变换,而且如果Widget行为改变,例如平移,缩放等,都会触发Mesh重新合并,这会带来一定的CPU消耗,这就需要开发者谨慎组织UI元素到各个UIPanel,并且对深度需要细致安排,否则达不到减少DC效果的同时更可能带来比较大的CPU消耗。
    FairyGUI没有采取合并Mesh的策略,原因有两个:
    ● FairyGUI使用的是树状显示对象结构,各个元件之间的层次关系非常复杂;
    ● FairyGUI编辑器给予用户最大的设计自由度,加上动效的引入,各个元件的状态都可能非常动态;
    FairyGUI基于Unity的Dynamic Batching技术,提供了深度调整技术进行 drawcall优化 。FairyGUI能在不改变最终显示效果的前提下,尽可能的把相同材质的物体调整到连续的renderingOrder值上,以促使他们能够被Unity Dynamic Batching优化。Dynamic Batching是Unity提供的Draw Call Batching技术之一。如果动态物体共用着相同的材质,那么Unity会自动对这些物体进行批处理。但Dynamic Batching的一个重要的前提是这些动态物体是连续渲染的。先来看看FairyGUI中物体的渲染顺序,例如:

    这里有4个按钮,每个按钮都是一个组件,每个组件里包含一个图片和一个文字对象。FairyGUI是树状的显示对象结构,那么他们按深度排序应该是:

    因为文字和图片的材质并不相同,所以每次从文字到图片都产生上下文切换,所以产生了6个DC。
    FairyGUI的深度调整技术可以优化这种情况。观察一下,其实四个按钮之间并不相交,所以FairyGUI智能地将渲染顺序调整为:

    因为FairyGUI使用了图集,而且动态文字也使用了相同的贴图,这样,DC就降低到了2个,达到了优化的目的。实际情况会比这个复杂很多,但FairyGUI能在不改变最终显示效果的前提下,尽可能的把相同材质的物体调整到连续的renderingOrder值上,以促使他们能够被Unity Dynamic Batching优化。而对开发者来说,这些底层上的调整是透明的,也就是不会影响原来的显示对象层次。从效率上考虑,这种技术仅比较物体之间的显示矩形区域(一个Rect)是否相交,所以速度是非常快的,不会带来过多的CPU负荷。
    FairyGUI提供了一个开关控制组件是否启用深度调整,API是:
    GComponent someComponent;
    someComponent.fairyBatching = true;
    如果某个组件设置了fairyBatching,那么无需在子组件和孙子组件再启用fairyBatching。一般只在顶层组件打开这个功能,例如主界面,加载界面等。注意,Window这个类已经自动打开了fairyBatching,这符合我们的使用习惯,因为一般我们都是以窗口为单位安排功能的。如果界面不复杂,Draw Call本来就不高的情况下,开发者也可以忽略这个功能,从10个DC优化到8个DC并没有什么意义。在实际使用过程中,
    对于打开了fairyBatching的组件,当开发者动态改变子元件或者孙子元件的位置或大小时,并不会自动触发深度调整,例如一个图片原来显示在一个窗口里的顶层,你用Tween将它从原来的位置移到另外一个位置,这个图片就有可能被窗口里的其他元素遮挡。这时开发者可以手动触发深度调整,API是
    someObject.InvalidateBatchingState();
    这个API并不需要由开启了fairyBatching的组件调用,它可以用任何一个内含的元件发起。对于UI动效(Transitions),FairyGUI已经自动调用了这个API,所以开发者不必处理。
    下载并运行Demo,可以观察fairyBatching的实际效果。例如这个Demo的首页:

    设置了fairyBatching后由42个DC减少到了6个DC,另外,可以看到Saved by batching: 27的字样。

    1. 与ULUA配合
      一、安装
      1、将以下语句添加到Assets\uLua\Editor\WrapFile.cs适当的位置,然后调用Lua的菜单Gen Lua Wrap Files,重新生成绑定文件。
      _GT(typeof(EventContext)),
      _GT(typeof(EventDispatcher)),
      _GT(typeof(EventListener)),
      _GT(typeof(InputEvent)),
      _GT(typeof(DisplayObject)),
      _GT(typeof(Container)),
      _GT(typeof(Stage)),
      _GT(typeof(Controller)),
      _GT(typeof(GObject)),
      _GT(typeof(GGraph)),
      _GT(typeof(GGroup)),
      _GT(typeof(GImage)),
      _GT(typeof(GLoader)),
      _GT(typeof(PlayState)),
      _GT(typeof(GMovieClip)),
      _GT(typeof(TextFormat)),
      _GT(typeof(GTextField)),
      _GT(typeof(GRichTextField)),
      _GT(typeof(GTextInput)),
      _GT(typeof(GComponent)),
      _GT(typeof(GList)),
      _GT(typeof(GRoot)),
      _GT(typeof(GLabel)),
      _GT(typeof(GButton)),
      _GT(typeof(GComboBox)),
      _GT(typeof(GProgressBar)),
      _GT(typeof(GSlider)),
      _GT(typeof(PopupMenu)),
      _GT(typeof(ScrollPane)),
      _GT(typeof(Transition)),
      _GT(typeof(UIPackage)),
      _GT(typeof(Window)),
      _GT(typeof(GObjectPool)),
      _GT(typeof(Relations)),
      _GT(typeof(RelationType)),
      2、拷贝FairyGUI.lua到你的lua文件存放目录。
      二、使用
      1、普通方法的侦听和删除侦听
      require ‘FairyGUI’
      function OnClick() –也可以带上事件参数,OnClick(context)
      print(‘you click’)
      end
      UIPackage.AddPackage(‘Demo’)
      local view = UIPackage.CreateObject(‘Demo’, ‘DemoMain’)
      GRoot.inst:AddChild(view)
      view.onClick:Add(OnClick)
      –view.onClick:Remove(OnClick)
      2、类方法的侦听和删除侦听
      require ‘FairyGUI’
      TestClass = class(‘TestClass’, {})
      function TestClass:ctor()
      UIPackage.AddPackage(‘Demo’)
      self.view = UIPackage.CreateObject(‘Demo’, ‘DemoMain’)
      GRoot.inst:AddChild(self.view)
      self.view.onClick:Add(TestClass.OnClick, self)
      –self.view.onClick:Remove(TestClass.OnClick, self)
      end
      function TestClass:OnClick() –也可以带上事件参数,TestClass:OnClick(context)
      print(‘you click’)
      end
      TestClass.New()
      3、如果要使用Tween,你可以直接使用GObject.TweenXXXX系列函数,免除了Wrap DOTween的麻烦。

    END——————————————————————————
    以上只是个人摘录,更详细的可以看官网教程:http://www.fairygui.com/tutorial

    展开全文
  • FairyGUI

    万次阅读 2016-09-02 14:09:39
    FairyGUI是一款专业的 UI编辑器 FairyGUI UI编辑器 操作简单,使用习惯与Adobe系列软件保持一致,美术设计师可以轻松上手。在编辑器即可组合各种复杂UI组件,以及为UI设计动画效果,无需编写任何代码。可一键导出...

    FairyGUI是一款专业的 UI编辑器

    FairyGUI UI编辑器 操作简单,使用习惯与Adobe系列软件保持一致,美术设计师可以轻松上手。在编辑器即可组合各种复杂UI组件,以及为UI设计动画效果,无需编写任何代码。可一键导出到Unity,Starling,Egret, LayaAir,Flash等多个主流应用和游戏平台。

    我们的目标:99%的UI制作任务都直接可视化完成!

    UI编辑器

    特性:

    1. 所见即所得。操作简易,使用习惯与Adobe系列软件保持一致,美术设计师可以轻松上手。
    2. 在编辑器即可组合各种复杂UI组件,无需编写代码。不需要程序员编码扩展UI组件。
    3. 强大的文本控件。支持动态字体,位图字体,以及BMFont制作的位图字体,支持HTML语法和UBB语法,支持图文混排。
    4. 强大的列表控件,支持多种布局,支持虚拟列表和循环列表,即使列表项目数量巨大也拒绝卡顿。
    5. 支持图片的九宫格和平铺处理,支持图片变色和灰度,支持序列帧动画编辑和使用。
    6. 内置手势支持。
    7. 提供时间轴设计UI动效,可实时看到每帧的位置或其他效果。
    8. 编辑状态下使用分散的素材,发布时自动打包图集。支持定义多个图集,自动支持抽出A通道的压缩方式。
    9. 多国语言支持。
    10. 各种分辨率自适应。
    11. 提供插件机制,可以根据项目的需要为编辑器加入个性功能。
    12. 为各个游戏平台提供了一致的API,得益于编辑器强大的编辑功能,程序员只需要了解少量API就能完成UI展现,相比Feathers, NGUI, UGUI等UI框架,FairyGUI提高了UI制作效率,降低了成本。

    加入Q群获得FairyGUI最新资讯:434866637 FairyGUI技术交流群

    查看例子

    阅读手册

    ========== 更新信息===============

    【2016-08-29】

    Unity SDK更新到了1.5.1版本

    1、修正文本控件使用位图文字时字体全部无效的情况下导致异常的bug。
    2、简化了ScrollUp/Down/Left/Right的代码。
    3、修正UIPanel和UIPainter处理disable和enable的逻辑。
    4、设置正确的BlendMode.Add。
    5、取消长按手势对手指数量的限制。
    6、修正了输入文本光标有时定位不准确的bug。
    7、修改输入文本在手机上点击报错的bug。
    8、处理GLoader设置texture为null时错误。
    9、TreeNode中numChildren增加为空判断。
    10、修正输入文本过多的剪裁导致y的下面缺了两个像素的bug。
    11、修改关联系统,不出现小数坐标。
    12、增加了普通文本剪裁的支持。
    13、SetCustomInput增加buttonUp参数(在前面版本删掉了,还是很有用,所以加回)。如果使用不带buttonUp参数的版本,则buttonDown后下一帧自动触发buttonUp。如果使用带buttonUp参数版本,则buttonDown后直到buttonUp传入true时才触发buttonUp。
    14、设置UI的正交摄像机在VR开发中不参与随视野旋转。
    15、增加了PC平台上鼠标中键和右键的支持:InputEvent.button。
    16、着色器bug修正(影响ETC+A混合模式下,图片Alpha值设置失效)

    【2016-08-15】

    编辑器更新到2.5.8版本

    1、增加了设置位图字体“允许动态改变颜色”的功能。现在用图片组成的位图字体也可以动态改变颜色了。
    2、丰富了输入类型的文本的设置。

    2016-08-15_112934

    SDK更新

    1、Laya版本适配到了LayaAir1.1.0版本。
    2、Laya版本修改了剪裁的实现,现在使用scrollRect实现,提高性能,而且不会出现超过cache超过2048的错误。
    3、Starling和AS3版本增加了对embedFont的支持。
    4、各个SDK增加了对编辑器设置input类型文本参数(maxLength,restrict)的支持。
    5、各个SDK(除H5)增加了对位图字体着色的支持。

    Unity SDK更新到了1.5.0版本

    1、优化了文本控件,包括以下几点:
    1)优化了RichTextField的实现,代码更简洁。
    2)增强了链接的实现,现在链接具有单独的显示对象,可以进行更复杂的控制,比如鼠标移过/点击时显示特定的背景颜色(通过HtmlParseOptions.DefaultLinkHoverBgColor等),又比如可以侦听链接的rollover/rollout等。
    3)增加了UIConfig.inputCaretSize和UIConfig.inputHighlightColor,可以个性化输入光标的大小和选择文本的背景色。
    4)修改了下划线样式下空格出现多余的下划线的bug。
    5)修改了输入文本垂直居中时,即使文本框很高,也不容易激活输入的bug。
    2、增加了GRichTextField/GTextInput.emojies接口,可以设置unicode字符对应的图片。通过这个接口,不但可以实现不使用html也能图文混排,更方便的是这种方式支持输入文本。通过简单定义,可以轻松支持显示IOS键盘中自带的表情。详见EmojiPro这个示例。
    3、增加输入验证功能 GTextInput.restrict。例如GTextInput.restrict=”[a-zA-Z]”;
    4、UIPackage.RemovePackage增加了一个可选参数allowDestroyingAssets,当设置为true时,包里的资源会立刻释放,如果为false,则等待垃圾收集。这个功能仅当包是从AassetBundle中载入时才有意义。如果包是放在Resources目录的,这个参数被忽略。
    5、增加了虚拟列表对不等高item和不同资源item的支持。现在虚拟列表支持通过关联,或者直接在RenderListItem回调中改变item的大小。更可以通过ListItemProvider回调,为不同位置的item提供不同的资源。详见EmojiPro这个示例。
    6、事件机制增加了一个EventContext.CaptureTouch。当在onTouchBegin事件处理时,你可以调用context.CaptureTouch(),这样,无论鼠标/手指在哪里释放(即使不在对象区域内),对象的onTouchEnd都会被调用。注意仅生效一次。
    7、增加了Shape.DrawPolygon,现在可以传入多个点构建多边形。
    8、增加一个自定义遮罩的擦除DC,解决多个被遮罩组件重叠时出现的显示错误。
    9、 修正UIPanel没有正确处理GameObject.SetActive的情况。
    10、Unity5.4兼容性测试。

    【2016-07-28】

    编辑器更新到2.5.7版本

    1、修正了动画编辑窗口不能输入帧延迟的bug。
    2、增加了关闭滚动惯性的选项,请打开滚动属性面板设置。
    3、修改了按钮/标签等组件,在不设置赋值标题/图标时,保留设计时给title和icon设置的值。
    4、修改了列表编辑窗口,现在你可以给列表项目设置名称(即GObject.name)。
    5、增加了下拉框弹出方向的设置。
    6、修正了使用UBB设置文本某些情况下显式不正确的bug。
    7、修正了发布ETC+A纹理时,RGB纹理错误进行了预乘的bug。

    SDK更新

    1、现在可以访问GearXY/GearSize/GearLook的Tweener。
    2、增加了GObject.pixelSnapping,当为真时,GObject的坐标将自动取整。默认为false。
    3、修改虚拟列表由于延迟渲染造成设置选中项不正确的bug。
    4、[AS3][Egret]修改了动画连续使用setPlaySettings时可能播放不正确的bug。
    5、[Egret][Laya]增加了多语言支持,UIPackage.setStringsSource。
    6、[Egret][Laya]修正了位图字体对齐不正确的bug。

    Unity SDK更新到了1.4.4版本
    1、修正了输入文本在处理粘贴时,没有判断maxLength的bug。
    2、修改了在ETC+A模式下,没有进行每帧设置材质的AlphaTexture的bug。
    3、增加了ScrollPane.onScrollEnd事件。
    4、增加了EventListener.Set方法,方便设置事件的回调函数,当这类事件不需要多个回调函数,Add/Remove麻烦且容易重复添加。
    5、增加了GSlider.onGripTouchEnd事件,当手指离开滑块后调用。
    6、增加了图片平铺的一种特殊实现方式,当图片为“单独(NPOT)”导出,且纹理的Wrap Mode设置为Repeat时,自动利用纹理的Repeat特性实现平铺。这种情况下纹理的FilterMode不需要设置为Point,可以使用Bilinear,而且不受抗锯齿设置的影响。

    【2016-07-04】

    编辑器更新到2.5.6版本

    1、编辑器的Windows版本发布方式改为压缩包,不再使用msi安装格式。
    2、修改了设置属性控制器的方式。新的方式更节省空间。

    2016-07-04_002122

    3、现在动效编辑界面也支持撤销和重做了。
    4、增加了按住鼠标中键可以直接拖拽移动舞台的功能。

    各个SDK都有对应编辑器新功能的更新。

    Starling修正了文字关联没有实时更新的bug。

    Unity SDK更新到了1.4.2版本

    修正了UI适配的一个bug。
    修正了组件接收交互的同时销毁引发异常的bug。

    【2016-06-28】

    编辑器更新到2.5.5版本

    1、增加了文字投影效果的设置。XY是阴影的偏移。投影的颜色与描边的颜色设置方式一致。

    2016-06-28_163232

    2、增加了将轴心作为锚点的设置。勾选后,轴心的位置将作为元件的原点位置。

    2016-06-28_163533

    3、现在组件设计时可以直接设置轴心。

    2016-06-28_163547

    4、预览界面现在支持缩放。(快捷键也同时支持)

    2016-06-28_163749

    5、发布时如果发布路径不存在将自动创建路径。
    6、修改了设置为自动播放的深层嵌套的动效没有自动播放的bug。

    各个SDK都有对应编辑器新功能的更新。(H5版本暂时未支持文字阴影)

    修正了动画摆动播放无效的bug

    Unity SDK更新到了1.4.1版本

    增加了树形视图的支持,并增加了相应的Demo。

    【2016-06-11】

    编辑器更新到2.5.2版本

    1、增加了倾斜、颜色滤镜和BlendMode的设置(所有SDK均已支持,除AS3版本未支持倾斜)

    2016-06-11_230334 2016-06-11_230352

    2、新建组件、新建按钮等功能中的默认新名称改为使用英文。
    3、修正了Layabox项目类型设置不成功的bug。
    4、修正了设置了比较小的最大输出纹理大小值后发布有时会卡死的bug。

    Egret SDK更新到了适应最新的默认使用webgl的Egret引擎。demo已全部更新。

    Layabox SDK更新到了适应最新的Layair1.0.0rc引擎。demo已全部更新。

    Unity SDK更新到了1.4.0版本

    1、增加了显示对象的Painting模式。在此模式下,任意组件可以当做一张位图一样使用。(组件的BlendMode,倾斜、滤镜均基于该技术)

    2016-06-11_232518

    2016-06-11_232611

    2、增加了透视模拟功能。在普通UI相机下(即正交相机),rotaionX/rotationY没有透视效果,如果把UI放到主相机下,又难以和普通UI共存。使用FairyGUI提供的模拟功能,可以轻松实现逼真的翻转效果。
    3、Stage.setCustomInput去除了第三个参数:buttonUp。如果当前帧不传入buttonDown而上一帧是buttonDown,则将自动模拟一个buttonUp事件。
    4、Stage.setCustomInput增加一个使用参数类型为RaycastHit的重载,你可以直接传入手柄的射线。
    5、增加了CopyPastePatch,如果你是使用DLL形式的插件,那么把这个脚本放到工程里,并在游戏启动时加上 CopyPastePatch.Apply(); 可以在编辑器或者发布到PC平台时,使输入文本中的复制粘贴能正常使用。(如果是使用源码形式的插件,忽略这一条)。
    6、FairyBatching优化和bug修正。

    【2016-05-25】

    编辑器更新到2.5.0版本

    增加了自定义遮罩的功能,你可以为组件设置一个图片,或者一个图形为遮罩。

    2016-05-25_232458

    SDK更新

    1、增加了自定义遮罩的功能。(暂时只支持Unity和Starling)
    2、修正了Starling版本按钮移除,鼠标手型没有还原的bug。
    3、修正了图片翻转后九宫格显示不正确的bug。
    4、修正了按钮设置为按下变暗或缩放时显示位置不正确的bug。

    Unity版本更新到1.3.2版本

    【2016-05-19】

    编辑器更新到2.4.9版本

    新增加了LayaBox LayaAir引擎的支持,欢迎使用!

    1、增加了控制器缓动的延时设置

    2016-05-19_114602

    2、预览增加了修改分辨率的功能,可用于测试关联

    2016-05-19_114733

    3、动效里面的缩放设置加入负数的设置支持
    4、发布代码去掉了强制成员变量使用m_前缀
    5、使用了新的编辑器图标,感谢@白猫

    SDK更新

    1、Starling版本修正了位图字体在贴图未载入时显示出错的bug。
    2、Egret版本升级到适应3.0.8引擎。
    3、调整了Window点击后自动调整最前的策略,现在只会调整到所有窗口的最前,而不是GRoot的最前。
    4、调整进度条的进度文字不显示小数。
    5、修正Starling版本从舞台移除GTextInput时,没有移除原生输入的bug。

    Unity版本更新到1.3.1版本

    修正了输入文本的bug。着色器文件名称去掉了空格。

    【2016-05-04】

    编辑器更新到2.4.8版本

    1、增加了滚动容器的三项设置。在页面模式下,滚动容器每次滚动将翻过一页。在PC上,鼠标的少量位移可以触发翻页;在手机上,需要手指划过页面的一半。

    2016-05-04_184203

    2、显示列表现在可以多选了。
    3、发布对话框删除了“保存”按钮。任何更改都会自动保存,避免切换包时修改的数据丢失。
    4、当向字体编辑对话框拖入图片时,自动设置图片对应的文字为图片的名称。
    5、标签扩展在title为输入文本时,允许设置”输入提示“。
    6、轴心输入已经统一修改为百分比,旧面板的数据可以自动兼容,但动效里的设置不能兼容,请修改!!图形现在也支持设置轴心了。
    7、其他一些bug的修正。

    SDK更新

    1、支持滚动的页面模式。
    2、现在可以通过代码设置组件的留空:GComponent.margin。
    3、虚拟列表现在可以动态改变layout, lineGap, columnGap和itemSize
    4、GObject.setPivot修改为使用百分比,删除了setPivotByRatio
    5、增加了Window.bringToFontOnClick和UIConfig.bringWindowToFrontOnClick,现在可以设置窗口在点击时不自动提到最前
    6、ScrollToView增加了一个参数setFirst,现在你可以使某一个项目滚动到第一条,而不是任何可见的位置。
    7、增加了GearBase.disableAllTweenEffect开关,可以打开和关闭所有控制器引起的缓动。
    8、增加了GComponent.childrenRenderOrder,默认情况下,显示列表的渲染结果是索引小的对象显示在后,索引大的对象显示在前。childrenRenderOrder提供了其他的模式,例如ChildrenRenderOrder.Descent,可以使显示列表反向渲染;ChildrenRenderOrder.Arch,可以使显示列呈拱形顺序渲染,即中间的在最前,然后两边依次向后排。这个属性并不影响原有显示列表的顺序。

    Unity版本更新到1.3.0版本

    1、增加了UIPainter组件,你可以为任何几何体挂上UIPainter组件,然后UI面板将像一张纹理一样显示在几何体上,而且保持原有的交互特性。例如导入一个凹面模型,轻松制作出曲面效果的UI:

    2016-05-04_191146

    2、GTextInput增加了键盘类型的设置。GTextInput.keyboardType。
    3、现在你可以通过侦听GTextInput.onFocusOut事件,获得输入键盘关闭通知。
    4、你可以通过GTextInput.RequestFocus()方法弹出输入键盘。
    5、增加了UPanel的HitTestMode设置,对WorldSpace的UI,你可以设置为Raycast,表示这个对象将使用射线进行点击检测。
    6、增加了Stage.SetCustomInput,你可以每帧调用这个方法,传递坐标和按键标志,用于取代默认输入设备的输入,例如从VR设备得到的输入。
    7、增强的Html解析。

    【2016-04-11】

    编辑器更新到2.4.7版本

    1、增加了按钮常用按下效果的快捷设置(适用于手游)。

    2016-04-11_215954

    2、修正了序列帧动画暂停状态下显示不正常的bug。

    Unity版本更新到1.2.3版本

    1、优化了着色器。
    2、优化了QuadBatch的接口。
    3、增加了UIConfig.allowSoftnessOnTopOrLeftSide,以前滚动区域的左/上边缘是不会开启虚化效果的,现在你可以使用这个开关。
    4、描边粗细现在已支持。
    5、加入了机制无论任何时候调用Stage.IsTouchOnUI总能获得正确的结果。

    Egret SDK更新到适配Egret Engine 3.0.6

    【2016-04-06】

    编辑器更新到2.4.6版本

    1、增加了动效自动播放功能。动效可以设置为出现在舞台后自动播放(从舞台移走后自动停止)。

    2016-04-06_095340

    2、修正了宽高关联与大小控制器冲突的bug。
    3、动效时间轴增长指1分钟。
    4、其他一些小显示bug修正。

    Unity版本更新到1.2.2版本

    1、增加了UIConfig组件,可以设置属性和预加载包。

    2016-04-06_095535
    2、 修改UIPanel的创建时间点为Start或者第一次访问ui属性。这样使其他组件可以Awake里进行UIPanel创建前的预处理。
    3、修正了PixelPerfect相关的一些问题,当发布为Standalone时文字更清晰。
    4、修正了当屏幕仅宽度改变时(常见于Standalone),UI自适应没有生效的bug。

    所有SDK

    增加了动效自动播放的支持。
    增加了当组件从舞台移走时,自动停止所有动效播放的特性。

    【2016-03-29】

    编辑器更新到2.4.5版本

    1、增加了生成代码的功能

    2016-03-29_224947

    2、显示列表面板中增加了组折叠的功能。
    3、在预览界面中滚动内容现在可以拖拽。
    4、图片现在可以设置Scale。图片的Scale与改变大小的区别是前者对九宫格或平铺无效。
    5、修正了多个动效切换编辑时显示不正常的bug。
    6、修改了九宫格图片在很小时显示不正常的bug。
    7、修改了转换为组件时显示对象层次可能不正常的bug。
    8、修正了字体编辑界面中不能点中删除按钮的bug。

    Unity版本更新到1.2.1版本

    1. 修改了FillImage的实现。去除了FillImage这个Shader。
    2. 优化了着色器
    3. 修改UIContentScaler,使横屏和竖屏切换时不会调整scale。
    4. 增加了Stage.SortWorldSpacePanelsByZOrder, 可以按Z值对UIPanel排序。

    其他SDK也有bug修正,具体请参考git。

    【2016-03-21】

    编辑器更新到2.4.4版本

    1、增加了图片填充方式的设置,现在你可以利用它来制作环形进度条。(目前只有unity版本可以用,其他语言待开发)。

    2016-03-29_225012
    2、修正了2.2.3版本引入的一个bug,导致库面板选中焦点不对的bug。
    3、修正了导出空白动画时报错的bug。

    Unity版本更新到1.2.0版本

    1、新增编辑器扩展,UIPanel/UIScaler/StageCamera,现在可以直接放置UI了
    2、增加了图片的填充方式.
    3、重构了着色器。
    4、重构了部分代码。

    【2016-03-09】

    编辑器更新到2.4.3版本

    1、新增了像素级点击测试的功能。你可以指定组件中的任一个图片作为点击测试的源。如果点击在该图片的透明像素上,则点击将穿透。鼠标悬浮同样有效。图片不需要可见。

    2016-03-09_162728

    2、现在动效编辑时可以为高级组设置透明度。效果等同于为每一个属于改组的元件设置相同的透明度。
    3、修改了锁定对象后不能点中这个对象后面的内容的bug。

    Starling/AS3版本更新了虚拟列表和循环列表的支持, 加入了相应的demo,在下载页面可以下载。

    Egret版本优化了文本和动画的显示。

     

    展开全文
  • 初学FairyGUI,对比NGUI

    万次阅读 2017-01-24 10:53:30
    粗略介绍了FairyGUI的背景与优缺点,介绍了在做界面时NGUI存在的问题
  • 笔者之前沉迷游戏无法自拔,但是现在之前玩的游戏也不太爱玩了,发现下班到睡觉之前有2-3个小时空闲,仿佛发现了一逼宝贵的财富不能浪费。 笔者从事手游工作也有两年的时间了,主要做的是逻辑和SDK方面的工作,有...
  • FairyGui简单介绍

    千次阅读 2018-05-07 09:12:27
    1.什么是FairyGui?跨平台UI编辑器,支持多种项目:如Unity,Cocos2dx,CryEngine,HavokVision,Starling,Egret,LayaAir,Haxe,Pixi,LibGDX and More ……2.assets目录下每个目录都是一个包,包发布之后可以得到一个描述...
  • UGUI和fairyGUI的区别

    千次阅读 2019-09-06 17:28:01
    https://blog.csdn.net/yangxun983323204/article/details/78490097
  • FairyGUI加载包生成物体的过程解析

    千次阅读 2017-02-14 11:39:24
    这两天在看FairyGUI的工作流程,在加载FairyGUI某个组件的时候需要先AddPackage,然后在CreateObject,这时才能正确加载组件。要了解FairyGUI加载包生成UI的过程,要先了解FairyGUI编辑器生成包的格式。在FairyGUI编辑...
  • 以显示控制器为例,代码如下 //GearXXX对象是控制器和属性之间的连接。0-显示控制,1-位置控制,2-大小控制, // 3-外观控制,4-颜色控制,5-动画控制,6-文字控制,7-图标控制 GearDisplay gear = (GearDisplay)...
  • FairyGUI 中,文本控件自带了投影的功能,我们可以在设置中设置投影的偏移以及颜色。但是我们的UI同学想给图片等也添加投影的效果,就无从实现了。然后就丢给我们程序帮忙解决=。= 需求 可以给组件,图片等添加...
  • 我在做一个小游戏的时候需要实现界面滑动效果,开始第一念头是用监听鼠标的滑动位置改变来做,但是fairygui有一种滚动组件就可以很方便的实现。 我们需要用到滑动界面情况,通常是因为游戏的背景图片比游戏可视界面...
  • FairyGUI笔记:Component(九)

    千次阅读 2018-11-07 15:49:19
    自定义数据 可以设置一个自定义的数据,这个数据FairyGUI不做解析,按原样发布到最后的描述文件中。开发者可以在运行时获取。获取方式根据SDK版本有所不同,如果是支持XML包格式的SDK,获取方式为: //Unity/Cry ...
  • fairygui自定义扩展+两个例子

    千次阅读 2017-08-11 19:24:26
    近日看fairygui的几个例子,试着看懂代码,并照着例子再做一遍, 看是不是真的掌握了,并将其步骤等写在这,不然过段时间我可能又会忘记掉了。 关于组件的扩展,官网上有相关的介绍,用组件的扩展可以完成很多内容,...
  • 定义了一个无参数无返回值的委托,那么在FGUI中如何给一个按钮的点击事件添加这个委托,又如何将其删除呢?
  • Unity FairyGUI 自适应扩展

    千次阅读 2018-08-03 14:02:36
    Running Figure 1 - Adapt None 没有任何适配 Figure 2 - Adapt RelationFullScreen ...缺点:当某个分辨率大小超过了FairyGUI内的设计大小是,就会出现一些内容适配显示不完整,等问题,如:背景图,设计为...
  • fairyGUI界面控件的基本制作和功能实现 1.学习地址:官网和泰课在线 fairyGUI官网: http://www.fairygui.com/tutorial 泰课在线: http://www.taikr.com/cloud/search?q=fairyGUI 2.按钮 ...
  • FairyGUI笔记:进度条(十六)

    千次阅读 2018-11-08 09:20:21
    命名约定 bar 当进度改变时,改变“bar”对象的宽度。一般用于横向的进度条。注意:一定要设置bar对象的宽度为进度条处于最大值时的宽度。 “bar”元件可以是任何类型,不限制于图片。 特别的,如果“bar”对象是...
  • FairyGUI 生成模板修改

    2020-06-22 19:25:04
    /** This is an automatically generated class by FairyGUI. Please do not modify it. **/ using ETModel; using FairyGUI; namespace ETHotfix.Main { [ObjectSystem] public class UI_SettingAwakeSystem ...
  • cocos creator FairyGUI

    2020-03-19 14:06:12
    (1)当组件扩展为按钮时,按下按钮时,只让按钮里的某一图片变暗效果 使用控制器按下时,将需要变暗的图片的颜色改为#CCCCCC 教程:图片->实例属性->亮度 (2)使用动效改变组件透明度时,如果该组件里有矩形...
  • FairyGUI中创建遮罩

    千次阅读 2017-04-08 19:40:15
    下面让我们在FairyGUI编辑器中创建一个List组件,并导入到Unity中显示,没有添加任何遮罩,List的遮挡区域是一个方形.现在我们为List添加一个遮罩来限制List的显示区域和触摸区域.首先导入一张带Alpha通道的不规则图片...
  • 自读FairyGUI以及源码分析

    千次阅读 2018-09-09 17:42:37
     这里简单介绍一下自己看了几天对FairyGUI的一些认识,以及对和UGUI一样,理解的Text,NGraphic,Image,Shape这几个类的主要功能。只要是关于在Unity里面的使用,这里只是写一下自己对源码的一些认识和理解,有错误的地方...
  • 这里写自定义目录标题 素材管理 可以直接将图片(Gif)、声音(mp3)、动画、文字等素材从资源浏览器拖动到库中。 资源UrlUIPackage.getItemURL(“包名“,“资源名”) AudioClip clip = (AudioClip)UIPackage....
  • FairyGUI资源

    2018-10-10 09:48:02
    用于UI编辑,美术和策划都可以轻松上手,工具中提供各种案例方便学习和使用
  • FairyGUI Unity评估

    万次阅读 2017-11-09 15:26:42
    FairyGUI是一款UI制作的编辑器,它是一个跨平台的UI编辑器,支持多个开发平台,当然,对我们而言,它支持Unity,还有Egret,Egret和Unity有一点关系,它支持从Unity导入数据。 http://www.fairygui.com/是它的官网...
  • FairyGUI插件

    2018-01-24 14:44:15
    一款非常好用的FairyGUI-Editor_3_4_3。内附视频教程,解压可用
  • 需求环境 通常在项目中我们会使用MVC的方式去构建界面框架,而以往我们也会使用NGUI,UGUI,或者DaikonGUI等等方案去实现界面的搭建。 这些UI方案各有优点,也都适用于我们的工程,但在实际项目中,热更新的逻辑...
  • FairyGUI中常用的方法

    2020-02-29 00:05:58
    素材管理 可以直接将图片(Gif)、声音(mp3)、动画、文字等素材从资源浏览器拖动到库中。 资源Url UIPackage.getItemURL(“包名“,“资源名”) AudioClip clip = (AudioClip)UIPackage.GetItemAsset(“包名称”,”...
  • pivotAsAnchor 设置顺序必须在pivot 之后 this.pivot = new Vector2(0.5f, 0.5f); this.pivotAsAnchor = true;

空空如也

1 2 3 4 5 ... 20
收藏数 563
精华内容 225
关键字:

fairygui