Skip to main content

Properties

In this chapter you'll learn how to expose different types of Properties from a Jenova C++ Script.

Screenshot_JenovaExposedProperties

Inspector Panel, Exposed Jenova Properties from C++ Script

Jenova allows you to expose various types of properties to the Godot Inspector and manipulate them directly in the game or editor. You can set these properties through the interface or use third-party languages like C#, GDScript, and Python etc.

Benefits of using Properties:

  1. Easily use resources in the scene such as Nodes, Textures, Audios etc. with Drag and Drop support.
  2. Avoid hardcoding values in your C++ Script.
  3. Adjust and test values within your game logic in real-time.

📝 Note : You can get and set properties directly in your C++ Script like any other value.

Just remember, properties must be defined only in sub-types of godot::Variant

📝 Note : Each script instance has its own unique properties; these properties can't be shared across different instances.

Basic Properties

To expose a property from your C++ Script, Simply add JENOVA_PROPERTY inside the Script Block :

JENOVA_PROPERTY(double /* Type */, run_speed /* Name */, 200.0 /* Default Value */)

After compiling your project, you will see the property appear in the Inspector.

Screenshot_JenovaPropertySampleResult1

Inspector Panel, A property with name of run_speed and default value of 200.0 appeared.

Here's an example :

Jenova C++ Script
// Class Name
JENOVA_CLASS_NAME("My C++ Script")

// Script Block Begin
JENOVA_SCRIPT_BEGIN

// Properties
JENOVA_PROPERTY(double, run_speed, 200.0)

// Callbacks
void OnProcess(double _delta)
{
Output("Run Speed : %lf", run_speed);
}

// Script Block End
JENOVA_SCRIPT_END

By compiling above script you will see this :

Screenshot_JenovaPropertySampleResult2

Inspector Panel, By adding JENOVA_CLASS_NAME property area gets a name.

Now, If you run the game, You can modify the property in the Inspector and it will be updated in the Output on-the-fly.

Advanced Properties

The property definer macro JENOVA_PROPERTY is dynamic. You can use more advanced property features in the following form :

JENOVA_PROPERTY(String, label_prefix, "Untitled", Group:"My Props", Usage:PROPERTY_USAGE_EDITOR)

Current valid extra parameters are Group, Hint, HintString, Usage and they can be used in any order.

Here's an example :

Jenova C++ Script
// Class Name
JENOVA_CLASS_NAME("My C++ Script")

// Script Block Begin
JENOVA_SCRIPT_BEGIN

// Properties
JENOVA_PROPERTY(String, label_prefix, "Untitled")
JENOVA_PROPERTY(double, label_value, 1.5f, Group:"Custom Props")
JENOVA_PROPERTY(Color, label_color, Color(1.0f, 0.5f, 0.5f, 1.0f))

...

// Script Block End
JENOVA_SCRIPT_END

By compiling above script you will see this :

Screenshot_JenovaPropertySampleResult3

Game Debug Mode, Property label_value is grouped in Custom Props

Here's a more advanced example :

Jenova C++ Script
// Class Name
JENOVA_CLASS_NAME("Dummy Controller")

// Script Block Begin
JENOVA_SCRIPT_BEGIN

// Properties
JENOVA_PROPERTY(int, dummy_state, 0, Hint:PROPERTY_HINT_ENUM, HintString:"Idle,Walk,Run", Usage:PROPERTY_USAGE_EDITOR)

// Script Block End
JENOVA_SCRIPT_END

By compiling above script you will see this :

Screenshot_JenovaPropertySampleResult4

Inspector Panel, Result of the Dummy State property with advanced parameters.

Resources/References

By using Jenova, you can define Objects, Resources and References as properties, providing a highly flexible C++ script for your nodes.

Resource Property

Resource properties are useful for adding customizable resources to your script. For example, you can expose a Material property, enabling direct access to a material resource in your C++ code. Simply use a registered engine type along with a default initializer to achieve this.

Here's an example :

Jenova C++ Script
// Class Name
JENOVA_CLASS_NAME("Material Overrider")

// Script Block Begin
JENOVA_SCRIPT_BEGIN

// Properties
JENOVA_PROPERTY(StandardMaterial3D, material, StandardMaterial3D())

// Routines
void OnReady(Caller* instance)
{
auto mesh = GetSelf<MeshInstance3D>(instance);
mesh->set_material_override(Ref<StandardMaterial3D>(&material));
}

// Script Block End
JENOVA_SCRIPT_END

Upon compiling the script, an exposed material property will become available. Assigning a StandardMaterial3D to this property enables runtime modification.

Screenshot_JenovaPropertySampleResult5

Inspector Panel, Exposed Material property with an assigned material resource.

Reference Property

Reference properties are useful for directly accessing nodes in your scene. To create reference properties, simply expose a NodePath property in your C++ script and this allows you to assign nodes from the SceneTree directly to your script. You can then resolve these nodes by retrieving them through their paths.

Here's an example :

Jenova C++ Script
// Class Name
JENOVA_CLASS_NAME("Character Controller")

// Instances
CharacterBody3D* characterBody = nullptr;

// Script Block Begin
JENOVA_SCRIPT_BEGIN

// Properties
JENOVA_PROPERTY(NodePath, playerCharacter, "")

// Routines
void OnAwake(Caller* instance)
{
// Solve Assigned References
auto self = GetSelf<Node>(instance);
characterBody = GetNode<CharacterBody3D>(String(self->get_path()) + "/" + playerCharacter);
}
void OnProcess(Caller* instance, double delta)
{
// Use Assigned References
Vector3 cbPos = characterBody->get_position();
Output("%s Position : %lf %lf %lf", GetCStr(characterBody->get_name()), cbPos.x, cbPos.y, cbPos.z);
}

// Script Block End
JENOVA_SCRIPT_END

By compiling the script above you will see a reference slot appear in Inspector. You can then drag and drop any node into the slot to assign it.

Tip : Properties will be updated at Debug Mode when changed from editor!

Attention

Since the Jenova Property Macro doesn't change the preprocessed source code and is only used by the Jenova Source Code Parser.

You need to clear the cache database before building to see the changes. Simply use Jenova > Tools > Clear Cache Database from menu.

Warning
  • Do not break Jenova Property Macro into multiple lines; It must be in one line.
  • Do not mix flags in Usage parameter as it's not supported yet.