Dynamically update use message text on Usable UI

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
ohheymatt
Posts: 6
Joined: Fri Jul 01, 2022 4:14 pm

Dynamically update use message text on Usable UI

Post by ohheymatt »

I am using a ProximitySelector in combination with SelectorUseStandardUIElements to populate a UsableUI nested under a Usable GameObject. Technically, I made a subclass of ProximitySelector that skips the IsUseButtonDown checks in favor of hooking up to my InputActionsAsset. I have an Action in there for Interact (both Keyboard & Controller) that I want to use for the selector instead of configuring it in the selector component itself.

What I'm trying to do is dynamically update the Use Message Text with the Interact button of the currently active Controller Scheme in my InputActionsAsset.

I've managed to hook into the ControlChangedEvent of my InputActionsAsset to reset the Usable.overrideUseMessage. This will get the Use Message Text to change every time the ShowControls function is called.

Is there a way to update this text without ShowControls being re-called?
User avatar
Tony Li
Posts: 22148
Joined: Thu Jul 18, 2013 1:27 pm

Re: Dynamically update use message text on Usable UI

Post by Tony Li »

What about changing the SelectorUseStandardUIElements component's elements.useMessageText.text directly?
ohheymatt
Posts: 6
Joined: Fri Jul 01, 2022 4:14 pm

Re: Dynamically update use message text on Usable UI

Post by ohheymatt »

Hm...I just tried this with no luck.

Code: Select all

public class TriggerSelector : ProximitySelector
{
    public PlayerInput input;
    public SelectorUseStandardUIElements ui;

    public override void Start() {
        SetUseMessage();
    }

    protected override void Update() {
        // Exit if disabled or paused:
        if (!enabled || (Time.timeScale <= 0)) return;

        // If the currentUsable went missing (was destroyed, deactivated, or we changed scene), tell listeners:
        if (toldListenersHaveUsable && (currentUsable == null || !currentUsable.enabled || !currentUsable.gameObject.activeInHierarchy)) {
            SetCurrentUsable(null);
            OnDeselectedUsableObject(null);
            toldListenersHaveUsable = false;
        }
    }

    // Called on ControlsChangedEvent
    public void SetUseMessage() {
        InputActionAsset asset = input.actions;
        InputAction action = asset.FindAction("Interact");
        defaultUseMessage = $"{action.GetBindingDisplayString()} to interact";
        ui.elements.useMessageText.textMeshProUGUI.text = defaultUseMessage;
    }

    public void OnClickUse() {
        UseCurrentSelection();
    }
}
My Use Message Text on the Usable UI is set to a Text Mesh Pro UGUI component (and yes I have TMP enabled in the Dialogue System).
User avatar
Tony Li
Posts: 22148
Joined: Thu Jul 18, 2013 1:27 pm

Re: Dynamically update use message text on Usable UI

Post by Tony Li »

Does your Usable override the use message? If so, it will take precedence over your SetUseMessage() method / defaultUseMessage.

After Start() runs, does defaultUseMessage have the value you expect?

If that doesn't help, can you send a reproduction project to tony (at) pixelcrushers.com?
User avatar
Tony Li
Posts: 22148
Joined: Thu Jul 18, 2013 1:27 pm

Re: Dynamically update use message text on Usable UI

Post by Tony Li »

Hi,

Thanks for sending the reproduction project.

The StandardUISelectorElements component caches the use message. It does this because it can be configured to show different use messages for usables on different layers or tags.

I sent a patch with an updated StandardUISelectorElements which makes the ConnectDelegates() method public. This change will also be in version 2.2.29.

Then change your SetUseMessage() method to something like:

Code: Select all

  // Called on ControlsChangedEvent
  public void SetUseMessage() {
      InputActionAsset asset = input.actions;
      InputAction action = asset.FindAction("Interact");
      defaultUseMessage = $"{action.GetBindingDisplayString()} to interact";
      GetComponent<SelectorUseStandardUIElements>().ConnectDelegates();
  }
You'll probably want to cache the GetComponent<SelectorUseStandardUIElements>().
Post Reply