Cocos Creator 中使用装饰器进行自动绑定

推荐一个偷懒的方式,使用装饰器自动绑定节点到脚本的属性

背景

用 Cocos Creator 写脚本组件的时候,有时需要场景中一个节点作为这个脚本的属性值。

按照官方文档推荐的方法,需要以下两步

  1. 添加一个 @property 属性,

  2. 在场景中拖入这个节点。

7a54b8c149dc996566224ceea77e29ef.png

为了省去场景中的拖拽,也有这样写法

  1. 添加属性

  2. getChildByName

11e83b4a5644cb0487803ded291ecec3.png

当属性多了,就要写一排相似的代码

b39b7d711d3fe530e986ab89cfa6b25c.png

使用

环境

Cocos Creator 3.8.1

只是为了偷懒

从上面的背景来看,相似的代码可以用装饰器去简化

  1. 添加一个 @child 属性,

2fe63adaa47849862c03e0cfbfa3658e.png

这样就会直接去组件的子节点中寻找对应的需要的节点或组件,实现自动绑定啦!

代码

这代码不是我写的,是一起工作的扫地僧写的。他说这个东西没什么难度,可以分享给大家。

//Decorator.tstype PropertyDecorator = ($class: Record<string, any>, $propertyKey: string | symbol, $descriptorOrInitializer?: any,
) => void;import { Node } from "cc"const searchChild = function (node: Node, name: string) {let ret = node.getChildByName(name);if (ret) return ret;for (let i = 0; i < node.children.length; i++) {let child = node.children[i];if (!child.isValid) continue;ret = searchChild(child, name);if (ret) return ret;}return null;
}const CookDecoratorKey = ($desc: string) => `__ccc_decorator_${$desc}__`const KeyChild = CookDecoratorKey("child_cache");
type ParamType = {name?: string,
};export function child($opt?: ParamType): PropertyDecorator {// eslint-disable-next-line @typescript-eslint/no-unused-varsreturn ($target, $propertyKey: string, $descriptorOrInitializer) => {const cache: { propertyKey: string, childName: string }[] = $target[KeyChild] ??= [];if (!cache.some($vo => $vo.propertyKey === $propertyKey)) {cache.push({ propertyKey: $propertyKey, childName: $opt?.name || $propertyKey });} else {throw new Error(`child 装饰器重复绑定属性:${$propertyKey},class:${$target.name}`);}if (cache.length === 1) {const oldOnLoad: () => void = $target.onLoad || undefined;//$target.onLoad也可以拿到父类的实现$target.onLoad = function () {cache.forEach($vo => this[$vo.propertyKey] = searchChild(this.node, $vo.childName));oldOnLoad && oldOnLoad.apply(this);};}};
}import { Component } from "cc";interface INewable<T = any> extends Function {new(...args: any[]): T;
}const KeyComp = CookDecoratorKey("comp_cache");export function comp($compoentClass: INewable<Component>, $childName?: string, $mute = false): PropertyDecorator {return ($target, $propertyKey: string, $descriptorOrInitializer) => {const cache: { propertyKey: string, compClass: INewable<Component>, childName: string }[] = $target[KeyComp] ??= [];if (!cache.some($vo => $vo.propertyKey === $propertyKey)) {cache.push({ propertyKey: $propertyKey, compClass: $compoentClass, childName: $childName || $propertyKey });} else {if (!$mute) {throw new Error(`comp装饰器重复绑定属性:${$propertyKey},class:${$target.name}`);}return;}if (cache.length === 1) {const oldOnLoad: () => void = $target.onLoad || undefined;//$target.onLoad也可以拿到父类的实现$target.onLoad = function () {cache.forEach($vo => {const node = ($vo.childName ? searchChild(this.node, $vo.childName) : this.node);if (!node) {if (!$mute) {throw new Error(`comp装饰器没有找到适合的node节点:class:${$target.name},组件:${$compoentClass.name},childName:${$childName}`);} else {return;}}this[$vo.propertyKey] = node.getComponent($vo.compClass) || node.addComponent($vo.compClass);});oldOnLoad && oldOnLoad.apply(this);};}};
}

小结

装饰器实现其实就是面向切面的编程思想吧,貌似,可以在这个切面上面进行封装,偷懒写少点代码,然后高阶的实现目的就是依赖注入之类的思想,其实都是为了极限解耦   --BY 扫地僧

a28b644075d19ce0cbb97d92acf7d63c.jpeg

“点赞“ ”在看” 鼓励一下c94881163aa99866e21630a9e9493f05.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/123531.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ORB-SLAM3算法2之开源数据集运行ORB-SLAM3生成轨迹并用evo工具评估轨迹

文章目录 0 引言1 数据和真值1.1 TUM1.2 EuRoc1.3 KITTI2 ORB-SLAM3的EuRoc示例3 ORB-SLAM3的TUM-VI示例4 ORB-SLAM3的ROS各版本示例4.1 单目4.2 单目和IMU4.3 双目4.4 双目和IMU4.5 RGB-D0 引言 ORB-SLAM3算法1 已成功编译安装ORB-SLAM3到本地,本篇目的是用TUM、EuRoc和KITT…

案例分析大汇总

案例分析心得 2018-2022年的案例分析考试内容汇总&#xff08;近五年&#xff09; 架构设计题型 软件系统建模 数据库 Web 系统设计 2018年 胖/瘦客户端 C/S 架构非功能性需求 数据流图DFDE-R图Essential Use Cases(抽象用例)&#xff0c;Real Use Cases(基础用例)信息工…

双目视觉计算三维坐标

一、原理 双目视觉的基本原理&#xff0c;以及公式推导&#xff0c;我参考的b站上的视频&#xff0c;链接如下&#xff1a; 2-线性相机模型-Linear Camera Model-Camera Calibration_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Q34y1n7ot/?p2&spm_id_from333.…

vue 路由懒加载,图片懒加载,组件懒加载

1.路由懒加载 方法一&#xff1a; import { createRouter, createWebHistory } from vue-router;const Home () > import(./components/Home.vue); const About () > import(./components/About.vue); const Contact () > import(./components/Contact.vue);cons…

Android底层摸索改BUG(二):Android系统移除预置APP

首先我先提供以下博主博文&#xff0c;对相关知识点可以提供理解、解决、思考的 Android 系统如何预装第三方应用以及常见问题汇集android Android.mk属性说明及预置系统app操作说明系Android 中去除系统原生apk的方法 取消预置APK方法一&#xff1a; 其实就是上面的链接3&a…

03、SpringCloud -- 动态倒计时 及 当前用户的获取(用户未登录提示其登录)

目录 动态倒计时需求思路代码效果优化获取当前登录用户思路代码前端后端controllerservice接口impl实现效果问题修改动态倒计时 需求 根据不同时间展示不同状态,动态显示时间,如原型图: 思

Lua脚本语言

1. 概念 Lua&#xff08;发音为"loo-ah"&#xff0c;葡萄牙语中的"lua"意为月亮&#xff09;是一种轻量级的、高效的、可嵌入的脚本编程语言。官网Lua最初由巴西计算机科学家Roberto Ierusalimschy、Waldemar Celes和Luiz Henrique de Figueiredo于1993年开…

【JVM】字节码文件的组成部分

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 JVM 一、字节码文件的组成部分1.1 iconst_0…

Linux命令(108)之dirname

linux命令之dirname 1.dirname介绍 linux命令dirname是用来获取文件的指定路径 2.dirname用法 dirname [参数] NAME dirname参数 参数说明-z使用NUL而不是换行符分隔输出--help查看帮助信息--version查看版本信息 3.实例 3.1.获取文件的指定路径 命令&#xff1a; dirn…

聊一下Word2vec-训练优化篇

Word2vec 涉及到两种优化方式&#xff0c;一种是负采样&#xff0c;一种是层序Softmax 先谈一下负采样&#xff0c;以跳字模型为例。中心词生成背景词可以由两个相互独立事件的联合组成来近似&#xff08;引自李沐大神的讲解&#xff09;。 第一个事件是&#xff0c;中心词和…

idea 提升效率的常用快捷键 汇总

点击File --> Settings --> keymap便可进入看到 IDEA 提供的快捷键。我们也可以搜索和自定义所有快捷键 下面13个事我常用的快捷键&#xff0c;后面还有全部&#xff0c;可以当做字典来查 1.当前文件下查找&#xff1a;CtrlF 当前文件下替换&#xff1a;CtrlR 2.当前…

前端的简单介绍

前端核心的分析 CSS语法不够强大&#xff0c;比如无法嵌套书写&#xff0c;倒是模块化开发中需要书写很多重复的选择器 没有变量和合理的样式复用机制&#xff0c;使逻辑上相关的属性值必须字面量的心事重复的输出&#xff0c;导致难以维护 CSS预处理器,减少代码的笨重&#…

前端 :用HTML和css制作一个小米官网的静态页面

1.HTML&#xff1a; <body><div id "content"><div id "box"><div id "top"><div id "top-left"><span id "logo">MI</span><span id "text-logo">小米账…

leetcode-二叉树

B树和B树的区别 B树&#xff0c;也即balance树&#xff0c;是一棵多路自平衡的搜索树。它类似普通的平衡二叉树&#xff0c;不同的一点是B树允许每个节点有更多的子节点。 B树内节点不存储数据&#xff0c;所有关键字都存储在叶子节点上。B树&#xff1a; B树&#xff1a; 二叉…

kafka丢数据的原因

目录 背景kafkaClient代码消息丢失的可能原因broker is downRD_KAFKA_MSG_SIZE_TOO_LARGE分区问题Kafka Broker的处理能力无法跟上&#xff0c;可能会出现以下情况 Some基础知识补充 背景 采用的client是librdkafka&#xff0c;在producerClient Send的数据时候发现会有数据丢…

Maven - 国内 Maven 镜像仓库(加速包,冲冲冲~)

<?xml version"1.0" encoding"UTF-8" ?><!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding…

onclick事件的用法

onclick 事件是一种在网页开发中用来处理用户点击操作的事件。它通常用于 HTML 元素&#xff08;如按钮、链接、图像等&#xff09;&#xff0c;以便在用户单击该元素时触发 JavaScript 函数或执行一些特定的操作。以下是 onclick 事件的用法&#xff1a; HTML 元素上的 onclic…

react关于类组件this指向

在 React 中&#xff0c;类组件中 this 的指向和普通的 JavaScript 类相同&#xff0c;指向当前实例对象。但是&#xff0c;在事件处理函数中&#xff0c;this 的指向会有所不同。 当我们使用类组件的时候&#xff0c;事件处理函数中的 this 默认指向 undefined。为了保证 thi…

一、灵动mm32单片机_开发环境的搭建(Keil)

1、安装Keil MDK。 略。 2、安装芯片对应的Pack包。 (1)这里以MM32F0130单片机为例。 (2)进入灵动微电子官网。上海灵动微电子股份有限公司 (3)点击“支持”→“KEILPacl”。 (3)点击下载Pack包。 (4)下载后&#xff0c;解压下载的压缩包&#xff0c;找到对应的Pack包&…

【ARMv8 SIMD和浮点指令编程】NEON 通用数据处理指令——复制、反转、提取、转置...

NEON 通用数据处理指令包括以下指令(不限于): • DUP 将标量复制到向量的所有向量线。 • EXT 提取。 • REV16、REV32、REV64 反转向量中的元素。 • TBL、TBX 向量表查找。 • TRN 向量转置。 • UZP、ZIP 向量交叉存取和反向交叉存取。 1 DUP (element) 将…