Some examples of C++ scripts. Share yours too

If you too are waiting for the C++ docs to be written, but cannot wait to code and are struggling with it, why not share here examples of code you made, or common mistakes you encounter.

Flax’s C++ Manual :
Flax’s API tags doc :
Flax’s GitHub sources :

To enable C++ script in you project you must open the file “ProjectFolder/Source/Game/Game.Build.cs” and change this line to true :

BuildNativeCode = true;

otherwise it will not compile and Flax’s build tool will ignore all C++ script.

Here a bunch of includes you might need :

#include “Engine/Scripting/Script.h”
#include “Engine/Input/Input.h”
#include “Engine/Core/Log.h”
#include “Engine/Core/Math/Transform.h”
#include “Engine/Core/Math/Vector3.h”
#include “Engine/Level/Actor.h”
#include “Engine/Level/Level.h”
#include “Engine/Level/Actors/StaticModel.h”
#include “Engine/Level/Actors/Camera.h”
#include “Engine/Physics/Actors/RigidBody.h”
#include “Engine/Physics/Colliders/CharacterController.h”
#include “Engine/Physics/Colliders/SphereCollider.h”
#include “Engine/Engine/Screen.h”
#include “Engine/Engine/Time.h”
#include “Engine/Input/Input.h”
#include “Engine/Content/Asset.h”
#include “Engine/Content/Assets/Model.h”
#include “Engine/Content/Cache/AssetsCache.h”

How to use log :

#include “Engine/Core/Log.h” // <- Don’t forget to include this.
int foo = 4;
bool bar = true;
LOG(Info, “Log are variadic, here my first variable {0}, here the second {1}, etc…”, foo, bar);

For using OnFixedUpdate() function you must enable it in the script’s constructor, otherwise it will never be called:

_tickFixedUpdate = true;

Using API tag to show public member of yours script in Flax’s editor properties window :

API_FIELD() float radial_distance = 1000.0f;
API_FIELD() float latitude = 0.0f;
API_FIELD() float longitude = 0.0f;
API_FIELD() Vector3 orbit = Vector3(0, 70, 0);

How to spawn RigidBody, with loaded model and collider :

// Create rigid body
RigidBody* ball = New<RigidBody>();

// Loading sphere assets
AssetReference<Model> model;
AssetInfo info;
String path("C:\\Program Files (x86)/Flax/Flax_1.0/Content/Engine/Models/Sphere.flax");
if(Content::GetAssetInfo(path, info)) {
	LOG(Info, "LOADED ASSET !!!");
	model.Set(dynamic_cast<Model*>(LoadAsset(info.ID, Model::TypeInitializer)));
} else LOG(Info, "NOT LOADED ASSET !!!");

// Creating static model
StaticModel* ballModel = New<StaticModel>();
ballModel->SetName(String("Model ball"));
ballModel->Model = model;

// Creating collider
SphereCollider* ballCollider = New<SphereCollider>();
ballCollider->SetName(String("Ball collider"));

// Set translation, orientation and scale of rigidbody
ball->SetTransform(Transform(Vector3(0, 8, 0), Quaternion::Identity, Vector3(1)));

// Add it to the world

// Destroy actor after 5 seconds of in game time.
ball->DeleteObject(5.0f, true);

Lock and hide the mouse :


Unlock and show the mouse :


Find actor by name:


Add force to a RigidBody :

dynamic_cast<RigidBody*>(GetActor())->AddForce(speed*cam->GetDirection(), ForceMode::Impulse);

Get input keyboard.

if(Input::GetAction(String(“Name input in settings.”))) { /*Stuff to do on input*/ }

Get input mouse.

float mouseX = Input::GetAxis(String(“Name mouse X in settings.”));

Add movement for a CharacterController:

In your .h :

	API_FIELD() float gravity = -980.665f;
	API_FIELD() float speed = 500;
	API_FIELD() float jump = 500;

	CharacterController* _controller;
	Vector3 _velocity = Vector3(0.0f);

In your .cpp :

