Cocos Native Plugin Quick Tutorial

If you want to use third-party native libraries in a native project, you can follow the steps in this article.

This article requires some understanding of native project compilation and generation, which developers can learn about through CMake official website. We have also prepared a sample project GitHub for reference.

Create a native plugin

Basic Setup

  • Create a cocos project with Cocos Creator 3.6+

    Start the CocosCreator application, and run Create an empty project in the chosen folder.

    create

  • Create and save an empty scene

    save scene

  • A native build is needed to be created first to generate the native/ directory.

    Create a build task for any native platform, for example Windows

    build windows

    Run Build, native/ folder should be created after that.

    1. $ tree native/ -L 2
    2. native/
    3. └── engine
    4. ├── common
    5. └── win64
  • Create a folder for the plugin

    1. mkdir -p native/plugins/hello_cocos

Add support for Windows

  • Prepare the folder for Windows

    1. mkdir -p native/plugins/hello_cocos/windows/
  • Copy precompiled hello_cocos library and header files into the plugin directory

    1. $ tree native/plugins/
    2. native/plugins/
    3. └── hello_cocos
    4. ├── include
    5. └── hello_cocos.h
    6. └── windows
    7. └── lib
    8. ├── hello_cocos.lib
    9. └── hello_cocosd.lib
  • Add files hello_cocos_glue.cpp, CMakeLists.txt and hello_cocos_glue-config.cmake

    1. mkdir native/plugins/hello_cocos/src
    2. touch native/plugins/hello_cocos/src/hello_cocos_glue.cpp
    3. touch native/plugins/hello_cocos/src/CMakeLists.txt
    4. touch native/plugins/hello_cocos/windows/hello_cocos_glue-config.cmake

    Now the plugin directory should look like this:

    1. $ tree native/plugins/hello_cocos/
    2. native/plugins/hello_cocos/
    3. ├── include
    4. └── hello_cocos.h
    5. ├── src
    6. ├── CMakeLists.txt
    7. └── hello_cocos_glue.cpp
    8. └── windows
    9. ├── hello_cocos_glue-config.cmake
    10. └── lib
    11. ├── hello_cocos.lib
    12. └── hello_cocosd.lib
  • Edit hello_cocos_glue-config.cmake with following content

    1. set(_hello_cocos_GLUE_DIR ${CMAKE_CURRENT_LIST_DIR})
    2. add_library(hello_cocos STATIC IMPORTED GLOBAL)
    3. set_target_properties(hello_cocos PROPERTIES
    4. IMPORTED_LOCATION ${_hello_cocos_GLUE_DIR}/lib/hello_cocos.lib
    5. IMPORTED_LOCATION_DEBUG ${_hello_cocos_GLUE_DIR}/lib/hello_cocosd.lib
    6. )
    7. include(${_hello_cocos_GLUE_DIR}/../src/CMakeLists.txt)

    Declare an existing library hello_cocos add import it.

  • Edit native/plugins/hello_cocos/src/CMakeLists.txt with following content

    1. set(_hello_cocos_GLUE_SRC_DIR ${CMAKE_CURRENT_LIST_DIR})
    2. add_library(hello_cocos_glue ${_hello_cocos_GLUE_SRC_DIR}/hello_cocos_glue.cpp)
    3. target_link_libraries(hello_cocos_glue
    4. hello_cocos
    5. ${ENGINE_NAME} # cocos_engine
    6. )
    7. target_include_directories(hello_cocos_glue PRIVATE
    8. ${_hello_cocos_GLUE_SRC_DIR}/../include
    9. )
  • Create cc_plugin.json in native/plugins/hello_cocos/

    1. {
    2. "name":"hello-cocos-demo",
    3. "version":"0.1.0",
    4. "author":"cocosdemo",
    5. "engine-version":">=3.6.0",
    6. "modules":[
    7. {
    8. "target":"hello_cocos_glue"
    9. }
    10. ],
    11. "platforms":["windows"]
    12. }

Now the plugin is created and enabled in this project. But it won’t compile, since there is no code in hello_cocos_glue.cpp

Let’s Build again in the build panel to refresh the Visual Studio project.

  • Open the Visual Studio project under build/windows/proj/

Two additional targets are generated

Solution Explorer

If you run the target directly, you will fail with the following link error:

link error

  • Edit hello_cocos_glue.cpp

    ```c++

    include “hello_cocos.h”

    include “bindings/sebind/sebind.h”

    include “plugins/bus/EventBus.h”

    include “plugins/Plugins.h”

  1. // export c++ methods to JS
  2. static bool register_demo(se::Object *ns) {
  3. sebind::class_<Demo> klass("Demo");
  4. klass.constructor<const char *>()
  5. .function("hello", &Demo::hello);
  6. klass.install(ns);
  7. return true;
  8. }
  9. void add_demo_class() {
  10. using namespace cc::plugin;
  11. static Listener listener(BusType::SCRIPT_ENGINE);
  12. listener.receive([](ScriptEngineEvent event) {
  13. if (event == ScriptEngineEvent::POST_INIT) {
  14. se::ScriptEngine::getInstance()->addRegisterCallback(register_demo);
  15. }
  16. });
  17. }
  18. /**
  19. * Regist a new cc plugin entry function
  20. * first param: should match the name in cc_plugin.json
  21. * second param: callback when engine initialized
  22. */
  23. CC_PLUGIN_ENTRY(hello_cocos_glue, add_demo_class);
  24. ```

