Skip to content

UI and input

All · 20 min · No code

Problems with buttons, menus, popups, HUD widgets and input. For the model behind them, read UI shell and HUD and Input and camera.

Input

One tap of a button does the action several times

Fails silently

It looks like the feature is broken: a conversation skips lines, then closes and reopens.

Why: an Enhanced Input action with no triggers fires on every frame the key is held. A normal tap lasts several frames. An ability that runs for a while (a jump, an Art) ignores the repeats because it is still active; an ability that ends on the frame it starts activates again on the next frame, once per frame of the tap.

Fix: open the input action and add a Pressed trigger to Triggers. Every one-shot action in Input/InputActions/ has one; copy that.

Avoid it next time: Show an input action prompt.

A button does nothing, even though its input action is mapped

Fails silently

The action never fires, so there is nothing for the ability to log.

Why: two input mapping contexts map the same key at the same priority, and the other one's action consumes the input. Enhanced Input settles the conflict before any ability is asked, so blocking abilities with tags cannot fix it. XenoCore adds its own context, IMC_XenoCore, at priority 2 and Lyra's IMC_Default at 1, so they win ties against contexts added at the default 0, such as those from another Game Feature you add.

Fix:

  1. List every key your new mapping shares with IMC_Default and IMC_XenoCore.
  2. Give your context a higher Priority in the Game Feature Data's Add Input Mapping action, or move the action to a free key.
  3. On the winning action, leave Consume Input off if the other action must still work.

Avoid it next time: Show an input action prompt.

One press of a button also opens the menu

Why: the Escape key is bound twice. It is a gameplay key in a mapping context and CommonUI's UI.Action.Escape UI action (in Config/DefaultInput.ini), which the HUD layout answers by opening its Escape Menu Class. Both fire on one press. XenoCore's UI.Action.Escape is on the Escape key only, so pad Select (View/Back) is free for the quest tracker; the menu opens from Y, Start, I or Escape.

Fix: do not map a gameplay action to a key listed under UI.Action.Escape's Key Mappings in Config/DefaultInput.ini, or take that key off the UI action.

Avoid it next time: Show an input action prompt.

Holding a trigger switches at once instead of opening the party cursor

Fails silently

The hold looks exactly like a tap: control changes hands and no cursor appears.

Why: the Hold trigger on IA_XenoCore_PartySelect has Is One Shot ticked. A one-shot hold reports the press as released on the frame after it fires, so the cursor opens and commits in the same moment.

Fix: untick Is One Shot on that trigger. Keep the Hold Time Threshold on IA_XenoCore_PartySelect equal to the Tap Release Time Threshold on IA_XenoCore_PartySwitch and IA_XenoCore_PartySwitchPrev (0.25 s), or a press between the two values does both or neither.

Avoid it next time: Input and camera.

Tapping a trigger shows "Can't switch"

Why: the switch was refused, on purpose. The leader is toppled or dazed, an ally-targeted Art is choosing its target, the party is being wiped, or nobody else can take control (everyone else is downed, toppled, dazed or in the air, or there is only one active member). The Output Log has a LogXenoParty line starting switch refused.

Fix: none needed. To change the message or its sound, set Switch Refused Text and Switch Refused Sound on BP_XenoCore_Party. See Party.

The triggers do nothing at all

Fails silently

No "Can't switch", no cursor, nothing in the log.

Why: the switch abilities are granted only through the party's Leader Only Ability Set (Game/AbilitySet_XenoCore_Interact). If you replaced that set with your own, or cleared the field on your copy of BP_XenoCore_Party, nothing holds the abilities. With an empty starting roster the party component never hands the set to the player's pawn either.

Fix: add GA_XenoCore_PartySwitch, GA_XenoCore_PartySwitchPrev and GA_XenoCore_PartySelect, with their input tags, to the set named in Leader Only Ability Set.

The character jumps or acts while a menu is open, or when it closes

Why: gameplay input stops under a menu because every gameplay mapping context only matches while the input mode has InputMode.Game, and CommonUI removes that tag while a menu is up. The project sets this once, as the default query in Config/DefaultInput.ini. A mapping context of yours with its own Input Mode Query instead of Use Project Default Query keeps working under menus.

Separately, when a menu closes while its confirm button is still held, gameplay input comes back and can read the held button as a fresh press.

