cocos creator FairyGUI(日常踩坑)
FGUI日常使用
·
一.列表动态边缘留空
const newMargin = new fgui.Margin();
const margin = this.ui.m_List.margin;
//将列表的边缘留空数据记录到新的Margin上
newMargin.top = margin.top;
newMargin.bottom = margin.bottom;
newMargin.left = margin.left;
newMargin.right = margin.right;
//其它地方调用
newMargin.left = 1;//设置左边缘留空为1
this.ui.m_List.margin = newMargin;//刷新列表边缘留空
二.关联缩放
背景:fgui编辑器不支持关联缩放,按钮效果单独放在最顶层(drawCall)按钮支持缩放,按钮效果spine,跟随缩放的情况
思路:使用自定义函数覆盖了原有的setScale函数(野路子,有更好方案留言改进)
private relationScale(btn: fgui.GButton, relationsItemArray: fgui.GComponent[]): void {
const sourceSetScale = btn.setScale;
btn.setScale = (sx: number, sy: number) => {
sourceSetScale.call(btn, sx, sy);//修改this指向
relationsItemArray.forEach((item: fgui.GComponent) => {
item.setScale(sx, sy);
});
}
}
三.使用外部资源
1.spine
//使用spine数据默认值
const skeleton = skeletonData.skeletonJson.skeleton;
const spW = Math.floor(skeleton.width);//包围盒w
const spH = Math.floor(skeleton.height);//包围盒h
const aX = Math.floor(skeleton.width + skeleton.x);//锚点x
const aY = Math.floor(skeleton.height + skeleton.y);//锚点y
//同步编辑器spine设置大小和锚点
const paintSpItem = this.paintItem.m_PaintSp;
paintSpItem.setSize(spW, spH);
paintSpItem.setSpine(skeletonData, new cc.Vec2(aX, aY), true);
2.图片
const spriteFrame = <cc.SpriteFrame>resInfo.res;
const paintItem = this.paintItem.m_Paint;
const texture = spriteFrame.getTexture();
paintItem.setSize(texture.width, texture.height);
paintItem.texture = spriteFrame;
3.cocos使用fgui已加载资源
const packageData = fgui.UIPackage.getByName('资源所属包名');
const asset = packageData.getItemAssetByName('资源名称');
四.进度条动画
背景:进度条动画在许多动画之间,需要知道进度条动画完成的时机,还需要动画加快效果
const gTweener = pro.tweenValue(90, 1);//进度条有动态的过程
gTweener.setTimeScale(3);//修改进度条动画播放速度
gTweener.onComplete(() => {
//进度条动画完成回调
})
五.资源动态加载、卸载思路
理想效果:只加载bin文件,然后打开界面时,加载基础界面元素依赖资源和创建基础元件,然后逐步加载创建内元素,离开指定系统时,销毁元件和卸载依赖资源
遇到问题:再次进入卸载的系统,重新加载资源和创建元件添加到场景上时,发现资源缺失
解决思路:再次创建元件时,fgui并没有重新索引新加载的资源,需要小改一下源码
UIPackage.prototype.getItemAsset = function (item) {
switch (item.type) {
case fgui.PackageItemType.Image:
if (item.decoded) {//补丁:外部销毁资源:内存decoded重置为undefined
const texture = item.asset.getTexture();
if (!texture.isValid) { item.decoded = undefined; }
}
if (!item.decoded) {
item.decoded = true;
var sprite = this._sprites[item.id];
if (sprite) {
var atlasTexture = this.getItemAsset(sprite.atlas);
if (atlasTexture) {
var sf = new cc.SpriteFrame(atlasTexture, sprite.rect, sprite.rotated, new cc.Vec2(sprite.offset.x - (sprite.originalSize.width - sprite.rect.width) / 2, -(sprite.offset.y - (sprite.originalSize.height - sprite.rect.height) / 2)), sprite.originalSize);
if (item.scale9Grid) {
sf.insetLeft = item.scale9Grid.x;
sf.insetTop = item.scale9Grid.y;
sf.insetRight = item.width - item.scale9Grid.xMax;
sf.insetBottom = item.height - item.scale9Grid.yMax;
}
item.asset = sf;
}
}
}
break;
case fgui.PackageItemType.Atlas:
case fgui.PackageItemType.Sound:
if (item.decoded) {//补丁:外部销毁资源:内存decoded重置为undefined
if (!item.asset.isValid) { item.decoded = undefined; }
}
if (!item.decoded) {
item.decoded = true;
item.asset = this._bundle.get(item.file, ItemTypeToAssetType[item.type]);
if (!item.asset)
cc.error("Resource '" + item.file + "' not found");
}
break;
case fgui.PackageItemType.Font:
if (!item.decoded) {
item.decoded = true;
this.loadFont(item);
}
break;
case fgui.PackageItemType.MovieClip:
if (!item.decoded) {
item.decoded = true;
this.loadMovieClip(item);
}
break;
default:
break;
}
return item.asset;
};
六.遇到的坑
1.fgui源码未处理阶乘问题,导致编辑器效果和游戏内不一致
2.编辑器里加载的spine,界面构造的时候,content最开始会没值(没有加载完,如果开始就对content操作要自行判断)
3.使用虚拟列表时,如果在渲染函数里设置item的尺寸(每个item都不一样高),手动拖动刷新没有问题,设置posY或posX时就会触发列表item部分缺失(原因:源码里先获取的firstIndex,再执行渲染函数,刷新了item的height,导致获得firstIndex是不正确的,在没执行渲染函数之前是不知道item的height的)
4.按钮按下效果为“变暗”,按钮内有单独设置颜色的图片时,该图片颜色异常(按钮变暗也是通过修改颜色实现的,相互冲突)
5.进度条修改value时,bar的width会发生变化(bar不能加关联),如果想要通过修改进度条size的方式实现进度条伸缩的效果,只需给进度条加宽宽关联即可,bar会自动适配
6.元件A做了一种属性关联,那么制作动效的时候,元件A就不能有相关的属性(元件A做了宽宽,高高关联,那么元件A在动效内就不能有Size相关,x,y同理,会互相冲突)
7.列表嵌套列表的情况下,item通过localToGlobal获得世界的坐标偶现错误(未发现问题所在,目前是通过自己计算)
8.如果位图字体图片发布到两张图集,就会导致运行时部分位图字体丢失(表现是只显示最后一张图集的位图字体)
更多推荐
所有评论(0)