How to recenter HUD to an Actor

Hi Everyone.

I have been implementing a simple HUD where after you select a Building to construct it should follow the building and display a Build and Cancel Button, I have managed to create it partially has I want it to function but need some help with the last part, basically if I move the Building around, the HUD is not always centered to the building and that is causing the problem since I want the buttons to always be in the same place centered to the Building, here are some Images to demonstrate what I mean.

In this image you can see that the building and button are correctly placed:

106480-capture.png

But if I move the building a little bit, the buttons get offset to the wrong position:

106521-capture2.png

Here is the Blueprint Function I’m using to re-position the HUD:

and here is the code in C++ that calls the function and passes the parameters to it:

if (BuildingTemp && *CurrentPlayState == EPlayState::MoveBuilding)
	{
		FVector BoxExtent;
		FVector Origin;

		UUserWidget* WidgetBuildBuilding = nullptr;
		for (TObjectIterator<UUserWidget> Itr; Itr; ++Itr)
		{
			if (Itr->GetName().Contains("BuildBuildingHUD"))
			{
				WidgetBuildBuilding = *Itr;
				break;
			}
		}

		BuildingTemp->GetActorBounds(false, Origin, BoxExtent);
		BuildingTemp->SetActorLocation(BuildingPosition);

		BuildingPosition.X += BoxExtent.X;
		BuildingPosition.Y += BoxExtent.Y * 5;

		FOutputDeviceNull oDNull;
		FString Command = FString::Printf(TEXT("RePositionContainer %f %f %f"), BuildingPosition.X, BuildingPosition.Y, BuildingPosition.Z);
		WidgetBuildBuilding->CallFunctionByNameWithArguments(*Command, oDNull, NULL, true);
	}

Any help with this would be great, thank you.

WolfAlvein,

If you used a widget component on the actor that you’d like the widget to be “centered” on, and then use screen space instead of world space for the widget component, it should then recenter for you.

Hi Samantha, sorry but I don’t understand your answer, could you please explain a little more.

I’m using a Widget Blueprint that contains a Function that recenter the widget depending on the movement of the Actor in the screen that is why in the C++ code I pass the location to the Function called “RePositionContainer” and the use the player controller to cast that position from world coordinates to Screen (Project World To Screen blueprint event) coordinates and center there the widget, it works correctly for certain portions of the screen, mostly when the object is in the center and not near the borders of the screen. thank you

Sorry for confusing you - I mean’t that if you went into the Widget Component and then went down to User Interface and selected ‘Screen’ instead of ‘World’ it should fix the issue for you. I should have been more descriptive.

[Widget Component Documentation][1]

Hi Samantha.

Thank you for the information, I wasn’t using a Widget component, didn’t even know they existed, I was just painting the widget in screen and if it existed executed the re position code, but know that I see this component exists I’ll try using it when I have to spawn the actor in screen and after built will dispose of it, once I have it working I’ll let you now, but will have to wait until next week since I’m taking a small vacation from programming.

You’re welcome. I am marking this question as answered - if you run into any further trouble with this specific issue, please reopen the question by replying back.

Thanks!

Hi Samantha, Tomorrow I’ll start with this and verify if it works for me and thank you for your answers, by the way do you think you could look into this other question I have: line trace hits Air??, this is a case I posted quite a while ago but no one seems to know whats happening.

Thank you.

Hi Samantha.

I have been using the code i post next to create the component, and I have set it to the correct Class and the Widget Space to the one you indicated before, but I can’t seem to be able to display the HUD in the World even though when I check the Actor the Component is attached correctly and it’s using the corresponding Class.

void ABuilding::SetupBuildingWidget()
{
	UWidgetComponent* Widget = NewObject<UWidgetComponent>(this, UWidgetComponent::StaticClass(), TEXT("Building Widget"));

	if (!Widget)
	{
		return;
	}

	FStringClassReference BuildConfirmReference(TEXT("/Game/UI/BuildBuildingHUD.BuildBuildingHUD_C"));
	
	if (UClass* ConfirmClass = BuildConfirmReference.TryLoadClass<UUserWidget>())
	{

		UUserWidget* ConfirmBuildWidget = CreateWidget<UUserWidget>(GetWorld(), ConfirmClass);
				
		Widget->RegisterComponent();
		Widget->SetWidgetSpace(EWidgetSpace::Screen);
		Widget->SetWidgetClass(ConfirmBuildWidget->GetClass());
		Widget->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetIncludingScale);
	}
	else
	{
		Widget->DestroyComponent();
	}
}

And here is a Screenshot:

Thank you.

Hi Samantha, I have found something new, it seems that the Widget is not getting painted unless I change something manually from the Editor, one I do change anything, it updates and repaints the Widget correctly in the Viewport, any idea of what could be making this issue to happen?

WolfAlvein,

Thanks for providing additional information. Code and UMG aren’t typically what I work with, so I’m unfamiliar with some aspects of the engine. While it’s possible that you’re entering the wrong code, I would suggest taking that question to the forums for additional review.

What I would suggest you do is if you feel there is a bug you’ve found with the widget not being painted when you change anything manually in the Engine, you should write up a bug report.

Please make sure that if you choose to go this route, you provide detailed information, including repro. steps.

Thank you!