suppress world interaction while a menu panel is open
DialogueInteractable, DialogueTransitionController, and DialogueUIVisibility are reworked against the new UI layer: visibility is driven by UIStateController rather than each component toggling canvases itself, which removes the duplicated show/hide logic the two had accumulated. NPCStandIn now ignores the interact button while UIStateController reports a menu open, so pressing interact through an open panel no longer starts a conversation behind it. The yarnproject change is graph-editor node positions only. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -1,23 +1,13 @@
|
||||
using NightclubArcadia.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NightclubArcadia.Dialogue
|
||||
{
|
||||
/// <summary>
|
||||
/// Shows and hides the dialogue UI *without* deactivating its GameObject.
|
||||
///
|
||||
/// SetActive(false) is not a safe way to hide this UI. TextMeshProUGUI
|
||||
/// resolves its Canvas through Graphic.CacheCanvas, which calls
|
||||
/// GetComponentsInParent(includeInactive: false) and then requires
|
||||
/// canvas.isActiveAndEnabled. Once the Canvas GameObject has been
|
||||
/// deactivated, that lookup yields null, and TMP.GetTextInfo does:
|
||||
///
|
||||
/// if (m_canvas == null) m_canvas = this.canvas; // still null
|
||||
/// GenerateTextMesh(); // m_canvas.worldCamera -> NRE
|
||||
///
|
||||
/// GenerateTextMesh dereferences m_canvas unguarded, so the very next line
|
||||
/// Yarn tries to type throws NullReferenceException. Keeping the hierarchy
|
||||
/// active and driving a CanvasGroup instead means the cached Canvas
|
||||
/// reference stays valid across any number of enter/exit dialogue cycles.
|
||||
/// Forwards to <see cref="PanelVisibility"/> — kept as a thin wrapper so
|
||||
/// existing call sites (NPCStandIn, DialogueInteractable,
|
||||
/// DialogueTransitionController) continue to compile unchanged.
|
||||
/// </summary>
|
||||
public static class DialogueUIVisibility
|
||||
{
|
||||
@@ -27,41 +17,12 @@ namespace NightclubArcadia.Dialogue
|
||||
/// case the caller must wait one frame before rendering text so that
|
||||
/// TMP's OnEnable can re-cache its Canvas.
|
||||
/// </summary>
|
||||
public static bool Show(GameObject dialogueUI) => SetVisible(dialogueUI, true);
|
||||
public static bool Show(GameObject dialogueUI) => PanelVisibility.Show(dialogueUI);
|
||||
|
||||
/// <summary>
|
||||
/// Hides the dialogue UI, leaving the hierarchy active. See class docs.
|
||||
/// Hides the dialogue UI, leaving the hierarchy active. See
|
||||
/// <see cref="PanelVisibility"/>.
|
||||
/// </summary>
|
||||
public static void Hide(GameObject dialogueUI) => SetVisible(dialogueUI, false);
|
||||
|
||||
static bool SetVisible(GameObject dialogueUI, bool visible)
|
||||
{
|
||||
if (dialogueUI == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The UI may still be deactivated by an older saved scene state or
|
||||
// by code that predates this helper. Recover from that, and tell
|
||||
// the caller a frame of grace is needed.
|
||||
var wasReactivated = false;
|
||||
if (!dialogueUI.activeSelf)
|
||||
{
|
||||
dialogueUI.SetActive(true);
|
||||
wasReactivated = true;
|
||||
}
|
||||
|
||||
var group = dialogueUI.GetComponent<CanvasGroup>();
|
||||
if (group == null)
|
||||
{
|
||||
group = dialogueUI.AddComponent<CanvasGroup>();
|
||||
}
|
||||
|
||||
group.alpha = visible ? 1f : 0f;
|
||||
group.interactable = visible;
|
||||
group.blocksRaycasts = visible;
|
||||
|
||||
return wasReactivated;
|
||||
}
|
||||
public static void Hide(GameObject dialogueUI) => PanelVisibility.Hide(dialogueUI);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user