关于cc.find,丢到node里用起来不是更方便?

cc.find(‘xxx/yyy/zzz’,this.node) ×
this.node.find(‘xxx/yyy/zzz’) √
再抠一点可以写成动态参数,不用拆分字符串,效率更高
this.node.find(‘xxx’) 效率等同于 this.node.getChildrenByName(‘xxx’)
this.node.find(‘xxx’,‘yyy’,‘zzz’) 效率优于 cc.find(‘xxx/yyy/zzz’,this.node)

QQ图片20240223104441

666,英雄所见略同 :smirk:

个人从来不用这个 api,因为复杂 UI 节点是要调整,根据业务或者是优化性能,在编辑器里就要能够查找到。节点调整要不影响已有代码。你这个 cc.find,简直后期火葬场

cc.find好像是会遍历节点下的所有子节点,不如直接拖到属性里

要找到名称匹配的节点,肯定要遍历啊

可以试试把节点都保存到一个叫ui的map中,节点名字作为key,节点本身作为value。这样调用时直接通过map获取,不用遍历也不用拆解路径,例如有个node1节点,this.ui[“node1”],直接获取到,缺点就是如果存在两个同名字的会覆盖,可以做个警告,相同名字的节点会被警告出来,然后还能加一些规则,例如节点名以下划线开头命名的,不会存入uiMap等之类的规则。优势就是不用再写@property了,直接都在uiMap获取到。并且调整节点树路径也不会有影响。

import { _decorator, Component, Node } from "cc";
const { ccclass } = _decorator;

@ccclass("UIComp")
export class UIComp extends Component {
    ui: { [nodeName: string]: Node } = {};

    __preload() {
        this.walkUI(this.node);
    }

    walkUI(node: Node) {
        if (node.name.chatAt(0) == "_") return;
        if (this.ui[node.name]){
            console.warn("存在相同名称的节点", node.name);
            return;
        }
        this.ui[node.name] = node;
        node.children.forEach(c => this.walkUI(c));
    }
}
1赞

以前接手过一个 fgui 的项目,是这个方案

这么搞太隆重了吧,占用内存,而且每次增删节点还要维护这个map

跟我们项目解决方案一样,打开界面时把所有节点扔到map中,这个map不用维护,跟prefab一致就行。随取随用。确实会占用少量内存,但效率上提升会更多吧。

中途添加节点 map 不维护吗

中途加的节点不维护,中途创建的节点使用者自己保存或者使用this.node.getChildByName

那也用不上map吧,把高频使用的节点保存起来,其他节点随用随取好了

这个api我们一般用来让策划通过配置获得节点 从而实现配置相关的可复用业务逻辑
平时开发里面基本很少用

我这里跟你的差不多,不过我的MAP是直接映射到组件;比如节点名:lblName就映射为 lblName=>cc.Label,这样用的时候就不用写getComponent了

目前看来你这个方案还比较方便

666 商业互吹

项目不大的话感觉还行,开发的心智成本降低不少 :rofl:,至于创建新节点的话,我这一般都是直接创建新预制,由新增的预制中挂的组件继承了UIComp,这样新组件里会有新的uiMap维护,移除了也会自动销毁,也就是由预制组件自身维护。但如果像新增单条label啥的,一般用新的变量记录起来,uiMap不做新增维护。uiMap只是保存预制上原本的节点。

NoNo,是技术交流,写代码时间长了需要上论坛逛逛调剂一下,但是都找不到几个人聊天

那你干嘛通过组件来维护map呢,一个节点可能添加N个组件,会重复提示重名吧。