UUserWidget::bIsEnabled unexpected behaviour

Hi everyone,

I was working with 3D widgets and to disable a 3D widget for certain users, I was using UUserWidget->bIsEnabled = …;

Looking at the documentation for bIsEnabled, it looks like this would be the correct way to do it, and it works correctly on the server. However, on clients it didn’t have the same effect. After a lot of testing I ended up fixing it by calling a similar node from the blueprint of my extended Blueprint class, and now it worked for the client too.

The c++ equivalent of the BP call was UUserWidget->SetIsEnabled, which looks like this:

void UWidget::SetIsEnabled(bool bInIsEnabled)
{
	bIsEnabled = bInIsEnabled;

	TSharedPtr<SWidget> SafeWidget = GetCachedWidget();
	if (SafeWidget.IsValid())
	{
		SafeWidget->SetEnabled(bInIsEnabled);
	}
}

Since there’s more going on here, I would say bIsEnabled should not be a publicly accessible member in UUserWidget, since it doesn’t always do what it says it does in its documentation.

1 Like

Hey BasV,

I have a couple of questions regarding this issue:

  • How are you using your 3D Widget? Are you ensuring that you’re replicating your variable change so that the clients also have the “disabled” version of the widget?
  • Could you provide a list of steps I can follow to reproduce the issue on my end?

Any context, screenshots, code snippets, etc that you can provide would be fantastic.

Thanks!

1 Like

Hi Sean,

I would normally love to make an example project, but I’m on a deadline right now. I’ll try to make my setup as clear as possible:

  • I’m actually not replicating the widgets on purpose, because I want only the owning client to have an enabled version of their own widget while all other clients can only see the disabled version. The underlying actor does replicate and replicates the needed information about ownership.
    So practically, the underlying actor checks if the local player is the owner, then it enables the widget, or disables if not.

When testing, I run this code on both the client and the server to set the Widget’s enabled state (this is in PIE mode, 2 players, no dedicated server)

MenuWidget->SetIsEnabled(bEnabled);

bEnabled will be true for the owner, and false for any non-owners. I absolutely double checked this. This works correctly, and for both the server and the client I see the owned menu enabled, and the non-owned menu disabled (they both spawn their own 3d menu)

However, if I change my code to this:

MenuWidget->bIsEnabled = bEnabled;

The menus will correctly display for the server, but not for the client - they will both me enabled client-side.

I hope that helped! Cheers!

1 Like

Unfortunately, after attempting to reproduce the issue in a clean project on my end, I’m not seeing the same results. It’s very possible I’m missing a step, though.

Since it sounds like you’ve got a way to get this working for now, and we have been unable to reproduce the issue locally, I am going to mark this topic as resolved for tracking purposes. Sadly, without a local repro I’m limited as far as what action I can take on the issue.

However, if you do get the chance at any point to recreate the issue or provide a simplified test project that showcases it, you are more than welcome to leave a comment to reopen this thread and I will be glad to continue the investigation into the issue.

Have a great day

1 Like

Exactly this issue happened to me, and exactly the same solution worked - use the setter function

1 Like