void Player::OnFixedUpdate()
	//LOG(Info, "PLAYER's OnFixedUpdate CALLED !!!!!");
	auto t = Time::GetDeltaTime();

	// Apply gravity on velocity if not grounded (physics).
	// V1 = -g*t+V0
	if(!_controller->IsGrounded()) _velocity.Y = gravity*t + _velocity.Y;

	// PLayer's input
	_velocity.X = 0;
	_velocity.Z = 0;
	if(_controller->IsGrounded()) {
		_velocity.Y = 0;
		if(Input::GetAction(String("Jump"))) {
			_velocity.Y = jump;;
	if(Input::GetAction(String("Left"))) {
        _velocity.X = -speed;
	if(Input::GetAction(String("Right"))) {
        _velocity.X = speed;
	if(Input::GetAction(String("Up"))) {
        _velocity.Z = speed;
	if(Input::GetAction(String("Down"))) {
        _velocity.Z = -speed;

	// Translation is an aproximation from velocity.
	Vector3 translation = _velocity*t;
    _controller->AddMovement(translation, Quaternion::Identity);

How to make a procedural mesh (and not a procedural mess) :

void YourScript::OnEnable()
	// Only virtual model can be edited on the fly.
    AssetReference<Model> virtual_model = Content::CreateVirtualAsset<Model>();
    // Setting the number of mesh per LOD.
    // Span<T> are universal representation of a contiguous region of arbitrary memory.
    // Here we want to make space for an array of one single integer, who's value will be
    // the number of meshs per LOD we want. We just want one.
    const int32 meshesCountPerLod = 1; 
    Span<int32> spanMeshesCountPerLod(&meshesCountPerLod, sizeof(int32));

    // Generating procedural mesh and sending data to the GPU, be carefull, it returning FALSE IF SUCCESSFUL !
    if(UpdateMesh(virtual_model->LODs[0].Meshes[0])) LOG(Info, "Mesh NOT updated.");
    else LOG(Info, "Mesh updated !!!");

	// Creating static model, add it to actor
	StaticModel* procedural_static_model = New<StaticModel>();
	procedural_static_model->SetName(String("Procedural Static Model"));
	procedural_static_model->Model = virtual_model;
	procedural_static_model->SetTransform(Transform(GetActor()->GetPosition(), Quaternion::Identity, Vector3(1)));
	// Say we are using LODs[0] for all distance, we do this so if the camera is not near from the model, it will not switch to the next LOD,
	// and because there is none other, this would make the model invisible otherwise.


bool YourScript::UpdateMesh(Mesh& mesh)
	// We scale the point by x100, Flax unit are centimeters,
	// if we don't do that you model will be so small you wouldn't be able to see it.
    const float X = 0.525731112119133606f * 100;
    const float Z = 0.850650808352039932f * 100;
    const float N = 0.0f;
    Vector3 vertices[] = {
        Vector3(-X, N, Z),
        Vector3(X, N, Z),
        Vector3(-X, N, -Z),
        Vector3(X, N, -Z),
        Vector3(N, Z, X),
        Vector3(N, Z, -X),
        Vector3(N, -Z, X),
        Vector3(N, -Z, -X),
        Vector3(Z, X, N),
        Vector3(-Z, X, N),
        Vector3(Z, -X, N),
        Vector3(-Z, -X, N)
    uint32 triangles[] = {
        1, 4, 0, 4, 9, 0, 4, 5, 9, 8, 5, 4,
        1, 8, 4, 1, 10, 8, 10, 3, 8, 8, 3, 5,
        3, 2, 5, 3, 7, 2, 3, 10, 7, 10, 6, 7,
        6, 11, 7, 6, 0, 11, 6, 1, 0, 10, 1, 6,
        11, 0, 9, 2, 11, 9, 5, 2, 9, 11, 2, 7

    // Most functions in flax return true if somethings fail, it a little counter-intuitive
    // but it's important you know and don't forget that. It's for avoiding to add ! to condition clause.
    // This is the case of this function, it will return false if successful.
    return mesh.UpdateMesh(
        (uint32) 12,    // uint32 vertexCount
        (uint32) 20,    // uint32 triangleCount

I may edit this post to add more examples. Don’t hesitate to post your finding here too.


How to handle JSON Assets!

I’ve been trying to expand the C++ stuff on the docs, heres how you can create and access your very own JSON Asset!


#pragma once

#include <Engine/Core/ISerializable.h>
#include <Engine/Core/Types/BaseTypes.h>
#include <Engine/Content/Assets/Model.h>
#include <Engine/Scripting/ScriptingType.h>

/// <summary>
/// Contains data 
/// </summary>
API_CLASS() class GAME_API DataExample : public ISerializable



    API_FIELD(Attributes = "Range(0, 20), EditorOrder(0), EditorDisplay(\"Data\")") 
    float Field1 = 20.0f;

    API_FIELD(Attributes = "Range(1000, 10000), EditorOrder(1), EditorDisplay(\" Data\")")
    float Field2 = 1000.0f;

    API_FIELD(Attributes = "Limit(0, 20), EditorOrder(2), EditorDisplay(\"Data\")")
    int32 Field3 = 10;

    API_FIELD(Attributes = "EditorOrder(3), EditorDisplay(\"Data\")")
    Vector3 Field4 = Vector3(0.1f);


#pragma once

#include "Engine/Scripting/Script.h"
#include <Engine/Core/Types/BaseTypes.h>
#include <Engine/Content/JsonAsset.h>
#include <Engine/Debug/DebugLog.h>
#include <Engine/Content/AssetReference.h>

API_CLASS() class GAME_API MyScript : public Script


    API_FIELD(Attributes = "AssetReference(typeof(DataExample))")
    AssetReference<JsonAsset> MyData;

    // [Script]
    void OnEnable() override;
    void OnDisable() override;
    void OnUpdate() override;
    void OnStart() override
        auto obj = (DataExample*)MyData.Get()->Instance;
    	DebugLog::Log(String::Format(TEXT("{0}"),  obj->Field2));

Hi, I repeated your code, but for some reason the model is not displayed in the game. Maybe the Flax API has changed and this code needs updating?