Fix: leave Use Project Default Query on for gameplay contexts. If gameplay input works under every menu, the project's default query was never set: run Tools › XenoCore › Apply XenoCore Project Settings, which writes it to Config/DefaultInput.ini. For the close, add a short delay before re-enabling anything the confirm button also triggers, or block the ability with a state tag until the menu has faded.

A HUD element that takes Menu mode kills its own inputs

The Arts palette works in combat because it is a HUD plate, not an activatable screen. A widget that sets Menu mode filters out the gameplay contexts, including its own keys.

Avoid it next time: Add a menu screen.

Enter doesn't press menu buttons on keyboard

Why: CommonUI's Common Button Accept Key Handling is not TriggerClick in the project you are running. XenoCore's project setup writes it to the project's Config/DefaultGame.ini ([/Script/CommonUI.CommonUISettings], CommonButtonAcceptKeyHandling=TriggerClick). If the setup was never applied, or the project already had its own value (setup never overwrites one), the engine's older default applies, where buttons ignore the Enter key. Arrow keys still move focus. Gamepad and mouse work.

Fix: run Tools › XenoCore › Apply XenoCore Project Settings (see Install) and check the Output Log (LogXenoSetup) for a conflict on that line. Or set it yourself: Project Settings › Plugins › Common UI Framework, Button section, Common Button Accept Key Handling = Trigger Click.

Avoid it next time: Restyle the menus.

Pad A on a focused button does nothing, but the mouse works

Fails silently

Keyboard tests pass, which hides it.

Why: a gamepad's A press on a CommonUI button becomes a simulated click at the centre of the focused widget. Anything hit-testable drawn over the button at that point, such as a text label or icon in an Overlay above it, takes the click instead.

Fix: set every text block and image layered over a button to Not Hit-Testable (Self & All Children).

Avoid it next time: Restyle the menus.

A prompt glyph shows the wrong key

Why: most prompts come from rows in UserInterface/Foundation/DT_XenoCore_Actions, which name their keys directly. A few rows exist only so a widget can draw a glyph for an Enhanced Input action. If you rebind the input action and not its row, the prompt names a key that does nothing.

Fix: when you rebind an action, update its row in DT_XenoCore_Actions to the same keys.

Avoid it next time: Show an input action prompt.

A button's prompt stays in the action bar when the button shouldn't be usable

Fails silently

The bar draws a live-looking prompt that does nothing when pressed.

Why: the bottom action bar draws a prompt for every bound action, and it never looks at the button that bound it. Set Is Enabled and collapsing the button do not remove its prompt.

Fix: to show and hide a contextual prompt, call Set Triggering Input Action on the button: pass the action's row to show it, and an empty row handle (Make DataTableRowHandle with nothing set) to remove it. The loadout screen's Unequip prompt works this way.

Avoid it next time: Show an input action prompt.

Pressing Back on a popup closes the whole screen behind it

Why: a popup only receives Back if it is a back handler. Is Back Handler is off by default, so Back falls through to the screen underneath, which closes and takes the popup with it. It looks exactly like "No closed the popup".

Fix: tick Is Back Handler on the popup widget. After it closes, give focus back to the row the player was on, because nothing does it for you. XenoCore's W_XenoCore_ConfirmPopup does both.

Avoid it next time: Add a confirm popup.

Pressing Back on a loot or choice panel loses what it offered

Why: a panel that must be answered cannot let Back simply close it. Turning Is Back Handler off is not enough: Back then goes to whatever else is listening, such as the screen underneath. XenoCore's loot panel takes Back and ignores it.

Fix: for your own mandatory panel, keep Is Back Handler ticked, then in the widget's My Blueprint panel override the function On Handle Back Action and make it return true (ticked) without doing anything else. Back is then taken by the panel and goes nowhere.

Avoid it next time: Add a menu screen.

A screen works the first time and misbehaves when opened again

Why: CommonUI layers reuse screen widgets instead of creating new ones. Anything a screen sets once in Construct or its constructor, such as a "finished" flag, is still set the next time it opens.

Fix: reset per-visit state when the screen is shown (On Activated), not in Construct. Bind button clicks in Construct, though: binding in On Activated adds another handler every time the screen opens.

Avoid it next time: Add a menu screen.

A screen doesn't update after something changes

Why: most screens redraw only when they are told to. Equipment and inventory changes are broadcast as XenoCore.Equipment.Message.SlotChanged and XenoCore.Inventory.Message.Changed, but a screen that listens to neither only changes when you call its refresh.

