Jump to content
  • entries
    4
  • comments
    0
  • views
    1,203

Mouse Movement Controller


Andy90

665 views

 Share

This component generates a Mouse Movement Controller featuring a free-look mode. Typically, such character controllers find application in ARPG (Action Role-Playing Game) or RTS (Real-Time Strategy) games. In this setup, you observe the character from a top-down perspective and direct their movement to a specified position by clicking the left mouse button.

image.thumb.png.d92e724e8dd5b7da95d276be4efd0c17.png

The Component itself need the terrain name and the name for the walk animation. Also your character needs an idle animation. 

You can switch into the "free look mode" by pressing the tab key. Within the "free look mode" you are able to move the camera with "W" "A" "S" "D" free around. If you press tab again you switch the mode back to the character. 

1. C++ Header

#pragma once
#include "UltraEngine.h"
#include "GatherWaterTask.h"

using namespace UltraEngine;

class MouseMovementController : public Component
{
private:
    shared_ptr<Map> scene;
    shared_ptr<NavMesh> nav_mesh;

    bool freeLook = false;
public:
    string terrainName;
    string animationName;
    Vec3 destination;

    shared_ptr<NavAgent> agent;
    shared_ptr<Terrain> terrain;
    shared_ptr<Camera> camera;
    
    MouseMovementController();

    void Start();
    void Update();
    bool Load(table& properties, shared_ptr<Stream> binstream, shared_ptr<Map> scene, const LoadFlags flags);
    bool Save(table& properties, shared_ptr<Stream> binstream, shared_ptr<Map> scene, const SaveFlags flags);
    shared_ptr<Component> Copy();
};

 

2. C++ Source File

#include "UltraEngine.h"
#include "MouseMovementController.h"

MouseMovementController::MouseMovementController() {
    this->name = "MouseMovementController";
}

/// <summary>
/// Setup the Controller
/// </summary>
void MouseMovementController::Start() {
    auto entity = GetEntity();
    ///Create the camera and attach them to the player character
    this->camera = CreateCamera(entity->GetWorld());
    Vec3 currentcameraposition = TransformPoint(0, 15, 5, entity, nullptr);
    //this->camera->SetParent(entity);
    this->camera->SetPosition(currentcameraposition, true);
    this->camera->SetRotation(Vec3(45, 0, 0));
    this->camera->SetFov(40);
    this->camera->Point(entity);

    ///Creates a navmesh ToDo: Has to changed when the NavMesh bug is fixed
    this->nav_mesh = CreateNavMesh(entity->GetWorld(), 5, 8, 8);
    this->nav_mesh->SetPosition(0, 0, 0);
    this->nav_mesh->Build();

    ///Create a new NavAgent for the player character
    this->agent = CreateNavAgent(this->nav_mesh);
    entity->Attach(agent);
}

//Update method, called once per loop
void MouseMovementController::Update()
{
    auto entity = GetEntity();
    auto window = ActiveWindow();
    auto world = entity->GetWorld();

    if (window) {
        ///Set the destination if the player hits the left mouse button
        if (window->MouseHit(MOUSE_LEFT)) {
            auto mousePosition = window->GetMousePosition();
            auto pick = this->camera->Pick(window->GetFramebuffer(), mousePosition.x, mousePosition.y, 0, true);
            if (pick.success)
            {
                auto pos = pick.position;
                if (pick.entity->name == this->terrainName) {
                    this->destination = pos;
                }
            }
        }

        ///Move to the destination if the destination is not null
        if (this->destination != NULL) {
            if (entity->position.DistanceToPoint(this->destination) > 1.0f)
            {
                this->agent->Navigate(this->destination);
                auto model = entity->As<Model>();
                model->Animate(this->animationName);
            }
            else {
                this->agent->Stop();
                auto model = entity->As<Model>();
                model->Animate("idle");
                this->destination == NULL;
            }
        }

        ///Toggle the freelook mode
        if (window->KeyHit(KEY_TAB)) {
            if (this->freeLook) {
                this->freeLook = false;
            }
            else {
                this->freeLook = true;
                Vec3 currentcameraposition = TransformPoint(0, 15, 0, GetEntity(), nullptr);
                this->camera->SetPosition(currentcameraposition, true);
                this->camera->SetRotation(Vec3(90, 0, 0));
            }
        }

        ///Position the camera according to the selected mode
        if (!this->freeLook) {
            Vec3 currentcameraposition = TransformPoint(0, 15, 5, GetEntity(), nullptr);
            this->camera->SetPosition(currentcameraposition, true);
            this->camera->Point(entity);
        }
        else {
            Vec3 camPos = this->camera->GetPosition();
            if (window->KeyDown(KEY_W)) {
                camPos.z += 0.5f;
            }
            else if (window->KeyDown(KEY_S)) {
                camPos.z -= 0.5f;
            }
            else if (window->KeyDown(KEY_A)) {
                camPos.x -= 0.5f;
            }
            else if (window->KeyDown(KEY_D)) {
                camPos.x += 0.5f;
            }
            this->camera->SetPosition(camPos);
        }
    }
}

bool MouseMovementController::Load(table& properties, shared_ptr<Stream> binstream, shared_ptr<Map> scene, const LoadFlags flags)
{
    this->scene = scene;
    this->terrainName = (String)properties["terrainName"];
    this->animationName = (String)properties["animationName"];
    for (auto e : scene->entities) {
        if (e->name == terrainName)
        {
            this->terrain = std::static_pointer_cast<Terrain>(e);
        }
    }
    return true;
}

bool MouseMovementController::Save(table& properties, shared_ptr<Stream> binstream, shared_ptr<Map> scene, const SaveFlags flags)
{
    properties["terrainName"] = (String)terrain->name;
    properties["animationName"] = (String)this->animationName;
    return true;
}

shared_ptr<Component> MouseMovementController::Copy()
{
    return std::make_shared<MouseMovementController>(*this);
}

3. JSON File

{
  "component": {
    "properties": [
      {
        "name": "terrainName",
        "label": "Terrain Name",
        "value": ""
      },
      {
        "name": "animationName",
        "label": "Animation Name",
        "value": ""
      }
    ]
  }
}

 

  • Like 3
 Share

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...