Jump to content

Working voice chat example


Josh
 Share

Recommended Posts

This supports voice chat and allows you to join and invite other users to your lobby.

You need to be using the dev branch for this.

#include "UltraEngine.h"
#include "Steamworks/Steamworks.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    // Initialize Steam
    if (not Steamworks::Initialize())
    {
        RuntimeError("Steamworks failed to initialize.");
        return 1;
    }
    
    // Get the displays
    auto displays = GetDisplays();

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

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

    // Create world
    auto world = CreateWorld();

    // Create camera
    auto camera = CreateCamera(world);

    // Create lobby
    auto lobby = Steamworks::CreateLobby();
    
    // Main loop
    while (not window->KeyDown(KEY_ESCAPE) and not window->Closed())
    {
        while (PeekEvent())
        {
            const auto e = WaitEvent();
            switch (e.id)
            {
            case Steamworks::EVENT_LOBBYINVITEACCEPTED:
            case Steamworks::EVENT_LOBBYDATACHANGED:
            case Steamworks::EVENT_LOBBYUSERJOIN:
            case Steamworks::EVENT_LOBBYUSERLEAVE:
            case Steamworks::EVENT_LOBBYUSERDISCONNECT:
                auto info = e.source->As<Steamworks::LobbyEventInfo>();
                auto username = Steamworks::GetUserName(info->userid);
                switch (e.id)
                {
                case Steamworks::EVENT_LOBBYINVITEACCEPTED:
                    Print("Invite accepted to lobby " + String(info->lobbyid));
                    if (not Steamworks::JoinLobby(info->lobbyid))
                    {
                        Print("Failed to join lobby");
                    }
                    break;
                case Steamworks::EVENT_LOBBYDATACHANGED:
                    Print("New lobby owner " + username);
                    break;
                case Steamworks::EVENT_LOBBYUSERJOIN:
                    Print("User " + username + " joined");
                    break;
                case Steamworks::EVENT_LOBBYUSERLEAVE:
                    Print("User " + username + " left");
                    break;
                case Steamworks::EVENT_LOBBYUSERDISCONNECT:
                    Print("User " + username + " disconnected");
                    break;
                }
                break;
            }
        }

        // Enable voice chat when the C key is pressed
        bool record = window->KeyDown(KEY_C);
        Steamworks::RecordVoice(record);
        if (record)
        {
            window->SetText("Ultra Engine (Microphone Enabled)");
        }
        else
        {
            window->SetText("Ultra Engine");
        }

        // Open friend invite interface when space key is pressed        
        if (window->KeyHit(KEY_SPACE))
        {
            lobby = Steamworks::CurrentLobby();
            if (lobby) Steamworks::InviteFriends(newlobby);
        }

        // Update world
        world->Update();

        // Update Steamworks
        Steamworks::Update();

        // Render world
        world->Render(framebuffer);
    }

    // Close Steam
    Steamworks::Shutdown();

    return 0;
}

 

  • Like 4

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Have not tested with anyone else yet but I think this will handle player movement:

#include "UltraEngine.h"
#include "Steamworks/Steamworks.h"
#include "ComponentSystem.h"

using namespace UltraEngine;

class Player : public Object
{
public:
    static inline std::map<uint64_t, shared_ptr<Player> > players;

    shared_ptr<Entity> entity;
    WString name;
    uint64_t userid;

    static std::shared_ptr<Player> Spawn(shared_ptr<World> world, const uint64_t userid)
    {
        auto player = std::make_shared<Player>();
        player->entity = CreatePivot(world);
        auto model = CreateCylinder(world, 0.25, 1.8);
        model->SetPosition(0, 0.9, 0);
        model->SetParent(player->entity);
        model->SetCollider(nullptr);
        player->userid = userid;
        Player::players[userid] = player;
        return player;
    }
};

struct PlayerState
{
    Vec3 position;
    Vec3 velocity;
    float yaw, omega;
};

