Hi,
I’m working on an item rotation system (item roulette) like in mario kart. My idea was that my PlayerController determines which item should be obtained after collecting an itembox. It passes the information to my own HUD and this creates with the help of a timeline the illusion of an item rotation. So far so good, this seems to work quite well. However I do have a local multiplayer game (without splitscreen!) where all players share one screen (and one camera). I do want each player to have their own place to display the current item. It should look like this:
I do see in PIE that I’ve got a HUD for each playerController but since they all share the same viewport only the HUD of the first player is drawn (at least thats my guess why I only see one item box). How would I go about implementing an itembox for each player? Would I really have to implement 4 timelines (for each player one timeline) and several functions in my HUD to cover up for all of them? Or is there an easier way to tell each playerController to draw their HUD onto the screen, so each HUD handles only it’s own itembox / itemrotation? If i activate splitscreen mode (which i dont want to) i can notice that each player has its own item drawn. So I need to tell each PC to draw onto the viewport from player 1 or something like this, right?
Here is my HUD:
// @author Theo
#include "Theosechs.h"
#include "Kismet/KismetMathLibrary.h"
#include "BrawlingPlayerController.h"
#include "BrawlHUD.h"
ABrawlHUD::ABrawlHUD()
{
PrimaryActorTick.bCanEverTick = true;
static ConstructorHelpers::FObjectFinder<UTexture2D> ItemTextureTextureOb(TEXT("/Game/UI/HUD/HUDMain"));
ItemTexture = ItemTextureTextureOb.Object;
itemIcons[0] = UCanvas::MakeIcon(ItemTexture, 128, 0, 64, 64);
itemIcons[1] = UCanvas::MakeIcon(ItemTexture, 64, 64, 64, 64);
itemIcons[2] = UCanvas::MakeIcon(ItemTexture, 128, 64, 64, 64);
itemIcons[3] = UCanvas::MakeIcon(ItemTexture, 192, 64, 64, 64);
itemIcons[4] = UCanvas::MakeIcon(ItemTexture, 64, 0, 64, 64);
TexColor = FColor(255, 255, 255, 255);
//TimeLine
const ConstructorHelpers::FObjectFinder<UCurveFloat> Curve(TEXT("CurveFloat'/Game/Effects/Curves/ItemRotation.ItemRotation'"));
TimeLine = FTimeline{};
FOnTimelineFloat progressFunction{};
progressFunction.BindUFunction(this, "UpdateTimeLine");
TimeLine.AddInterpFloat(Curve.Object, progressFunction, FName{ TEXT("SLOWROTATION") });
//bind the end event
FOnTimelineEvent FinishEvent;
FinishEvent.BindUFunction(this, "OnTimeLineEnd");
TimeLine.SetTimelineFinishedFunc(FinishEvent);
x = 0;
y = 0;
}
void ABrawlHUD::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (TimeLine.IsPlaying()) {
TimeLine.TickTimeline(DeltaTime);
}
}
void ABrawlHUD::DrawHUD()
{
Super::DrawHUD();
if (Canvas == nullptr) {
return;
}
ScaleUI = Canvas->ClipY / 1080.0f;
//items
DrawItems();
DrawItemFrames();
}
void ABrawlHUD::DrawItemFrames()
{
}
void ABrawlHUD::DrawItems()
{
if (x == 0 && y == 0) {
x = UKismetMathLibrary::RandomFloatInRange(100, 600); //750
y = UKismetMathLibrary::RandomFloatInRange(100, 600); //50
}
Canvas->SetDrawColor(TexColor);
Canvas->DrawIcon(itemIcons[itemCount], (x * ScaleUI), (y * ScaleUI), 2 * ScaleUI);
}
void ABrawlHUD::SlowItemRotation()
{
GetWorldTimerManager().SetTimer(ItemRotationTimer, this, &ABrawlHUD::RotateItems, ItemRotationSpeed, true);
}
void ABrawlHUD::RotateItems()
{
//get item count from gamemode
if (itemCount < 4)
{
itemCount++;
}
else
{
itemCount = 0;
}
GetWorldTimerManager().SetTimer(ItemRotationTimer, this, &ABrawlHUD::RotateItems, ItemRotationSpeed, false);
}
void ABrawlHUD::UpdateTimeLine(float Value)
{
ItemRotationSpeed = Value;
}
void ABrawlHUD::OnTimeLineEnd()
{
itemCount = 0;
GetWorldTimerManager().ClearTimer(ItemRotationTimer);
}
void ABrawlHUD::StartItemRotation()
{
TimeLine.PlayFromStart();
if (!GetWorldTimerManager().IsTimerActive(ItemRotationTimer)) {
GetWorldTimerManager().SetTimer(ItemRotationTimer, this, &ABrawlHUD::RotateItems, ItemRotationSpeed, false);
}
}
Cheers