SHA256
Document UI And Localization
This commit is contained in:
1 parent
a389283d33
commit
0fc01a84de
8 files changed
+910
-71
No files matched your search
+37
-9
@@ -6,15 +6,33 @@ using UnityEngine.UI;
|
||||
|
||||
namespace ADOFAIRenderer.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Hold-Escape-to-cancel handler shown during a render.
|
||||
/// <para>
|
||||
/// Created by <c>RenderManager</c> when the render reaches the OnScene stage, on a GameObject kept across scene loads.
|
||||
/// While Escape is held, a centered panel shows a countdown from 3 seconds; holding it for the full 3 seconds
|
||||
/// (measured in real time with a <see cref="Stopwatch"/>, independent of the patched game time) calls
|
||||
/// <c>RenderManager.CancelRender</c>. Releasing Escape earlier hides the panel and resets the countdown.
|
||||
/// The component destroys its GameObject as soon as <c>RenderManager.IsActive</c> is false (stage below OnScene).
|
||||
/// Runs on the Unity main thread.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
internal class EscapeHandlerUI : MonoBehaviour
|
||||
{
|
||||
/// <summary>Centered countdown panel (background and text); inactive while Escape is not held.</summary>
|
||||
private GameObject _containerObj = null!;
|
||||
/// <summary>Countdown text inside <see cref="_containerObj"/>.</summary>
|
||||
private TextMeshProUGUI _textComponent = null!;
|
||||
/// <summary>Real-time hold duration of the current Escape press; <c>null</c> while Escape is not held.</summary>
|
||||
private Stopwatch? _escapeStopwatch;
|
||||
|
||||
/// <summary>
|
||||
/// Builds the overlay canvas and the hidden countdown panel. Layout values are canvas units at the 1920x1080
|
||||
/// reference resolution.
|
||||
/// </summary>
|
||||
private void Start()
|
||||
{
|
||||
// Set UI layer (5)
|
||||
// Set UI layer (5, Unity's built-in "UI" layer)
|
||||
gameObject.layer = 5;
|
||||
|
||||
// Canvas setup
|
||||
@@ -22,7 +40,7 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
canvas.sortingOrder = 10000; // Placed above debug monitor
|
||||
|
||||
// Responsive Canvas Scaler setup
|
||||
// Canvas Scaler: 1920x1080 reference resolution, width and height matched equally (0.5)
|
||||
var scaler = gameObject.AddComponent<CanvasScaler>();
|
||||
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
scaler.referenceResolution = new Vector2(1920, 1080);
|
||||
@@ -31,7 +49,7 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
|
||||
gameObject.AddComponent<GraphicRaycaster>();
|
||||
|
||||
// 1. Create container and background panel object
|
||||
// 1. Create container and background panel object: 460x160 units at the screen center
|
||||
_containerObj = new GameObject("EscapeContainer");
|
||||
_containerObj.transform.SetParent(transform, false);
|
||||
_containerObj.layer = 5;
|
||||
@@ -46,7 +64,7 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
containerRect.anchoredPosition = Vector2.zero; // Screen center
|
||||
containerRect.sizeDelta = new Vector2(460, 160);
|
||||
|
||||
// 2. Create text object
|
||||
// 2. Create text object: 60 pt centered rich text, no wrapping, 10-unit margin inside the panel
|
||||
var textObj = new GameObject("EscapeText");
|
||||
textObj.transform.SetParent(_containerObj.transform, false);
|
||||
textObj.layer = 5;
|
||||
@@ -57,7 +75,8 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
_textComponent.textWrappingMode = TextWrappingModes.NoWrap;
|
||||
_textComponent.richText = true;
|
||||
|
||||
// Apply game's default font (RDString.fontData.fontTMP)
|
||||
// Apply the game's TextMeshPro font for the current language (RDString.fontData.fontTMP, assigned in
|
||||
// RDString.Setup). It is null before RDString.Setup has run; TextMeshPro's default font is kept then.
|
||||
if (RDString.fontData.fontTMP != null)
|
||||
_textComponent.font = RDString.fontData.fontTMP;
|
||||
|
||||
@@ -71,9 +90,13 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
_containerObj.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the Escape key every frame: shows and updates the countdown while it is held, cancels the render after
|
||||
/// 3 seconds of holding, and hides the panel when it is released.
|
||||
/// </summary>
|
||||
private void Update()
|
||||
{
|
||||
// Destroy self if rendering is no longer active
|
||||
// Destroy self once the render is inactive (stage below OnScene: finished, cancelled or failed)
|
||||
if (!RenderManager.IsActive)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
@@ -82,6 +105,7 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
|
||||
if (Input.GetKey(KeyCode.Escape))
|
||||
{
|
||||
// First frame of the press: start timing and show the panel
|
||||
if (_escapeStopwatch == null)
|
||||
{
|
||||
_escapeStopwatch = new Stopwatch();
|
||||
@@ -92,13 +116,14 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
var elapsed = (float)_escapeStopwatch.Elapsed.TotalSeconds;
|
||||
var remaining = Mathf.Max(0f, 3f - elapsed);
|
||||
|
||||
// Update remaining time text
|
||||
// Update remaining time text (seconds, one decimal). The text is fixed English, not localized.
|
||||
_textComponent.text = $"<color=#FF5252>Cancelling in {remaining:F1}s..</color>\n<size=40><color=#DDDDDD>Hold Esc to cancel render</color></size>";
|
||||
|
||||
// Micro pulse animation (container smoothly scales up while holding)
|
||||
// Grow animation: the panel scales linearly from 1.0 to 1.15 over the 3-second hold
|
||||
var scale = 1.0f + elapsed / 3.0f * 0.15f;
|
||||
_containerObj.transform.localScale = new Vector3(scale, scale, 1f);
|
||||
|
||||
// Held for the full 3 seconds: reset the panel, then cancel
|
||||
if (elapsed < 3f) return;
|
||||
|
||||
_escapeStopwatch.Stop();
|
||||
@@ -106,12 +131,14 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
_containerObj.transform.localScale = Vector3.one; // Reset scale
|
||||
_containerObj.SetActive(false);
|
||||
|
||||
// Cancel rendering and exit scene
|
||||
// Cancel rendering: RenderManager.CancelRender resets the render state, stops the encoder as cancelled and
|
||||
// ends the render. StopFFmpeg also destroys this handler's GameObject.
|
||||
if (RenderManager.Instance)
|
||||
RenderManager.Instance.CancelRender();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Escape released before 3 seconds: stop timing and hide the panel
|
||||
if (_escapeStopwatch == null) return;
|
||||
_escapeStopwatch.Stop();
|
||||
_escapeStopwatch = null;
|
||||
@@ -120,6 +147,7 @@ internal class EscapeHandlerUI : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stops the hold stopwatch if a press is in progress.</summary>
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_escapeStopwatch == null) return;
|
||||
|
||||
Reference in new issue
Block a user