FairyGUI笔记:Component(九)

  • Component

自定义数据 可以设置一个自定义的数据,这个数据FairyGUI不做解析,按原样发布到最后的描述文件中。开发者可以在运行时获取。获取方式根据SDK版本有所不同,如果是支持XML包格式的SDK,获取方式为:

//Unity/Cry
aComponent.packageItem.componentData.GetAttribute("customData");
//Cocos2dx/Vision
aComponent->getPackageItem()->componentData->RootElement()->Attribute("customData");
//LayaAir
aComponent.packageItem.componentData.getAttribute("customData");
//Egret
aComponent.packageItem.componentData.attributes.customData;
//AS3/Starling
aComponent.packageItem.componentData.@customData;

如果是支持二进制包格式的SDK,获取方式为:

//Unity/Cry/Laya/Egret
aComponent.baseUserData;
//Cocos2dx/Vision
aComponent->getBaseUserData();

穿透

//true表示不可穿透,false表示可穿透。
aComponent.opaque = false;

注意:图片和普通文字是不接受点击的,如果一个只含有图片或普通文字的组件,设置了点击穿透,那么整个组件就是完全穿透了,不会拦截到任何点击。

  • 像素点击测试

有些特殊需求,需要用到不规则区域的点击测试。首先你要准备一张包含不规则区域的图片,图片里不透明的像素代表接受点击的区域,透明的像素代表点击穿透的区域,组件里超出图片范围的也是可穿透的区域。

把这张图片拖入舞台,然后在组件的“像素点击测试”属性里,选择这张图片。

  • 遮罩

矩形遮罩

将组件的“溢出处理”设置为“隐藏”或者“滚动”,那么组件就带了矩形遮罩。超出组件(矩形区域-边缘留空)的区域都不可见。无论在什么平台,这种遮罩的效率是最高的。

自定义遮罩

可以设置组件内一个图片或者图形作为组件的遮罩。这种遮罩一般都是使用模板测试(Stencil Op)技术。各个平台支持的力度不同:

  • AS3/Starling/Egret/Laya 使用图形(Graph)作为遮罩时,有图形的区域内容可见,例如,一个圆形,则圆形区域内可见,其他区域不可见。

    不能使用图片(Image)作为遮罩,因为使用图片作为遮罩也是取其矩形区域而已,用一个矩形(Graph)的图形效果是一样的。

    Starling版本要使用自定义遮罩必须在应用程序描述文件里加上:

     

    <initialWindow>

    <depthAndStencil>true</depthAndStencil>

    </initialWindow>

  • Unity 使用图形(Graph)作为遮罩时,有图形的区域内容可见,例如,一个圆形,则圆形区域内可见,其他区域不可见。

    使用图片(Image)作为遮罩时,图片内透明度为0的像素对应区域的内容不可见,反之可见。超出图片区域的内容不可见

反向遮罩(挖洞)

效果和正常遮罩相反,也就是可见的区域变不可见,不可见的区域变可见。目前仅Unity平台支持,例如:

使用图形(Graph)作为遮罩时,有图形的区域内容不可见,例如,一个圆形,则圆形区域内不可见,其他区域可见。

使用图片(Image)作为遮罩时,图片内透明度为0的像素对应区域的内容可见,反之不可见。超出图片区域的内容可见

注意:

  1. 当遮罩发生时,点击测试也同样会发生变化,只有显示出来的内容才接受点击检测,被遮住的内容不接受点击检测。
  2. 对于正在编辑的组件,遮罩只有在预览时才能看到效果。
  3. 定义了遮罩的组件,其内部的元件永远无法和外部的元件合并Draw Call,因为他们有不同的材质属性。
  • 扩展

从提示可以看到,FairyGUI中“扩展”的定义方式是以”名称约定“为基础的。一个按钮,可以带有标题和图标,这个标题(一般是一个文本)和图标(一般是一个装载器)需要你自己放置到组件中,并把他们名字设置为title和icon,就像这样:

然后我们测试一下这个刚制作好的组件。把按钮组件拖到另一个组件中,并设置一下“标题”和“图标”,如下图

效果出来了。这说明标题文本被自动设置到了名称为“title”的文本元件上,图标被自动设置到了名称为“icon”的装载器元件上。

如果按钮组件里没有放置名称为icon的装载器控件呢?那么设置图标就没有效果,仅此而已。其他约定的处理方式也相同。不会有任何报错。

  • GComponent

组件支持动态创建,例如:

GComponent gcom = new GComponent();
gcom.SetSize(100,100);
GRoot.inst.AddChild(gcom);

动态创建的组件是空组件,可以作为其他组件的容器。一个常见的用途,如果你要建立一个多层的UI管理系统,那么空组件就是一个合适的层级容器选择。动态创建的组件默认是点击穿透的,也就是说如果直接new一个空组件作为接收点击用途,你还得这样设置:

//设置组件点击不穿透。
gcom.opaque = true;

如果要创建UI库里的组件,应该使用这样的方式:

GComponent gcom = UIPackage.CreateObject("包名","组件名").asCom;
GRoot.inst.AddChild(gcom);

