GDevelop 扩展如何用 PropertyDescriptor 声明对象属性并实现 updateProperty
GDevelop 扩展如何用 PropertyDescriptor 声明对象属性并实现 updateProperty【免费下载链接】GDevelop Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.项目地址: https://gitcode.com/GitHub_Trending/gd/GDevelop开发 GDevelop 扩展时如果你的对象object或行为behavior有用户需要在编辑器里修改的字段——文本、数字、开关、资源引用——就需要做两件事用PropertyDescriptor声明这些属性让属性面板自动生成对应的输入控件再实现updateProperty在用户在编辑器中修改属性时把新值写回对象内容。GDevelop 的官方说明文档 Properties-schema-and-PropertiesEditor-explanations.md 描述了这套机制本文结合仓库中 Video 对象和 TextObject 的真实代码给出 JS 扩展的完整操作路径。属性从哪里来PropertyDescriptor 与属性面板的关系在 GDevelop 中一个属性由 GDCore 里的 PropertyDescriptor 类定义。属性面板的显示逻辑是对象/行为声明一组PropertyDescriptor每个含值、类型、标签等这些描述符被映射为 PropertiesEditor 使用的 schema用户改动属性后编辑器回调你实现的updatePropertyC 中为UpdateProperty。文档明确提示只声明属性是不够的还必须实现updateProperty它会在用户在编辑器中修改属性时被调用你可以在其中加入任何需要的校验逻辑。PropertyDescriptor的完整 API 见 Core/GDCore/Project/PropertyDescriptor.h除SetValue、SetType、SetLabel外还支持SetDescription、SetGroup、AddChoice、SetHidden、SetDeprecated、SetAdvanced等链式调用返回PropertyDescriptor因此可以连续调用。在 JS 扩展中声明属性getProperties以仓库中 Video 扩展的 Extensions/Video/JsExtension.js 为例在ObjectJsImplementation上挂一个getProperties函数返回gd.MapStringPropertyDescriptorvideoObject.getProperties function () { var objectProperties new gd.MapStringPropertyDescriptor(); objectProperties .getOrCreate(Looped) .setValue(this.content.loop ? true : false) .setType(boolean) .setLabel(_(Loop the video)) .setGroup(_(Playback settings)); objectProperties .getOrCreate(Volume) .setValue(this.content.volume.toString()) .setType(number) .setLabel(_(Video volume (0-100))) .setGroup(_(Playback settings)); objectProperties .getOrCreate(videoResource) .setValue(this.content.videoResource) .setType(resource) .addExtraInfo(video) .setLabel(_(Video resource)); return objectProperties; };对应的默认值放在videoObject.content中如opacity: 255, loop: false, volume: 100getProperties只负责把content里的值转成描述符。getOrCreate的参数就是属性名后续updateProperty收到的propertyName与它一致。文档中列出的可用setType取值类型编辑器控件附加要求string文本输入框默认类型number数字输入框无boolean复选框无resource资源选择器必须再调用addExtraInfo指定资源类型image、audio、font或json资源类型下值以字符串形式存储但编辑器会显示选择器被选中的资源会加入项目。注意类型字符串的合法取值由负责更新属性网格的类来解释见PropertyDescriptor.h中对SetType的注释上表来自官方说明文档如果你使用文档未列出的自定义类型需要自行确认属性面板一侧是否认识它。实现 updateProperty 把编辑器输入写回 content同一个文件中updateProperty接收属性名和新值按名字分发更新this.content处理成功返回true不认识的名字返回falsevideoObject.updateProperty function (propertyName, newValue) { if (propertyName Opacity) { this.content.opacity parseFloat(newValue); return true; } if (propertyName Looped) { this.content.loop newValue 1; return true; } if (propertyName Volume) { this.content.volume parseFloat(newValue); return true; } if (propertyName videoResource) { this.content.videoResource newValue; return true; } return false; };要点新值newValue始终是字符串数字属性用parseFloat转换布尔属性按编辑器传入的字符串形式判断Video 示例中对Looped判断newValue 1。文档建议在这个方法里加入属性校验逻辑这是编辑器侧值生效前的必经回调。除对象属性外Video 示例还展示了实例instance侧的一对方法updateInitialInstanceProperty和getInitialInstanceProperties签名分别为(instance, propertyName, newValue)和(instance)用于场景内实例的可编辑属性实例不需要额外属性时返回false/ 空的MapStringPropertyDescriptor即可。C 扩展的对应写法C 侧的用法与 JS 基本一致对象实现GetProperties()返回std::mapgd::String, gd::PropertyDescriptor并实现UpdateProperty。官方说明文档给出的 Video 对象示例文档示例照抄自上述文档std::mapgd::String, gd::PropertyDescriptor videoObject::GetProperties() const { std::mapgd::String, gd::PropertyDescriptor properties; properties[_(Opacity)] .SetValue(opacity) .SetType(number) .setLabel(_(Video opacity (0-255))); // ... 其余属性同理 properties[_(Video resource)] .SetValue(videoDataFilename) .SetType(resource) .AddExtraInfo(video) .SetLabel(_(Video resource)); return properties; }仓库中可直接参考的完整 C 实现是 TextObjectTextObject::UpdateProperty位于第 44 行TextObject::GetProperties位于第 139 行行为behavior与实例属性也有各自的对应方法。修改后如何验证属性生效按 Extensions/Video/JsExtension.js 文件头的说明JsExtension.js会被监视编辑器正在运行时改动会被自动导入也可以手动执行导入在newIDE/app/scripts目录下运行node import-GDJS-Runtime.js如果改动后扩展没有加载打开开发者控制台搜索错误信息这是文档给出的排查入口。加载成功后在编辑器中创建你的对象属性面板会按getProperties的声明自动生成输入框类型决定控件样式修改某个属性触发updateProperty返回false的名字不会被处理。限制与后续方向type与extraInformation本身是任意字符串其合法取值由解释它们的类决定PropertyDescriptor.h注释原文新增类型前先核对属性面板一侧的支持范围。官方文档指出PropertyDescriptor与前端 schema 两个概念应当在未来合并原文The two concepts should be merged at some point即这条链路两侧的实现仍在演进改动前建议对照当前版本的 PropertiesMapToSchema.js。属性声明getProperties/GetProperties与回调updateProperty/UpdateProperty缺一不可只声明属性时用户看到的控件不会把值写回对象。【免费下载链接】GDevelop Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.项目地址: https://gitcode.com/GitHub_Trending/gd/GDevelop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考