The Ultra Engine entity component system allows you to easily add behavior to game objects. This class can be extended to add behavior and properties to an Entity.

Property Type Description
entity Entity* entity this component is attached to. A raw pointer is used to prevent a circular reference
Collide Method called whenever a physics collision occurs
Connect Method creates a new logical connection
Copy Method makes a copy of the component, for copying entities
FireOutputs Method fires a group of logical connections
Load Method called when an actor is loaded or copied
ReceiveSignal Method called when an input is triggered by a logical connection
Save Method called when an actor is saved or copied
Start Method called when a component is added
Update Method called once each time World::Update is called

You can override these methods or add your own in your component class. To add a new component, just create a new .hpp file in your "Source\Components" folder. You can use separate header and code files if you want, but it is more convenient to put everything in a single file that automatically gets included into your project. Compile your project once and the precompiler will detect your new file and update the component system code. The precompiler will automatically generate the files "ComponentSystem.h" and "ComponentSystem.cpp". These files should never be changed by hand, since they will be overwritten every time the precompiler runs.

The precompiler is limited in its ability to parse C++ declarations, so it's a good idea to stick to straightforward C++ syntax.

Using Components

To use components in C++, include the component's header file and add the component to an entity with Entity::AddComponent. The game engine will take care of the rest for you:

#include "UltraEngine.h"
#include "Components/Mover.hpp"

using namespace UltraEngine;

int main(int argc, const char* argv[])
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    //Create a world
    auto world = CreateWorld();

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a camera
    auto camera = CreateCamera(world);
    camera->SetPosition(0, 0, -3);

    //Create a light
    auto light = CreateBoxLight(world);
    light->SetRotation(35, 45, 0);
    light->SetRange(-10, 10);

    //Create a box
    auto box = CreateBox(world);

    //Entity component system
    auto component = box->AddComponent<Mover>();
    component->rotationspeed.y = 45;

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    return 0;

Example Component

The Mover component is about as simple as it gets. It just stores some motion parameters and moves or turns the entity each time Update is called:

#pragma once
#include "UltraEngine.h"

class Mover : public Component

    Vec3 movementspeed;
    Vec3 rotationspeed = Vec3(0, 10, 0);
    bool globalcoords = false;

    //Update method, called once per loop
    virtual void Update()
        if (globalcoords)
            this->entity->Translate(movementspeed / 60.0f, true);
            this->entity->Move(movementspeed / 60.0f);
        this->entity->Turn(rotationspeed / 60.0f, globalcoords);

    //This method will work with simple components
    virtual shared_ptr<Component> Copy()
        return std::make_shared<Mover>(*this);

Component Methods and Members

To call a component method or get a value, first check if a component of the desired type is attached to the entity, and then call the method:

auto component = entity->GetComponent<HealthManager>();
if (component) component->TakeDamage(10);
Copyright © 2023 Ultra Software.
All rights reserved.