int main(int argc, const char* argv[])
{
    // Initialize Steam
    if (not Steamworks::Initialize())
    {
        RuntimeError("Steamworks failed to initialize.");
        return 1;
    }
    
    // Get the displays
    auto displays = GetDisplays();

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

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

    // Create world
    auto world = CreateWorld();
    world->SetGravity(0, -18, 0);

    // Create lobby
    auto lobby = Steamworks::CreateLobby(Steamworks::LOBBY_PRIVATE);
    
    // Spawn local player
    auto player = Player::Spawn(world, Steamworks::GetUserId());
    player->entity->AddComponent<FirstPersonControls>();

    //Add a floor
    auto floor = CreateBox(world, 50, 1, 50);
    floor->SetPosition(0, -0.5, 0);
    auto mtl = CreateMaterial();
    mtl->SetTexture(LoadTexture("https://github.com/UltraEngine/Documentation/raw/master/Assets/Materials/Developer/griid_gray.dds"));
    floor->SetMaterial(mtl);

    auto light = CreateDirectionalLight(world);
    light->SetRotation(55, 35, 0);

    // Main loop
    while (not window->KeyDown(KEY_ESCAPE) and not window->Closed())
    {
        while (PeekEvent())
        {
            const auto e = WaitEvent();
            switch (e.id)
            {            
            case Steamworks::EVENT_LOBBYINVITEACCEPTED:
            case Steamworks::EVENT_LOBBYDATACHANGED:
            case Steamworks::EVENT_LOBBYUSERJOIN:
            case Steamworks::EVENT_LOBBYUSERLEAVE:
            case Steamworks::EVENT_LOBBYUSERDISCONNECT:
                auto info = e.source->As<Steamworks::LobbyEventInfo>();
                auto username = Steamworks::GetUserName(info->userid);
                switch (e.id)
                {
                case Steamworks::EVENT_LOBBYINVITEACCEPTED:
                    Print("Invite accepted to lobby " + String(info->lobbyid));
                    if (not Steamworks::JoinLobby(info->lobbyid))
                    {
                        Print("Failed to join lobby");
                    }
                    break;
                
                case Steamworks::EVENT_LOBBYDATACHANGED:
                    Print("New lobby owner " + username);
                    break;

                case Steamworks::EVENT_LOBBYUSERJOIN:
                    Print("User " + username + " joined");

                    if (not Player::players[info->userid])
                    {
                        // Spawn remote player
                        Player::Spawn(world, info->userid);
                    }

                    break;
                case Steamworks::EVENT_LOBBYUSERLEAVE:
                    Print("User " + username + " left");

                    // Remove remote player
                    Player::players[info->userid] = nullptr;

                    break;
                case Steamworks::EVENT_LOBBYUSERDISCONNECT:
                    Print("User " + username + " disconnected");

                    // Remove remote player
                    Player::players[info->userid] = nullptr;

                    break;
                }
                break;
            }
        }

        // Receive data
        PlayerState state;
        while (true)
        {
            auto pak = Steamworks::GetPacket();
            if (not pak) break;
            if (pak->data->GetSize() == sizeof(PlayerState))
            {
                auto player = Player::players[pak->userid];
                if (player)
                {
                    pak->data->Peek(0, (const char*)&state, pak->data->GetSize());
                    player->entity->SetPosition(state.position);
                    player->entity->SetRotation(state.yaw);
                }
            }
        }

        // Send player data
        auto userid = Steamworks::GetUserId();
        auto player = Player::players[userid];
        state.position = player->entity->position;
        state.yaw = player->entity->rotation.y;
        Steamworks::BroadcastPacket(&state, sizeof(PlayerState), 0, Steamworks::P2PSEND_UNRELIABLENODELAY);

        // Enable voice chat when the C key is pressed
        bool record = window->KeyDown(KEY_C);
        Steamworks::RecordVoice(record);
        if (record)
        {
            window->SetText("Ultra Engine (Microphone Enabled)");
        }
        else
        {
            window->SetText("Ultra Engine");
        }

        // Update world
        world->Update();

        // Render world
        world->Render(framebuffer);

        // Update Steamworks
        Steamworks::Update();
    }

    // Close Steam
    Steamworks::Shutdown();

    return 0;
}

 

  • Like 1

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   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.

 Share

×
×
  • Create New...