扩展属性检查器面板

属性检查器 作为 Creator 里显示当前选中状态的模块,为大家提供了一些基础的扩展能力。

属性检查器 里,定义了两个层级的数据:

  1. 选中的物体主类型
  2. 渲染主类型内容时,内容里包含的子数据类型

当在 层级管理器/资源管理器 中选中一个节点/资源时,Creator 便会将物体被选中的广播消息发送到 属性检查器。当 属性检查器 接收到消息后,会检查被选中的物体的类型,例如选中的是节点,那么类型便是 node

针对两种类型,允许注册两种渲染器:

  1. 主类型渲染器
  2. 主类型渲染器接收数据开始渲染的时候,允许附带子类型渲染器

示例里选中的是 nodenode 上携带了多个 component,所以主类型就是 node,而子类型则是 component

属性检查器 收到选中物体的广播消息后,首先确定类型,而后 属性检查器 会将收到的数据(物体的 uuid),传递给 node 渲染器,将渲染权限完全移交。

而在 node 渲染器里,会根据自身的实现,渲染到每个 组件 的时候,将该区域的渲染权限交给 子类型渲染器。大部分情况下,我们不需要关注这些。我们先来看看几种常用的的自定义方式吧。

自定义 Component 渲染

默认提供的组件渲染器有时候并不能满足我们的需求,我们可以在插件的 package.json 里这样注册一份数据:

  1. {
  2. "name": "extension",
  3. "editor": ">=3.3.0",
  4. "contributions": {
  5. "inspector": {
  6. "section": {
  7. "node": {
  8. "cc.Label": "./dist/contributions/inspector/comp-label.js"
  9. }
  10. }
  11. }
  12. }
  13. }

在 contributions 数据里,向 属性检查器 提供一份数据,要求渲染 section 区域内的 node 类型物体里的 cc.Label 组件。

然后我们针对这个书写一个 ./dist/contributions/inspector/comp-label.js 文件:

  1. 'use strict';
  2. module.exports = Editor.Panel.define({
  3. $: {
  4. button: 'ui-button[slot=content]',
  5. },
  6. template: `
  7. <ui-prop>
  8. <ui-label value="Button" slot="label"></ui-label>
  9. <ui-button slot="content">Console</ui-button>
  10. </ui-prop>
  11. `,
  12. update(dump: any) {
  13. // TODO something
  14. },
  15. ready() {
  16. this.$.button.addEventListener('confirm', () => {
  17. console.log('Custom Inspector: Label Button...');
  18. });
  19. },
  20. close() {
  21. // TODO something
  22. },
  23. });

Editor.Panel.define 是 v3.3 新增的接口,主要是合并一些数据。

需要兼容之前版本的话可以加一行:

  1. Editor.Panel.define = Editor.Panel.define || function(panel: any) {return panel;}

这样我们就能够在 inspector 内的 Label 组件最后添加一个 button。

这里需要注意的是,多个插件注册的数据是并存的。如果一个的 Component 已经有其他插件注册或者内置了自定义渲染器,那么再次注册的自定义渲染器都会附加在后面。如果一个 Component 没有内置自定义渲染器,使用的是默认的渲染,那么当插件注册渲染器的时候,会完全接管渲染内容。

自定义 Asset 渲染

如果官方资源面板不能满足需求,我们也可以扩展自定义的面板:

  1. {
  2. "name": "extension",
  3. "editor": ">=3.3.0",
  4. "contributions": {
  5. "inspector": {
  6. "section": {
  7. "asset": {
  8. "effect": "./dist/contributions/inspector/asset-effect.js"
  9. }
  10. }
  11. }
  12. }
  13. }

和 Component 注册一样,在 contributions 数据里,向 属性检查器 提供一份数据,请求渲染 “section” 区域内的 “asset” 类型里的 “effect” 资源。

  1. 'use strict';
  2. interface Asset {
  3. displayName: string;
  4. file: string;
  5. imported: boolean;
  6. importer: string;
  7. invalid: boolean;
  8. isDirectory: boolean;
  9. library: {
  10. [extname: string]: string;
  11. };
  12. name: string;
  13. url: string;
  14. uuid: string;
  15. visible: boolean;
  16. subAssets: {
  17. [id: string]: Asset;
  18. };
  19. }
  20. interface Meta {
  21. files: string[];
  22. imported: boolean;
  23. importer: string;
  24. subMetas: {
  25. [id: string]: Meta;
  26. };
  27. userData: {
  28. [key: string]: any;
  29. };
  30. uuid: string;
  31. ver: string;
  32. }
  33. // 兼容 v3.3 之前的版本
  34. Editor.Panel.define = Editor.Panel.define || function(panel: any) {return panel;}
  35. module.exports = Editor.Panel.define({
  36. $: {
  37. button: 'ui-button[slot=content]',
  38. },
  39. template = `
  40. <ui-prop>
  41. <ui-label value="Button" slot="label"></ui-label>
  42. <ui-button slot="content">Console</ui-button>
  43. </ui-prop>
  44. `,
  45. update(assetList: Asset[], metaList: Meta[]) {
  46. // TODO something
  47. },
  48. ready() {
  49. // @ts-ignore
  50. this.$.button.addEventListener('confirm', () => {
  51. console.log('Custom Inspector: Label Button...');
  52. });
  53. },
  54. close() {
  55. // TODO something
  56. },
  57. });

这样我们就能够在 inspector 内的 effect 资源页面最后添加一个 button。

这里也需要注意,多个插件注册的数据是并存的。如果一个的 Asset 已经有其他插件注册或者内置了自定义渲染器,那么再次注册的自定义渲染器都会附加在后面。如果一个 Asset 没有内置自定义渲染器,使用的是默认的渲染,那么当插件注册渲染器的时候,会完全接管渲染内容。

更多自定义方式

通过修饰器定义属性