FairyGUI和Flash/Cocos类似,采用树状的结构组织显示对象。容器可以包含一个或多个基础显示对象,也可以包含容器。这个树状结构称为显示列表。FairyGUI提供了API管理显示列表。

  • 显示列表管理

  • numChildren 获得容器内孩子元件的数量。

  • AddChild AddChildAt 向容器内添加元件。前者将元件添加到显示列表的队尾;后者可以指定一个索引控制元件的插入位置。

  • RemoveChild RemoveChildAt RemoveCihldren 从容器内删除元件。当元件从显示对象中移出时,将不再占用显示资源。但元件从显示列表移出后,只是不显示,并没有销毁,如果你没有保存这个对象的引用留待后续使用,或者没有调用对象的Dispose方法销毁对象,那么会产生内存泄露。

  • GetChild GetChildAt 通过索引或名称获得元件引用。元件的名字是允许重复的,在这种情况下,GetChild返回第一个匹配名称的对象。

  • GetChildIndex 获得指定元件在显示列表中的索引。

  • SetChildIndex SwapChildren SwapChildrenAt 设置元件在显示列表中的索引。

  • 渲染顺序

在FairyGUI中,显示列表是以树形组织的,下面说的渲染顺序均指在同一个父元件下安排的顺序,不同父元件的元件是不可能互相交错的,这是前提,请注意。

显示对象的渲染顺序取决于它的显示列表中的顺序,顺序大的后渲染,即显示在较前面。一般来说,我们都是使用AddChild或SetChildIndex调整渲染顺序。例如如果要一个元件显示在容器的最前面,那调用AddChild(元件)就可以了,AddChild是可以重复调用的。也可以调用SetChildIndex设置对象在显示列表中的具体位置,例如SetChildIndex(元件,0)就可以将元件置于最底层。

还有另外一个因子可以影响渲染循序,它就是GObject.sortingOrder。这个属性只用于特定的用途,不作常规的使用。它一般用于类似固定置顶的功能,另外,永远不要将sortingOrder用在列表中。sortingOrder越大,则渲染顺序越后,即显示到更前面的位置。一般情况下,sortingOrder为0,这时渲染顺序由显示对象在显示列表中的顺序决定。sortingOrder可以令你更灵活的控制渲染循序。例如,如果希望一个元件始终保持在其他元件上方,可以设置其sortingOrder一个较大的整数值,这样无论容器使用AddChild添加了多少元件,这个元件依然显示在最前面。(sortingOrder的效率较差,勿做频繁调用的用途)

上面提到的都是调整对象在显示列表中的顺序,如果不想调整这个顺序的同时,又要调整渲染顺序,组件还提供了另一种方式。

//升序,这是默认值,按照对象在显示列表中的顺序,从小到大依次渲染,效果就是序号大的显示在较前面。
aComponent.childrenRenderOrder = ChildrenRenderOrder.Ascent;
//降序,按照对象在显示列表中的顺序,从大到小依次渲染,效果就是序号小的显示在较前面。
aComponent.childrenRenderOrder = ChildrenRenderOrder.Descent;
//拱形,需要指定一个顶峰的索引,从两端向这个索引位置依次渲染,效果就是这个位置的对象显示在最前面,两边的对象依次显示在后面。
aComponent.childrenRenderOrder = ChildrenRenderOrder.Arch;
aComponent.apexIndex = 3; //索引为3的对象显示在最前面。
  • 绑定扩展类

可以绑定一个类为组件的扩展类。首先,编写一个扩展类:

public class MyComponent : GComponent
{
    GObject msgObj;
    //如果你有需要访问容器内容的初始化工作,必须在这个方法里,而不是在构造函数里。各个SDK的函数原型的参数可能略有差别,请以代码提示为准。
    override protected void ConstructFromXML(XML xml)
    {
        base.ConstructFromXML(xml);
        
        //在这里继续你的初始化
        msgObj = GetChild("msg");
    }
    public void ShowMessage(string msg)
    {
        msgObj.text = msg;
    }
}

然后注册你的扩展类。注意,必须在组件构建前注册,如果你使用的是UIPanel,那么在Start里注册是不够早的,必须在Awake里,总之,如果注册不成功,90%可能都是注册晚于创建,10%可能是URL错误,这可以通过打印URL排查。

UIObjectFactory.SetPackageItemExtension("ui://包名/组件A”, typeof(MyComponent));

这样就为组件A绑定了一个实现类MyComponent 。以后所有组件A创建出来的对象(包括在编辑器里使用的组件A)都是MyComponent类型。然后我们就可以为MyComponent添加API,用更加面向对象的方式操作组件A。例如:

MyComponent gcom = (MyComponent)UIPackage.CreateObject(“包名“, ”组件A”);
gcom.ShowMessage("Hello world");

注意:如果组件A只是一个普通的组件,没有定义“扩展”,那么基类是GComponent,如上例所示;如果组件A的扩展是按钮,那么MyComponent的基类应该为GButton,如果扩展是进度条,那么基类应该为GProgressBar,等等。这个千万不能弄错,否则会出现报错。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值