Button组件如何设置变灰?

Button设置getComponent(Sprite).grayscale =false,运行时无效,如何设置?以及子级Label,有没有更便捷的方式?

没啥便捷的方法吧,最便捷封装一个自己的button组件

/**

 * hex格式转RGB格式

 * @param hex

 */

public static hexToRgb(hex: string) {

    hex = hex.substring(1);

    hex = hex.toLowerCase();

    let b = new Array();

    for (let x = 0; x < 3; x++) {

        b[0] = hex.substring(x * 2, x * 2 + 2);

        b[3] = '0123456789abcdef';

        b[1] = b[0].substring(0, 1);

        b[2] = b[0].substring(1, 2);

        b[20 + x] = b[3].indexOf(b[1]) * 16 + b[3].indexOf(b[2]);

    }

    return new cc.Color(b[20], b[21], b[22]);

}

/**

 * 将颜色置灰 返回一个新对象

 * @param color

 */

public static colorToGrayScale(color: cc.Color) {

    if (!color) return;

    const gray = color.r * 0.3 + color.g * 0.59 + color.b * 0.11;

    return new cc.Color(gray, gray, gray);

}

/**

 * 设置按钮/节点交互状态

 * 按钮设置不可交互,图片置灰

 * @param node

 * @param interactable 是否可交互

 * @param recursion 递归子节点 默认false

 */

public static setInteractableState(node: cc.Node, interactable: boolean, recursion?: boolean) {

    if (!node?.isValid) return;

    if (recursion === undefined) {

        recursion = false;

    }

    let button = node.getComponent(cc.Button);

    button && (button.interactable = interactable);

    let sprite = node.getComponent(cc.Sprite);

    sprite && (sprite.grayscale = !interactable);

    //文字相关置灰

    const customKey = "custom_origiColor";

    let labFun = (obj: cc.Label | cc.LabelOutline) => {

        if (!obj?.isValid) return;

        if (interactable) {

            let origiColor: string = obj[customKey];

            if (origiColor) {

                if (!origiColor.includes("#")) {

                    origiColor = "#" + origiColor;

                }

                obj.color = this.hexToRgb(origiColor);

                obj[customKey] = null;

            }

        } else {

            if (!obj[customKey])

                obj[customKey] = obj.color.toHEX();

            obj.color = this.colorToGrayScale(obj.color);

        }

    }

    let label = node.getComponent(cc.Label);

    labFun(label);

    let labOutline = node.getComponent(cc.LabelOutline);

    labFun(labOutline);

    if (recursion) {

        for (let child of node.children) {

            this.setInteractableState(child, interactable, recursion);

        }

    }

}

调用 setInteractableState函数就行。

image
https://forum.cocos.org/t/topic/154984
直接设置材质为gray会打断合批,这里采用的是颜色变暗,不打断合批。
而且变暗的视觉效果更美观。