using System; using UnityEngine; using UnityEngine.EventSystems; /// /// uGUI InputField 가 IME 상태를 물어보는 통로. 레거시 UnityEngine.Input 접근을 감싼다. /// /// 왜 필요한가: /// 이 프로젝트는 Active Input Handling 이 "Input System Package (New)" 전용이다. /// 그 모드에서 레거시 UnityEngine.Input 의 멤버는 InvalidOperationException 을 던진다. /// 그런데 UnityEngine.UI.InputField 는 조합 문자(한글 입력 중인 글자)를 표시하려고 /// compositionString / imeCompositionMode / compositionCursorPos 를 매 프레임 읽는다. /// 그대로 두면 입력 칸에 포커스가 가는 순간부터 프레임마다 예외가 터진다. /// /// BaseInputModule.input 은 BaseInput 을 상속한 컴포넌트를 자동으로 고르지 않는다 /// (기본값은 정확히 typeof(BaseInput) 인 것만 쓴다). 그래서 이걸 붙인 뒤 /// module.inputOverride 에 직접 넣어줘야 한다. ChatWindowUI 가 그렇게 한다. /// /// 예외가 나는지는 Unity 버전과 플랫폼에 따라 다르다. 그래서 막아버리지 않고 /// 한 번 시도해 보고, 던지면 그때부터 안전한 기본값으로 고정한다. 되는 환경에서는 /// 한글 조합 중인 글자가 그대로 보이고, 안 되는 환경에서도 완성된 글자는 들어온다. /// public class SafeBaseInput : BaseInput { bool legacyInputUnavailable; public override string compositionString { get { if (legacyInputUnavailable) return string.Empty; try { return base.compositionString ?? string.Empty; } catch (Exception) { MarkUnavailable(); return string.Empty; } } } public override IMECompositionMode imeCompositionMode { get { if (legacyInputUnavailable) return IMECompositionMode.Auto; try { return base.imeCompositionMode; } catch (Exception) { MarkUnavailable(); return IMECompositionMode.Auto; } } set { if (legacyInputUnavailable) return; try { base.imeCompositionMode = value; } catch (Exception) { MarkUnavailable(); } } } public override Vector2 compositionCursorPos { get { if (legacyInputUnavailable) return Vector2.zero; try { return base.compositionCursorPos; } catch (Exception) { MarkUnavailable(); return Vector2.zero; } } set { if (legacyInputUnavailable) return; try { base.compositionCursorPos = value; } catch (Exception) { MarkUnavailable(); } } } /// 데스크톱 전용 앱이다. 터치를 물어볼 필요 없이 잘라낸다. public override bool touchSupported => false; void MarkUnavailable() { if (legacyInputUnavailable) return; legacyInputUnavailable = true; Debug.LogWarning( "[SafeBaseInput] 레거시 Input 접근이 막혀 있습니다. IME 조합 표시 없이 동작합니다. " + "(입력 자체는 IMGUI 이벤트로 들어오므로 완성된 글자는 정상 입력됩니다)"); } }