调整透明度不会影响流畅,应该是其他原因造成的
我刚刚在项目中用你说的方法试了一下,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一下。。
循环列表不得行呀,scrollview 抖动腻害,再动态修改位置 就更厉害了
这是说 不在可视范围内 的组件为完全透明,这样可以提高显示帧率?
那这个功能应该做到引擎层面呀!
1.x 时代是这样的,但是对于一些项目,要的就是实时渲染,所以2.x时代,官方修改了,个人认为这才是正确的,如果不需要,就自己设置就好了。
碰撞检测的思路点赞
大佬,新手一枚,用了你的插件,纵向是可以减少dc了,但是横向貌似没用,dc没减少,求解
- item 数量不够多
- this.node.scroll_view.content.parent 尺寸错误
感谢,我用力拉出屏幕dc可以下降,回弹回来又恢复了,数量刚好超出屏幕80多个像素吧
mark一下
有个疑问啊,难道滚动子控件的循环利用 不会比你这种方法好吗?例如 可视区域内最多显示8个item ,我用10个item 通过修改位置 数据刷新的方式 达到和tableview一样的效果,这种方式不会更好吗 ?,你这样隐藏显示的 实际上还是创建了,我有100条数据,难道就一定要创建100个item?