채팅 추가
This commit is contained in:
113
Assets/02_Scripts/Chat/SafeBaseInput.cs
Normal file
113
Assets/02_Scripts/Chat/SafeBaseInput.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
/// <summary>
|
||||
/// 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 버전과 플랫폼에 따라 다르다. 그래서 막아버리지 않고
|
||||
/// 한 번 시도해 보고, 던지면 그때부터 안전한 기본값으로 고정한다. 되는 환경에서는
|
||||
/// 한글 조합 중인 글자가 그대로 보이고, 안 되는 환경에서도 완성된 글자는 들어온다.
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>데스크톱 전용 앱이다. 터치를 물어볼 필요 없이 잘라낸다.</summary>
|
||||
public override bool touchSupported => false;
|
||||
|
||||
void MarkUnavailable()
|
||||
{
|
||||
if (legacyInputUnavailable) return;
|
||||
legacyInputUnavailable = true;
|
||||
Debug.LogWarning(
|
||||
"[SafeBaseInput] 레거시 Input 접근이 막혀 있습니다. IME 조합 표시 없이 동작합니다. " +
|
||||
"(입력 자체는 IMGUI 이벤트로 들어오므로 완성된 글자는 정상 입력됩니다)");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user