Skip to content

Game Objects

Adrian edited this page Feb 5, 2021 · 23 revisions

[Outdated documentation. To be updated]

Overview

A ZGameObject is the central point of focus in any Zenith game. It defines game objects that can be placed and manipulated in the world, whether they are visible or not. It is a subclass of ZProcess, described in the Process page.

We can create a game object simply by calling the ZGameObject constructor, preferably using a pointer, as most objects in Zenith are stored this way:

    auto gameObject = std::make_shared<ZGameObject>();

We can also pass in a position and/or orientation to the constructor. Note that Zenith currently uses glm, the OpenGL Mathematics library, to perform most vector and math operations:

    glm::vec3 position = glm::vec3(1.0f, 0.0f, -3.0f);
    glm::quat orientation = glm::quat(glm::vec3(pitch, yaw, roll));
    auto gameObject = std::make_shared<ZGameObject>(position, orientation);

A third option is to pass a smart pointer to a ZOFNode. This struct is described in more detail in the Zenith Object Format page.

    auto gameObject = std::make_shared<ZGameObject>(node);

We can modify the game object transform by calling any of SetPosition, SetOrientation or SetScale, or directly using the SetModelMatrix method.

    gameObject->SetPosition(glm::vec3(5.0f, 1.0f, -3.0f));
    gameObject->SetOrientation(glm::quat(glm::vec3(pitch, yaw, roll)));

It is also possible to query transform information using the corresponding getters:

    gameObject->Position();
    gameObject->Orientation();
    gameObject->ModelMatrix();

Several other methods of a similar nature are available.

Zenith follows an entity-component model, and therefore makes it trivial to manipulate components on a game object. Note that by design, a game object can only have one component of each type. Check out the Component page for more information on components.

Assuming we have previously defined and initialized a camera component pointer, we can do the following:

    gameObject->AddComponent(cameraComponent);

    auto cameraComp = gameObject->FindComponent<ZCameraComponent>();

    (cameraComponent == cameraComp); // Definately

    gameObject->RemoveComponent<ZCameraComponent>();

As described in the Game page, we must subsequently add this game object to the current game so that it renders and updates as expected.

    ZEngine::Game()->AddGameObject(gameObject);

Skyboxes

Skyboxes are a special kind of game object in Zenith, even though not much is going on under the hood. Albeit, we must handle skyboxes differently than most other game objects.

The ZSkybox class is our skeleton for skyboxes, and we call it’s single argument constructor to create a new one:

    auto skybox = std::make_shared<ZSkybox>(path);

The sole argument to the constructor is a path to the HDRI image we would like to use as our skybox. The image is internally converted into a cube map and used as a texture to this particularly non-interactable game object.

After creating our skybox, we can set it up for our game by using the ZGame SetSkybox method:

    ZEngine::Game()->SetSkybox(skybox);

Lights

Lights are also handled as game objects in Zenith because they share many of the same transformation properties that most other game objects have, and because, after all, real life light emanates from physical objects in the world.

The ZLight subclass is mostly used to hold light data, which is passed into shaders to perform lighting computations. The ZLight constructor optionally accepts a type as it’s parameter:

    ZLight pointLight(ZLightType::Point);

The different light types include ZLightType::Point, ZLightType::Spot, ZLightType::Directional and ZLightType::Hemisphere.

We can adjust the base and ambient colors of our light using the components member:

    ZLight areaLight(ZLightType::Directional);
    areaLight.directional.components.ambient = glm::vec4(0.3f);

For all available properties, take a look at the ZLight declaration.

Clone this wiki locally