diff --git a/Assets/Scripts/UI/Components/DreamTerminalUI.cs b/Assets/Scripts/UI/Components/DreamTerminalUI.cs index e2f7ba2eb..c11a351a2 100644 --- a/Assets/Scripts/UI/Components/DreamTerminalUI.cs +++ b/Assets/Scripts/UI/Components/DreamTerminalUI.cs @@ -132,6 +132,9 @@ namespace AibisDream.UI private bool _cursorVisible = true; private Coroutine _crashSpamCoroutine; private double _editorLastRepaintTime; + private IMECompositionMode _previousImeMode = IMECompositionMode.Auto; + private bool _imeOverridden; + private bool _compositionWasActive; // 全局 alpha(用于 DreamDoorSystem 淡入淡出) public float Alpha { get; set; } = 0f; @@ -171,6 +174,7 @@ namespace AibisDream.UI { base.OnDisable(); _phase = TerminalPhase.Idle; + RestoreImeMode(); StopAllCoroutines(); } @@ -209,12 +213,14 @@ namespace AibisDream.UI public void ForceEnd() { StopAllCoroutines(); + RestoreImeMode(); _phase = TerminalPhase.Done; } public void ResetVisualState() { StopAllCoroutines(); + RestoreImeMode(); _phase = TerminalPhase.Idle; _lines.Clear(); _lineColors.Clear(); @@ -544,11 +550,11 @@ namespace AibisDream.UI }); } - if (_phase == TerminalPhase.WaitingInput && _inputBuffer.Length > 0) + if (_phase == TerminalPhase.WaitingInput) { rows.Add(new RenderRow { - text = ">> Press Enter to submit", + text = ">> TYPE ANSWER | ENTER = CONFIRM", color = colAmberDim, showCursor = false }); @@ -558,7 +564,7 @@ namespace AibisDream.UI { rows.Add(new RenderRow { - text = ">> Submit? (Y/N)", + text = ">> Submit? [Y/Enter = YES | N = EDIT]", color = colWhiteGlow, showCursor = false }); @@ -582,12 +588,15 @@ namespace AibisDream.UI AddLine(GetInputDisplayText(), colWhiteGlow); if (includeConfirmPrompt) - AddLine(">> Submit? (Y/N)", colWhiteGlow); + AddLine(">> Submit? [Y/Enter = YES | N = EDIT]", colWhiteGlow); } private string GetInputDisplayText() { - return promptString + _inputBuffer; + string composition = Application.isPlaying && _phase == TerminalPhase.WaitingInput + ? Input.compositionString + : string.Empty; + return promptString + _inputBuffer + composition; } private void DrawContinuousLine(Vector3 start, Vector3 end, Color color, float thickness, float noiseSeed) @@ -749,28 +758,75 @@ namespace AibisDream.UI { _phase = TerminalPhase.WaitingInput; _inputBuffer = ""; + _compositionWasActive = false; + OverrideImeMode(IMECompositionMode.On); StartCursorBlink(); } private void HandleTypingInput() { + string compositionBeforeInput = Input.compositionString; + bool compositionHandledEnter = _compositionWasActive || !string.IsNullOrEmpty(compositionBeforeInput); + bool enterSeen = false; + bool backspaceSeen = false; + foreach (char c in Input.inputString) { if (c == '\b') { + backspaceSeen = true; if (_inputBuffer.Length > 0) _inputBuffer = _inputBuffer[..^1]; } else if (c == '\n' || c == '\r') { - EnterConfirmPhase(); - return; + enterSeen = true; } else if (!char.IsControl(c) && _inputBuffer.Length < maxInputLength) { _inputBuffer += c; } } + + if (!backspaceSeen && Input.GetKeyDown(KeyCode.Backspace) && string.IsNullOrEmpty(Input.compositionString)) + { + if (_inputBuffer.Length > 0) + _inputBuffer = _inputBuffer[..^1]; + } + + // inputString 在部分输入法/键盘布局下收不到回车,用 GetKeyDown 兜底 + if (!enterSeen && (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))) + enterSeen = true; + + string compositionAfterInput = Input.compositionString; + compositionHandledEnter |= !string.IsNullOrEmpty(compositionAfterInput); + _compositionWasActive = !string.IsNullOrEmpty(compositionAfterInput); + + if (enterSeen && !compositionHandledEnter && _inputBuffer.Length > 0) + EnterConfirmPhase(); + } + + /// + /// 保存玩家原输入法状态,并按终端当前阶段切换 IME。 + /// + private void OverrideImeMode(IMECompositionMode mode) + { + if (!_imeOverridden) + { + _previousImeMode = Input.imeCompositionMode; + _imeOverridden = true; + } + + Input.imeCompositionMode = mode; + Input.compositionCursorPos = new Vector2(Screen.width * 0.5f, Screen.height * 0.62f); + } + + private void RestoreImeMode() + { + if (!_imeOverridden) return; + Input.imeCompositionMode = _previousImeMode; + _imeOverridden = false; + _compositionWasActive = false; } #endregion @@ -780,6 +836,8 @@ namespace AibisDream.UI private void EnterConfirmPhase() { _phase = TerminalPhase.Confirming; + OverrideImeMode(IMECompositionMode.Off); + _compositionWasActive = false; StopCursorBlink(); } @@ -794,6 +852,7 @@ namespace AibisDream.UI else if (Input.GetKeyDown(KeyCode.N)) { _phase = TerminalPhase.WaitingInput; + OverrideImeMode(IMECompositionMode.On); StartCursorBlink(); } } @@ -804,7 +863,8 @@ namespace AibisDream.UI private IEnumerator HandleSubmission(string input) { - string val = input.Trim().ToLower(); + RestoreImeMode(); + string val = input.Trim().ToLowerInvariant(); bool isFalse = val is "false" or "0" or "no" or "不存在"; if (isFalse)