Fix: after your own action (an unequip, a purchase), call the screen's refresh yourself, or have the screen listen for the message. See Events.

Avoid it next time: Add a menu screen.

A Delete or other screen action acts on the wrong row

Why: a row that reports itself only on On Hovered is never reported by keyboard or gamepad navigation, which moves focus without hovering. The screen then acts on whichever row the mouse last touched.

Fix: report the row from On Focus Received as well, and have destructive actions ask which row has focus at the moment of the press.

Avoid it next time: Add a menu screen.

A list is missing its "none" or "empty" row

Fails silently

The list looks normal, with one row missing.

Why: Set List Items on a List View drops null entries. A null used to mean "nothing equipped" never reaches the list.

Fix: use a real object for the empty row, or show "nothing" outside the list. For unequipping, XenoCore uses a footer prompt instead of an empty list row.

Avoid it next time: Add a menu screen.

A shipped menu entry disappeared after I added mine

Fails silently

The menu still looks complete, with one button changed or missing.

Why: menu entries are merged by Id. An entry in Menu Entries or in an Additional Menu Entry Sets asset that reuses a shipped Id (Equipment, Arts, Skills, Collectables, Party, QuestLog, ChangeTime, Save, Load, Tutorials, Settings, ReturnToTitle, QuitGame) replaces that entry where it stands.

Fix: give your entry its own Id. Reuse a shipped Id only when you mean to replace or hide that entry.

Avoid it next time: Add a menu screen.

A menu entry shows but does nothing when pressed

Why: the entry has neither Action nor Screen, or the one it names did not load, or it is not the right class (a screen must be a Common Activatable Widget, an action a XenoCoreMenuAction). The Output Log says which (LogXenoMenu: "has neither an Action nor a Screen", "did not load as a ..."). In a packaged build, the usual cause is that the screen was not cooked; see Build and editor.

Fix: set Screen or Action to a class of the right type, and make sure it is cooked.

Avoid it next time: Add a menu screen.

HUD and world widgets

A widget above a character never appears, or disappears and never comes back

Fails silently

Nothing is logged.

Why: three causes:

  • A screen-space Widget Component that starts hidden may never get onto the screen; unhiding it later does not help.
  • Its widget class was set in Begin Play. Set it in the construction script so it is ready at registration.
  • The widget hides itself by setting Collapsed. A collapsed widget stops ticking, so it can never notice it should reappear.

Fix: start widget components visible and hide them with Render Opacity. HUD plates built on XenoCoreHudPlateBase already fade with opacity; use Set Shown on them rather than changing visibility.

Avoid it next time: Restyle the menus.

A world widget is enormous, cropped or invisible

Why: with Draw at Desired Size on, the widget is as big as its own layout says, and a Size Box override on any parent in the widget decides that, even on a collapsed branch. With a fixed draw size smaller than the layout, the widget is cropped, often to nothing. An Image whose brush has no size has a desired size of zero, which is invisible on a desired-size component.

Fix: size the widget in the widget Blueprint, not on the component. Walk up from the element to the root and clear any Size Box overrides you did not mean. Give images a brush size, or wrap them in a sized Size Box.

Avoid it next time: Restyle the menus.

A tutorial card never appears

Why: a card shows only the first time its trigger happens in a save, and only if the player's Tips switch is on (main menu › Tutorials). With tips off, cards are still recorded as seen, so turning tips back on does not replay them. A card also waits while any menu, conversation, loading screen or Change Time fade is up. A card whose row has no Triggers never shows by itself.

Fix: to test, run XenoCore.Tutorial.Reset to forget every seen card, or XenoCore.Tutorial.Show <RowName> to show one now. Check the row's Triggers in UserInterface/Tutorials/DT_XenoCore_Tutorials.

Avoid it next time: Tutorial cards.

The dialogue box jumps around the screen during a conversation

Why: the dialogue box is anchored in the world, above the speaker's head. Stopping the character (Gameplay.MovementStopped) does not stop the camera, so looking around sweeps the box across the screen. XenoCore's dialogue locks the look input for the conversation.

Fix: if you build your own world-anchored conversation or cutscene UI, call Set Ignore Look Input on the player controller as well as stopping movement. It is a counter, not a switch: every true needs exactly one matching false, on every exit path, or the camera stays locked.

Avoid it next time: Write an NPC conversation.