Skip to content

Components

Adrian edited this page Feb 5, 2021 · 13 revisions

[Outdated documentation. To be updated]

Overview

Components are the behavioral brains of Zenith game objects. They can easily be plugged in and reused to provide highly extensible game object operations. We can easily create our own by subclassing the ZComponent class. The ZComponent interface itself subclasses ZProcess, so all of the relevant methods are avaiable.

We initialize any ZComponent by calling it’s corresponding Initialize method, or using the overloaded initializer of the same name that takes a ZOFNode as it’s parameter.

    auto comp = std::make_shared<ZComponent>();
    auto anotherComp = std::make_shared<ZComponent>();
    comp->Initialize(node);
    // Subclasses may overload Initialize with different argument lists
    anotherComp->Initialize();

These components can then be added to game objects, as described in the Game Objects page

    gameObject->AddComponent(comp);
    anotherGameObject->AddComponent(anotherComp);

Zenith has a fresh set of useful, built-in components:

ZGraphicsComponent

ZCameraComponent

ZPhysicsComponent

ZScriptComponent

ZGraphicsComponent

If a game object intends to appear on screen, it needs a ZGraphicsComponent. This component holds the model and shader information necessary to draw an object into the current framebuffer.

This component can be initialized in one of two ways. The first is the standard ZOFNode initializer mentioned in the overview above. The second requires a ZModel pointer and a ZShader pointer:

    auto graphicsComp1 = std::make_shared<ZGraphicsComponent>();
    auto graphicsComp2 = std::make_shared<ZGraphicsComponent>();
    graphicsComp1->Initialize(node);
    graphicsComp2->Initialize(model, shader);

We can enable object outlines by calling the SetOutline method, optionally passing in a glm::vec4 color parameter:

    graphicsComp1->SetOutline(glm::vec4(0.3f, 0.7f, 0.75f, 1.f));

This is still an experimental feature, but it is useful for debugging or general purpose object selection feedback.

We can also set the active camera through which we wish to render the object, as well as the lights in the scene that will affect the given object.

    graphicsComp1->SetGameCamera(myCamera);
    graphicsComp1->SetGameLights(myLights);

The above two methods are mostly used internally within the engine, but are made public for flexibility.

Adding a material to a game object with a ZGraphicsComponent can be done through the component’s AddMaterial method. A ZGraphicsComponent can support many materials per object, which allows us to set different materials for the different mesh groups of a model.

ZCameraComponent

Attaching a ZCameraComponent to any game object will allow that object to act as a game camera. We can create a camera component with the usual ZOFNode initializer:

    auto cameraComp = std::make_shared<ZCameraComponent>();
    cameraComp->Initialize(node);

We can also also call the ZCameraComponent constructor with the camera type and/or camera position:

    auto cameraComp = std::make_shared<ZCameraComponent>(ZCameraType::Perspective, glm::vec3(1.0f, 10.0f, 10.0f));

Several getters allow us to query some of the camera's properties. Two of the most common, needed by renderable game objects, are ViewMatrix and ProjectionMatrix:

    // Returns a glm::mat4 view matrix
    cameraComp->ViewMatrix();
    // Returns a glm::mat4 projection matrix
    cameraComp->ProjectionMatrix();

As a bonus, we can set the camera movement style to either ZCameraMovementStyle::Normal or ZCameraMovementStyle::Follow, the latter giving us a damped follow camera effect.

    cameraComp->SetMovementStyle(ZCameraMovementStyle::Follow);

After creating and initializing our camera component, we can attach it to a game object using the game object's AddComponent method, add this to our game and set it as the active camera if we wish.

    cameraObject->AddComponent(cameraComp);
    game->AddGameObject(cameraObject);
    game->SetActiveCamera(cameraObject);

Note that we can access the current game using ZEngine::Game(). I used a simple game variable here to keep it short.

ZPhysicsComponent

The ZPhysicsComponent can be attached to game objects to simulate real world Newtonian mechanics. Zenith uses wrapper classes to allow different physics engines to be swapped in and out, but is currently using the Bullet Physics library as the underlying physics system.

We can create and initialize a ZPhysicsComponent in the standard way, using a ZOFNode initializer:

    auto physicsComp = std::make_shared<ZPhysicsComponent>();
    physicsComp->Initialize(node);

Alternatively, we can build up the physics component by creating an instance and using the necessary setters to supply data:

    physicsComp->SetMass(20.0f); // In Kg
    physicsComp->SetDamping(0.4f);  // Should usually be in the range [0, 1]

We can query any of the set properties with a corresponding getter. We can also add forces and torques to our simulated game objects:

    physicsComp->AddForce(glm::vec3(3.0f, 0.5f, 5.0f));
    physicsComp->AddForceAtPoint(force, point); // both force and point are glm::vec3 types
    physicsComp->AddTorque(torque); // also takes in a glm::vec3

Take a look at the Physics page for more info on how to work with physics in Zenith.

ZScriptComponent

UNDER ACTIVE DEVELOPMENT