是的,这是由版本2.3.4编写,3.0及以后需要修改部分代码,晚上回去我看看
好的,改好后发出来一下,我不知道怎么改,谢谢了
我用的也是这个,几千多条,一开始全部加载,但是只有前面20多个时候opacity255其它都是0,所以drawcall不会太高
好吧应该是1000多条~以前也是用别的,发现还是这个比较方便一点
发现了一个问题:就是当页面存在editbox的时候,聚焦输入出现软键盘,关闭输入的时候,列表会变空白或者部分空白 这是一个测试录屏,cocos 2.4.5 设备:华为畅想20
https://husangamerelease.yingzhongshare.com/1624613608790243.mp4
推荐一个DrawCall优化好帮手
问题已经解决了哈 感谢。。。
没想错的话,如果你的字体很大,这个drawcall不一定能到4哦。
另外,极限情况应该是把所有图标放在一个scrollview里,文本放到一个scrollview里,然后两边scrollview绑定偏移量。这种优化应该是可以把drawcall降低到2次吧,如果你再魔改一下引擎,把那个图放到生成的字体纹理里,甚至可以减少到只有1次drawcall
把透明度从0调整到255会导致列表的移动感觉不流畅
调整透明度不会影响流畅,应该是其他原因造成的
我刚刚在项目中用你说的方法试了一下,drawCall确实会降低很多,电脑上很流畅android打包后列表移动就感觉流畅的不如之前了
虽然我想说用循环做更好
不过这个思路不错
怎么加入群阿 想进群
请教一下cocos creator3.1.2 调用不了_calculWorldMatrix 这个方法,没这个api, 求教一下,cocos creator3.1.2应该 怎么实现_calculWorldMatrix 这个方法
3.x 实现
import {
Color,
color,
Component,
error,
mat4,
Mat4,
Node,
Rect,
Renderable2D,
ScrollView,
UIOpacity,
UITransform,
_decorator,
} from "cc";
const { ccclass, property, menu } = _decorator;
/**列表draw call优化组件 */
@ccclass
@menu("tool/list_optimize")
export default class list_optimize extends Component {
/* ***************private*************** */
private _scroll_view: ScrollView;
private _ui_transform: UITransform;
private _temp1_color = color();
private _temp1_m4 = mat4();
private _temp2_m4 = mat4();
/* --------------------------------segmentation-------------------------------- */
onLoad() {
this._scroll_view = this.node.getComponent(ScrollView);
this._ui_transform = this.node.getComponent(UITransform);
if (!this._scroll_view) {
error("不存在ScrollView组件!");
return;
}
this._event_update_opacity();
// 事件监听
{
this.node.on("scrolling", this._event_update_opacity, this);
this._scroll_view.content.on(
Node.EventType.CHILD_REMOVED,
this._event_update_opacity,
this
);
this._scroll_view.content.on(
Node.EventType.CHILD_ADDED,
this._event_update_opacity,
this
);
}
}
/* ***************功能函数*************** */
/**获取在世界坐标系下的节点包围盒(不包含自身激活的子节点范围) */
private _get_bounding_box_to_world(node_: any): Rect {
node_.getWorldMatrix(this._temp2_m4);
Mat4.fromRTS(
this._temp1_m4,
this.node.getRotation(),
this.node.getPosition(),
this.node.getScale()
);
let width = this._ui_transform.contentSize.width;
let height = this._ui_transform.contentSize.height;
let rect = new Rect(
-this._ui_transform.anchorPoint.x * width,
-this._ui_transform.anchorPoint.y * height,
width,
height
);
Mat4.multiply(this._temp2_m4, this._temp2_m4, this._temp1_m4);
rect.transformMat4(this._temp2_m4); // query child's BoundingBox
return rect;
}
/**检测碰撞 */
private _check_collision(node_: Node): boolean {
let rect1 = this._get_bounding_box_to_world(this._scroll_view.content.parent);
let rect2 = this._get_bounding_box_to_world(node_);
// 保险范围
{
rect1.width += rect1.width * 0.5;
rect1.height += rect1.height * 0.5;
rect1.x -= rect1.width * 0.25;
rect1.y -= rect1.height * 0.25;
}
return rect1.intersects(rect2);
}
/**设置节点透明度 */
private set_node_opacity(node_: Node, opacity_n_: number): void {
let rander_comp = node_.getComponent(Renderable2D);
if (rander_comp) {
Color.copy(this._temp1_color, rander_comp.color);
this._temp1_color.a = opacity_n_;
rander_comp.color = this._temp1_color;
} else {
(node_.getComponent(UIOpacity) || node_.addComponent(UIOpacity)).opacity = opacity_n_;
}
}
/* ***************自定义事件*************** */
private _event_update_opacity(): void {
this._scroll_view.content.children.forEach(v1 => {
this.set_node_opacity(v1, this._check_collision(v1) ? 255 : 0);
});
}
}
是真好用!!!
不知道是不是我的使用方式不对,我挂在scrollview节点上,刚打卡页面初始会透明度全 为0,要有滑动才显示内容,是哪里不对吗?cocos版本是2.4.6。
onLoad内执行的首次更新,如果更新时scrollView内的item不在可视区域内那么就会这样,检查下item的坐标
噢噢,我关闭的时候没有还原item的坐标,现在设置了scrollToTop就可以了,谢谢!
先mark一下。。