Skip to content

Commit

Permalink
Create a new viewport when a player becomes active
Browse files Browse the repository at this point in the history
  • Loading branch information
Benualdo committed Oct 3, 2024
1 parent 6b1c834 commit d89f018
Show file tree
Hide file tree
Showing 21 changed files with 514 additions and 98 deletions.
115 changes: 69 additions & 46 deletions data/Scenes/Aiguelongue.scene

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions projects/game/src/Behaviour/Camera/GameCameraBehaviour.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ class GameCameraBehaviour : public vg::core::Behaviour
GameCameraBehaviour(const vg::core::string & _name, vg::core::IObject * _parent);
~GameCameraBehaviour();

void OnPlay () final override;
void OnEnable () final override;
void Update (const Context & _context) override;

void setTarget (const vg::core::IGameObject * _target);

private:
vg::core::ObjectHandle m_target;
float m_delay = 0.1f;

vg::core::float3 m_offset = (vg::core::float3)0.0f;
vg::core::float3 m_targetPosition = (vg::core::float3)0.0f;
vg::core::float3 m_offset = vg::core::float3(0.0f, -9.0f, 14.0f);
vg::core::float3 m_targetPosition = (vg::core::float3)0.0f;
vg::core::float3 m_targetVelocity = (vg::core::float3)0.0f;
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include "Precomp.h"
#include "GameCameraBehaviour.h"
#include "Game.h"
#include "core/GameObject/GameObject.h"
Expand Down Expand Up @@ -31,24 +30,33 @@ bool GameCameraBehaviour::registerProperties(IClassDesc & _desc)
registerProperty(GameCameraBehaviour, m_target, "Target");
setPropertyDescription(GameCameraBehaviour, m_target, "Camera target");

registerProperty(GameCameraBehaviour, m_offset, "Offset");
setPropertyDescription(GameCameraBehaviour, m_offset, "Camera offset");

registerProperty(GameCameraBehaviour, m_delay, "Delay");
setPropertyDescription(GameCameraBehaviour, m_delay, "Time to smooth camera position (s)");

return true;
}

//--------------------------------------------------------------------------------------
void GameCameraBehaviour::OnPlay()
void GameCameraBehaviour::setTarget(const IGameObject * _target)
{
super::OnPlay();
m_offset = getGameObject()->getGlobalMatrix()[3].xyz;
m_target.setUID(_target->GetUID());
}

auto * target = m_target.get<IGameObject>();
if (target)
{
if (auto * player = target->GetComponentInChildrenT<CharacterBehaviour>())
m_offset -= player->getGameObject()->GetGlobalMatrix()[3].xyz;
}
//--------------------------------------------------------------------------------------
void GameCameraBehaviour::OnEnable()
{
super::OnEnable();
//m_offset = getGameObject()->getGlobalMatrix()[3].xyz;
//
//auto * target = m_target.get<IGameObject>();
//if (target)
//{
// if (auto * player = target->GetComponentInChildrenT<CharacterBehaviour>())
// m_offset -= player->getGameObject()->GetGlobalMatrix()[3].xyz;
//}
}

//--------------------------------------------------------------------------------------
Expand Down
239 changes: 239 additions & 0 deletions projects/game/src/Behaviour/Camera/GameCameraManagerBehaviour.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
#include "Precomp.h"
#include "GameCameraManagerBehaviour.h"
#include "editor/Editor_Consts.h"
#include "engine/ICameraComponent.h"
#include "GameCameraBehaviour.hpp"

using namespace vg::core;
using namespace vg::engine;

VG_REGISTER_COMPONENT_CLASS(GameCameraManagerBehaviour, "Game Camera Manager", "Game", "Camera Manager for Game cameras", vg::editor::style::icon::Script, 0);

//--------------------------------------------------------------------------------------
GameCameraManagerBehaviour::GameCameraManagerBehaviour(const string & _name, IObject * _parent) :
super(_name, _parent)
{
SetUpdateFlags(UpdateFlags::Update);
}

//--------------------------------------------------------------------------------------
GameCameraManagerBehaviour::~GameCameraManagerBehaviour()
{

}