Start the project in debug mode, a new window should launch.

empty window

Until now, we are not sure if the plugin is enabled or not.

In the output window, we can the debug URL of the devtools

debug url

Open the URL with chrome and type following code in Console

  1. new Demo("World").hello("Cocos")

devtools

The class hello_cocos and its methods are exported successfully!

Add support for Android

  • Add a build task for Android

  • Create a folder for android

    1. mkdir native/plugins/hello_cocos/android
  • Copy precompiled libraries and headers and create hello_cocos_glue-config.cmake

    The folder should look like this:

    1. $ tree native/plugins/hello_cocos/android/
    2. native/plugins/hello_cocos/android/
    3. ├── hello_cocos_glue-config.cmake
    4. ├── arm64-v8a
    5. └── lib
    6. └── libhello_cocos.a
    7. └── armeabi-v7a
    8. └── lib
    9. └── libhello_cocos.a
  • Edit hello_cocos_glue-config.cmake

    ```cmake set(_hello_cocos_GLUE_DIR ${CMAKE_CURRENT_LIST_DIR})

  1. add_library(hello_cocos STATIC IMPORTED GLOBAL)
  2. set_target_properties(hello_cocos PROPERTIES
  3. IMPORTED_LOCATION ${_hello_cocos_GLUE_DIR}/${ANDROID_ABI}/lib/libhello_cocos.a
  4. )
  5. include(${_hello_cocos_GLUE_DIR}/../src/CMakeLists.txt)
  6. ```
  • Update cc_plugin.json

    Add android to platforms field

    1. {
    2. "name":"hello-cocos-demo",
    3. "version":"0.1.0",
    4. "author":"cocosdemo",
    5. "engine-version":">=3.6.0",
    6. "modules":[
    7. {
    8. "target":"hello_cocos_glue"
    9. }
    10. ],
    11. "platforms":["windows", "android"]
    12. }
  • Create an android build task

    Android build

Run Build and debug with Android Studio.

Add support for iOS

  • Add a build task for iOS

    Prepare a folder for iOS

    1. mkdir -p native/plugins/hello_cocos/ios/lib

    Copy precompiled libraries and edit native/plugins/hello_cocos/ios/hello_cocos_glue-config.cmake

    ```cmake set(_hello_cocos_GLUE_DIR ${CMAKE_CURRENT_LIST_DIR})

  1. add_library(hello_cocos STATIC IMPORTED GLOBAL)
  2. set_target_properties(hello_cocos PROPERTIES
  3. IMPORTED_LOCATION ${_hello_cocos_GLUE_DIR}/lib/libhello_cocos.a
  4. )
  5. include(${_hello_cocos_GLUE_DIR}/../src/CMakeLists.txt)
  6. ```

Add support for Mac

  • Add a build task for MacOS

  • Prepare a folder for MacOS

    1. mkdir -p native/plugins/hello_cocos/mac/lib
  • Copy precompiled libraries and edit native/plugins/hello_cocos/ios/hello_cocos_glue-config.cmake

    ```cmake set(_hello_cocos_GLUE_DIR ${CMAKE_CURRENT_LIST_DIR})

  1. add_library(hello_cocos STATIC IMPORTED GLOBAL)
  2. set_target_properties(hello_cocos PROPERTIES
  3. IMPORTED_LOCATION ${_hello_cocos_GLUE_DIR}/lib/libhello_cocos.a
  4. )
  5. include(${_hello_cocos_GLUE_DIR}/../src/CMakeLists.txt)
  6. ```
  • Update cc_plugin.json again**, Add iOS & mac to platforms field

    1. {
    2. "name":"hello-cocos-demo",
    3. "version":"0.1.0",
    4. "author":"cocosdemo",
    5. "engine-version":">=3.6.0",
    6. "modules":[
    7. {
    8. "target":"hello_cocos_glue"
    9. }
    10. ],
    11. "platforms":["windows", "android", "iOS", "mac"]
    12. }

Now a plugin supporting Android, Windows, MacOS & iOS is done.

The final content of the plugins is:

  1. $ tree native/plugins/hello_cocos/
  2. native/plugins/hello_cocos
  3. ├── cc_plugin.json
  4. ├── include
  5. └── hello_cocos.h
  6. ├── src
  7. ├── CMakeLists.txt
  8. └── hello_cocos_glue.cpp
  9. ├── android
  10. ├── hello_cocos_glue-config.cmake
  11. ├── arm64-v8a
  12. └── lib
  13. └── libhello_cocos.a
  14. └── armeabi-v7a
  15. └── lib
  16. └── libhello_cocos.a
  17. ├── ios
  18. ├── hello_cocos_glue-config.cmake
  19. └── lib
  20. └── libhello_cocos.a
  21. ├── mac
  22. ├── hello_cocos_glue-config.cmake
  23. └── lib
  24. └── libhello_cocos.a
  25. └── windows
  26. ├── hello_cocos_glue-config.cmake
  27. └── lib
  28. ├── hello_cocos.lib
  29. └── hello_cocosd.lib

It’s ready to ship.

Distribute with Editor Extension

Follow the steps in Editor Extension to create an Editor Extension, you need to copy the directory native/plugins/hello_cocos into the extension package when Packaging the Extension, then submit.

About upgrade: The editor extension system does not support update detection at the moment. Plugin users need to check in Cocos Store or Dashboard and manually upgrade to the latest version. Of course, developers can still implement their version management based on the existing extension system.