There are many plug-ins available on the Cocos Store, but sometimes we need to create some plug-ins ourselves. This time, the developer, muzzik, will share the process and experience of v3.x plug-in development. So let’s make plug-ins together!
First of all, why develop plug-ins?
Any repetitive mechanical labor is meaningless, all mechanical labor can be automated, and plug-ins can help us achieve automation.
What can plug-ins bring to us?
The first is time. Of course, the most significant benefit of solving the automation problem is saving us extra manual operation time. So saving time is the most significant value of the plug-in.
The second is the revenue. We can release the developed plug-ins to the Cocos store to bring convenience to others in the process and additional income to themselves.
The third is ecology. All kinds of plug-ins cover all aspects of development and will help more developers. Each of our plug-ins can add to the Cocos ecology.
The fourth is technology. The technologies required for plug-in development, including but not limited to HTML, CSS, NodeJs, Vue, and the development of plug-ins, can also help us expand our technical scope and increase our personal competitiveness.
This time, through this article, I will share with you the process of developing Cocos Creator 3.x plug-ins from the beginning, advanced and in-depth, and the experience I have accumulated in actual development.
To open the plug-in creation panel, we can open Extensions/Create Extensions from the top menu bar.
Where are the plug-ins located? From the top menu bar, open Extensions/Extensions Manager to find our plug-in. Click Open Folder to open our plug-in root folder.
Since our plug-in may initially rely on some of the npm modules, it will need to be initialized with.
cd to the plug-in root directory.
package.json is a file in the root directory of the plug-in, which contains a lot of information equivalent to the identity card of the plug-in, where the three most important configurations are:
main: related to whether the plug-in can be started properly
panels: the panels can be displayed appropriately.
contributions: Most of the plug-in’s configuration is here.
In development, we often use multiple languages. How can plug-ins be implemented in various languages? In fact, it is created by an i18n folder placed in the root directory of the plug-in. The file name stored in the file is the language code, and the content is an exported object
The basic usage of plug-in multilingual is:
- Used in the script: let str = Editor.I18n.t(‘first-panel.open_panel’); - often used for dynamic display content.
- Used in HTML: ; - often used in panels.
- Used in JSON: “description”: “i18n:first-panel.description”; - used in package.json.
First, we need to start the plug-in panel to register a menu item in the package.json contributions.menu section, write a path, label, and message properties containing the data.
What do these elements represent?
- Menu path: path + label = extension/demo_part1/default panel.
- The message triggered by the menu click: message.
We can write the names of the messages we listen to and an array of methods to trigger in contributions.messages in the package.json file.
All our events are registered in
open-panel is the event we registered, and
open_panel is the name of the triggering method. Since the panel name is not specified, so the trigger is the method inside the
main. Next, we see what the
open_panel method does.
open_panel, we call
Editor.Panel.open, which is the method to open the panel and show the panel name.
Click on the menu here, and our plug-in panel opens.
First of all, we defined some basic properties of the panel in the
contributions.panels within the
title: the title of the panel.
type: dockable | simple (non-dockable).
main: panel entry script folder, default file name is index.js.
size: size information of the panel.
How does the panel display content control?
index.js file, we export the object,
template of the
html content, and
style is the
css content. This piece of content is relatively deep.
Earlier, we talked about how to listen to a message. Here we look at how to send a message.
There are three interfaces for sending messages: send, request, and broadcast, which can be found in the official documentation.
Open the menu Developer → Message Manager List to view them.
The messages in the message manager are not all the messages that exist in the editor, so how do we know what messages are triggered by our operations? Just use the message debugging tool, menu developer/message debugging tool:
- Click the play button (the button next to the broom icon) before starting.
- Click the Pause button when the operation is complete.
This allows us to see all the messages triggered by this operation, including the content of the message parameters.
Simply speaking, a scene script is a script in the same process as the environment in which the editor script runs. We need to use it when we need to call the engine interface, such as loading resources, getting nodes, etc.
load: load callback.
unload: unload callback.
methods: the location of the scene script event function.
We can communicate through messages defined by default in the messaging system:
method: the name of the event function to be triggered.
args: event argument.
The configuration system is a file reading and writing tool used to read and write files in the editor environment.
We can use it within the script without any prerequisites, but note that it must be undefined the first time we get the value before we write the file. We can configure the default value via
tsc (the TypeScript language’s own compiler).
We can compile the script by entering the following command at the command line:
tsc -b[directory where
tsconfigis located]: single compile.
tscconfigdirectory]: listens for compilation (automatically compiles after the TypeScript file has been saved and changes have been made).
Script commands can also be configured, searched, and executed within vscode by ctrl + shift + p.
After the plug-in development is finished, we can publish it to the Cocos Store. Before releasing, we recommend you carefully read the store’s plug-in class resource release specifications:
After confirming the error, log in to the Cocos Developer Center at
Click Store → Seller Center → Post New Resources. Please fill it out and leave it for two or three days for review. If there are any problems, the official team will contact you.
When you are in contact with plug-in development, you may have heard of the main and rendering processes. So what are they?
- Main process: the script running process (plug-in entry script) of the
- Render process: the script runtime of the
package.json(plug-in panel entry script).
- Through the messaging system: the easiest way.
websocket: no one usually does this.
- Inter-process data is not shared but is separate. A common mistake made here is to think that you are using the same data when it is two separate pieces of data that do not interfere with each other between different processes.
- Don’t put expensive computational logic in the main process. It is better to put it in the plug-in rendering process or open a separate sub-process.
element-plus is a common UI component library for the web front-end. Although the Cocos Creator editor also provides some plug-in UI components, they may not meet our needs, so that we can use element-plus.
Plug-in development requires frequent changes to
css, and we do not want to reload the plug-in every time. So how to do that?
We can open the plug-in panel, click the plug-in panel, then press ctrl + shift + i to open the developer tools. You can directly edit the
css in it. The effect is created in real-time, and we can modify the desired effect and then move it to the plug-in source code.
inspector is simply the content displayed by a component in the property
inspector panel. How to define
inspector and declare it in contributions in
The inspector customizes the display of our component properties panel, so how do we interact with the component data? There are two ways.
Scene script. The scene script can get the scene root node through
getSceneand use it to find our component for data access and modification.
- Message system. This is the recommended way to use the editor, as you don’t know the content of the messages, which can be obtained through the message debugger. The editor relies on these messages, such as undo operations.
In plug-in development, we may encounter several copies of the plug-in using the same code. We want to retain only a public code. You can add our public code base path in the plug-in root
But this creates a problem: the path structure is not the same as before the compilation of the plug-in. How to solve it? Here I wrote a small tool: a plug-in compiler, which can automatically modify the path inconsistency in
package.json caused by the reference to the public code base, and automatically copy the dependent
npm packages to the output directory, output zip.
Plug-in compiler - download and use:
It looks complicated, but it’s not that hard to implement. The plug-in panel is also a web interface, and the web interface is embeddable. At the same time, Cocos Creator can also output web packages, so things are pretty simple.
The plug-in panel can display the Creator interface by embedding a link to the specified URL in the
- When debugging: embed the preview URL.
When publishing: open a local
http-serverand point to the compiled web package path.
You may encounter a situation that the main process reports an error, but you can’t debug it. So how do we debug the main process?
First, set the Cocos Dashboard startup options with the path followed by the project root directory.
Then open chrome://inspect/#devices to configure:
- Add localhost:5858 by clicking on configure to the right of Discover network targets.
- Finally, open the corresponding project, and a new item will appear under target, click the blue inspect, then enter the main process developer tools. You can use ctrl + p to search for your own plug-in main.js for debugging:
- Logic on the server. The main code in the server, the plug-in panel is only responsible for the display. Even if the code is stolen, it does not matter.
- Use other languages. Using C, C++ compiled into wasm, basically eliminating the cracking of the core code.
- Obfuscation. In this method, only the gentleman is protected from the villain.
The above is all the content I can share. I hope it will help you! Finally, I recommend a few plug-ins and source code released on the Cocos Store to check out to help you learn more:
SDF texture generation tool.
Plug-in for generating node reference code based on the node name.
Editor menu extensions (used by plug-ins).