//--------------------------------------------------------------------------------------
bool GameCameraManagerBehaviour::registerProperties(IClassDesc & _desc)
{
super::registerProperties(_desc);

registerProperty(GameCameraManagerBehaviour, m_player1Camera, "Camera 1");
registerProperty(GameCameraManagerBehaviour, m_player2Camera, "Camera 2");
registerProperty(GameCameraManagerBehaviour, m_player3Camera, "Camera 3");
registerProperty(GameCameraManagerBehaviour, m_player4Camera, "Camera 4");

registerPropertyEx(GameCameraManagerBehaviour, m_players, "Players", vg::core::PropertyFlags::ReadOnly);
setPropertyRange(GameCameraManagerBehaviour, m_players, uint2(0, 4));

return true;
}

//--------------------------------------------------------------------------------------
void GameCameraManagerBehaviour::OnPropertyChanged(IObject * _object, const IProperty & _prop, bool _notifyParent)
{
if (!strcmp(_prop.GetName(), "m_players"))
updateGameViewports();

super::OnPropertyChanged(_object, _prop, _notifyParent);
}

//--------------------------------------------------------------------------------------
void GameCameraManagerBehaviour::OnPlay()
{
super::OnPlay();
}

//--------------------------------------------------------------------------------------
void GameCameraManagerBehaviour::Update(const Context & _context)
{
if (_context.m_playing && !_context.m_paused)
{
const uint playerCount = (uint)Game::get()->getActivePlayers().size();
if (m_players != playerCount)
{
m_players = playerCount;
updateGameViewports();
}
}
}

//--------------------------------------------------------------------------------------
void GameCameraManagerBehaviour::updateGameViewports()
{
VG_INFO("[CameraManager] Update Game Viewports for %u players", m_players);

vector<PlayerBehaviour *> activePlayersSorted = Game::get()->getActivePlayers();
sort(activePlayersSorted.begin(), activePlayersSorted.end(), [](PlayerBehaviour * a, PlayerBehaviour * b)
{
return (a->getViewportIndex() < b->getViewportIndex());
}
);

vector<IGameObject *> cameras(activePlayersSorted.size());

for (uint i = 0; i < activePlayersSorted.size(); ++i)
{
const PlayerBehaviour * player = activePlayersSorted[i];
IGameObject * camGO = nullptr;

const uint index = player->getViewportIndex() != -1 ? player->getViewportIndex() : i;
switch (index)
{
default:
VG_ASSERT_NOT_IMPLEMENTED();
break;

case 0:
camGO = m_player1Camera.get<IGameObject>();
break;

case 1:
camGO = m_player2Camera.get<IGameObject>();
break;

case 2:
camGO = m_player3Camera.get<IGameObject>();
break;

case 3:
camGO = m_player4Camera.get<IGameObject>();
break;
}

cameras[i] = camGO;
auto * playerGO = player->GetGameObject();
camGO->SetName("Camera_" + playerGO->GetName());
if (auto * gameCamBehaviour = camGO->GetComponentT<GameCameraBehaviour>())
gameCamBehaviour->setTarget(playerGO);
}

if (cameras.size() > 0)
{
if (m_players > 0)
{
cameras[0]->SetInstanceFlags(vg::core::InstanceFlags::Enabled, true);

if (auto * cam0 = cameras[0]->GetComponentT<ICameraComponent>())
{
switch (m_players)
{
default:
VG_ASSERT_NOT_IMPLEMENTED();
break;

case 0:
case 1: // ■■
cam0->SetViewportOffsetAndScale(float2(0.0f, 0.0f), float2(1.0f, 1.0f)); // ■■
break;

case 2:
cam0->SetViewportOffsetAndScale(float2(0.0f, 0.0f), float2(0.5f, 1.0f)); // ■□
break; // ■□

case 3:
case 4: // ■□
cam0->SetViewportOffsetAndScale(float2(0.0f, 0.0f), float2(0.5f, 0.5f)); // □□
break;
}
}
}
else
{
cameras[0]->SetInstanceFlags(vg::core::InstanceFlags::Enabled, false);
}
}

if (cameras.size() > 1)
{
if (m_players > 1)
{
cameras[1]->SetInstanceFlags(vg::core::InstanceFlags::Enabled, true);
if (auto * cam1 = cameras[1]->GetComponentT<ICameraComponent>())
{
switch (m_players)
{
default:
VG_ASSERT_NOT_IMPLEMENTED();
break;

case 2:
cam1->SetViewportOffsetAndScale(float2(0.5f, 0.0f), float2(0.5f, 1.0f)); // □■
break; // □■

case 3:
case 4: // □■
cam1->SetViewportOffsetAndScale(float2(0.5f, 0.0f), float2(0.5f, 0.5f)); // □□
break;
}
}
}
else
{
cameras[1]->SetInstanceFlags(vg::core::InstanceFlags::Enabled, false);
}
}

if (cameras.size() > 2)
{
if (m_players > 2)
{
cameras[2]->SetInstanceFlags(vg::core::InstanceFlags::Enabled, true);
if (auto * cam2 = cameras[2]->GetComponentT<ICameraComponent>())
{
switch (m_players)
{
default:
VG_ASSERT_NOT_IMPLEMENTED();
break;

case 3: // □□
cam2->SetViewportOffsetAndScale(float2(0.0f, 0.5f), float2(1.0f, 0.5f)); // ■■
break;

case 4: // □□
cam2->SetViewportOffsetAndScale(float2(0.0f, 0.5f), float2(0.5f, 0.5f)); // ■□
break;
}
}
}
else
{
cameras[2]->SetInstanceFlags(vg::core::InstanceFlags::Enabled, false);
}
}

if (cameras.size() > 3)
{
if (m_players > 3)
{
cameras[3]->SetInstanceFlags(vg::core::InstanceFlags::Enabled, true);
if (auto * cam3 = cameras[3]->GetComponentT<ICameraComponent>())
{
switch (m_players)
{
default:
VG_ASSERT_NOT_IMPLEMENTED();
break;

case 4: // □□
cam3->SetViewportOffsetAndScale(float2(0.5f, 0.5f), float2(0.5f, 0.5f)); // □■
break;
}
}
}
else
{
cameras[3]->SetInstanceFlags(vg::core::InstanceFlags::Enabled, false);
}
}
}
26 changes: 26 additions & 0 deletions projects/game/src/Behaviour/Camera/GameCameraManagerBehaviour.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "core/Component/Behaviour/Behaviour.h"
#include "core/Object/ObjectHandle.h"

