Urho3D Wiki
Register
Advertisement

This section explains how to create C++ components that you can use then in scripting just like you would with the components that come with Urho3D. We'll also discuss how to add them in the editor.

In order to make this work you should perform three steps: Creating the C++ class for the component, registering it to the game engine and register it to the Script API. With these three things you'll have the same functionality as a normal Urho3D component.

Creating your component[]

In order to create the component you can use the following templates. For convenience the templates are provided in a format that's suitable for most editors' snippets (Like Kdevelop or Sublime Text, for example). TODO: I don't know what this format is but every editor I've tried seems to support it.

MyComponent.hpp

    #pragma once

    #include <Urho3D/Urho3D.h>
    #include <Urho3D/Scene/LogicComponent.h>
    #include <Urho3D/Script/APITemplates.h>
 
    using namespace Urho3D;
  
    class ${1:MyComponent} : public LogicComponent {
       OBJECT(${1:MyComponent})
 
    public:
 
        ${1:MyComponent}(Context* context);
    
        static void RegisterObject(Context* context);

        virtual void ApplyAttributes();

        static void BindScriptMethods(asIScriptEngine *engine);

        virtual void Start();
    
        void AddRef() {/* do nothing */}
        void ReleaseRef() {/* do nothing */}

    private:

MyComponent.cpp

    #include "${1:ClassName}.h"
    #include "Debug.h"

    ${1:ClassName}::${1:ClassName}(Context* context) : LogicComponent(context) {
    
    }

    void ${1:ClassName}::RegisterObject(Context* context) {
        context->RegisterFactory<${1:ClassName}>("${2:Category}");
    }

    void ${1:ClassName}::ApplyAttributes() {
    
    }

    void ${1:ClassName}::BindScriptMethods(asIScriptEngine *engine) {
    
    }

    void ${1:ClassName}::Start() {
    
    }


At this point you'll want to fill this template with your Component's logic. Like in Scripting, you can also add the virtual methods Update, FixedUpdate and similar ones that will get auto-called by the engine.

For now just ignore the RegisterObject and BindScriptMethods functions, those will be used in the following sections.

Note: You should do any engine-related initializations (like browsing the scene graph or talking to other components) in the Start and ApplyAttributes methods and leave the constructor only for initialization of your Class' members. The use of ApplyAttributes will become more clear after you've read the next section.

Registering the component to the engine[]

In order for Urho to see your component you should register it to the engine. For that we'll use the RegisterObject method. Note, though, that Urho does not know about this method so you'll need to be calling that at some point during the engine initialization. This is discussed in the following sections.

    void MyComponent::RegisterObject(Context* context) {
        context->RegisterFactory<MyComponent>("Section");
        // Attributes
    }

First, register the component itself. The "Section" string is the submenu the Component will appear in the editor, new sections can be used and the editor will add them to the menu automatically.

After that, you might be interested in registering attributes that can be modified whithin the editor. While on script this is done automatically, here you should declare each individual attribute you want exposed using the ATTRIBUTE macro. Add as many ones as you want like this:

    URHO3D_ATTRIBUTE("Editor Name", type, classField, initial_value, AM_DEFAULT);

Where:

  • "Editor Name" - The name that will be displayed on the editor for this attribute
  • type - The C++ type for this attribute (IntVector2, bool, String...). All the types supported by Variant can go here.
  • classField - The field in your class that's going to hold the attribute. The editor sets this field automatically when the user modifies an attribute.
  • initial_value - The initial value for your attribute. That means you should guarantee this is the initial value, not that it's going to be set automatically. Therfore you should make it consistent with your Class constructor.

Applying the attributes[]

LogicComponent provides a function called ApplyAttributes that can be overriden. This function will be called whenever the user changes an attribute on the editor (or the code changes it programatically). When this function is called, all the fields will be set to its new values, so be sure to correctly update your component's state accordingly.

For example, you might have a String attribute called Mode so you can change your Enemy IA mode from "AGGRESSIVE" to "PEACEFUL". In this function you'd check for that string and adjust the mode accordingly.

Note Unfortunately, Urho doesn't support Enums to be set as attributes.

Registering the component the AngelScript's Script API[]

At this point, you might want to make it so the new created component is available to the script API and you can use it just like a regular component. If you don't need that you can skip this section.

To make this component's API available to AngelScript we'll be using the BindScriptMethods method of the component class. Bear in mind, though, that this method is not anything Urho3D recognises, and thus you will have to also call it at some point during engine initialisation.

The method's implementation should look like this:

TODO: This needs to be finished

Advertisement