Page 1 of 1

Dynamically update use message text on Usable UI

Posted: Fri Jul 01, 2022 4:42 pm
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?

Re: Dynamically update use message text on Usable UI

Posted: Fri Jul 01, 2022 8:13 pm
by Tony Li
What about changing the SelectorUseStandardUIElements component's elements.useMessageText.text directly?

Re: Dynamically update use message text on Usable UI

Posted: Sat Jul 02, 2022 3:29 pm
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).

Re: Dynamically update use message text on Usable UI

Posted: Sat Jul 02, 2022 4:40 pm
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?

Re: Dynamically update use message text on Usable UI

Posted: Sun Jul 03, 2022 2:01 pm
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>().