class GameCameraManagerBehaviour final : public vg::core::Behaviour
{
public:
VG_CLASS_DECL(GameCameraManagerBehaviour, vg::core::Behaviour);

GameCameraManagerBehaviour(const vg::core::string & _name, vg::core::IObject * _parent);
~GameCameraManagerBehaviour();

void OnPlay() final override;
void Update(const Context & _context) final override;
void OnPropertyChanged(vg::core::IObject * _object, const vg::core::IProperty & _prop, bool _notifyParent) final override;

private:
void updateGameViewports();

private:
vg::core::uint m_players = 0;

vg::core::ObjectHandle m_player1Camera;
vg::core::ObjectHandle m_player2Camera;
vg::core::ObjectHandle m_player3Camera;
vg::core::ObjectHandle m_player4Camera;
};
30 changes: 18 additions & 12 deletions projects/game/src/Behaviour/Character/Player/PlayerBehaviour.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,27 @@ class PlayerBehaviour final : public CharacterBehaviour
public:
VG_CLASS_DECL(PlayerBehaviour, CharacterBehaviour);

PlayerBehaviour (const vg::core::string & _name, vg::core::IObject * _parent);
~PlayerBehaviour ();
PlayerBehaviour (const vg::core::string & _name, vg::core::IObject * _parent);
~PlayerBehaviour ();

void OnPlay () final override;
void OnStop () final override;
void OnPlay () final override;
void OnStop () final override;

void FixedUpdate (const Context & _context) override;
void Update (const Context & _context) override;
void FixedUpdate (const Context & _context) override;
void Update (const Context & _context) override;

const vg::core::float4 & getCustomColor () const { return m_customColor; }
VG_INLINE const vg::core::float4 & getCustomColor () const;
VG_INLINE const vg::core::u8 getViewportIndex () const;

private:
vg::core::InputType m_controllerType = vg::core::InputType::Joypad;
vg::core::u8 m_controllerIndex = 0;
vg::core::float4 m_customColor = vg::core::float4(1, 1, 1, 1);
vg::core::ObjectHandle m_UI;
ItemBehaviour * m_rightHandItem = nullptr;
vg::core::InputType m_controllerType = vg::core::InputType::Joypad;
vg::core::u8 m_controllerIndex = 0;
vg::core::float4 m_customColor = vg::core::float4(1, 1, 1, 1);
vg::core::ObjectHandle m_UI;
ItemBehaviour * m_rightHandItem = nullptr;
vg::core::u8 m_viewIndex = -1;
};

#if VG_ENABLE_INLINE
#include "PlayerBehaviour.inl"
#endif
Loading

0 comments on commit d89f018

Please sign in to comment.