유니티 관련 입력 (IME)

  인터페이스에 InputField는 커서 근처 중국어 입력 방법의 대안 블록은 편리한 입력 결과에 따라되지 않습니다.

  우리는 비슷한이 볼 수 있지만, WebGL이 있습니다 : https://blog.csdn.net/Rowley123456/article/details/103726927/

  그것은 바로 플랫폼에 관련된 HTML 입력 컨트롤 다른 방법 프레임 위치,의 추가에 의해 수정되고 일반적인 특성이 없습니다.

  이 아이디어, 윈도우 제어 모듈에 직접 입력에 따르면 :

    [같이 DllImport ( " imm32.dll " )]
     공용  정적  통근 을 IntPtr ImmGetContext (HWND을 IntPtr); 
    [같이 DllImport ( " imm32.dll " )]
     공용  정적  통근  INT의 ImmReleaseContext (HWND를 IntPtr, hIMC을 IntPtr); 
    [같이 DllImport ( " imm32.dll " )]
     공용  정적  통근  부울 ImmSetCompositionWindow (hIMC을 IntPtr, REF COMPOSITIONFORM lpCompForm); 
    [System.Runtime.InteropServices.DllImport ( " USER32.DLL " )]
    개인  정적  통근 System.IntPtr 이름 GetActiveWindow ();

  그런 다음 창 핸들을 얻을, 설정 위치로 복귀 정확하지만 결과는 옵션 위치를 상자를 변경하지 않은 :

    보이드 SetInputPos () 
    { 
        을 IntPtr hImc = ImmGetContext (GetWindowHandle ()); 
        COMPOSITIONFORM의 CF는 = 새로운 COMPOSITIONFORM을 (); 
        cf.dwStyle = 2 ; 
        cf.ptCurrentPos.X = 500 ; 
        cf.ptCurrentPos.Y = 500 ;
        불리언 setcom = ImmSetCompositionWindow (hImc, REF CF);    // setcom == 사실 
        ImmReleaseContext (GetWindowHandle (), hImc); 
    } // 结构体略

  이것은 오히려 어색하고, 주어진 않고 아무 반응이 설정되어 있지 ......

  유니티, BaseInputModule 그래서 찾기 위해 내부 표준 입력 (IME 인터페이스)를 달성하기 위해 계정에 각각의 기본 인터페이스 플랫폼을 그것이 BaseInput 다음과 같은 구성 요소가 있습니다 것을 발견한다 :

// StandaloneInputModule : PointerInputModule
 // PointerInputModule : BaseInputModule 
공공  추상  클래스 BaseInputModule : UIBehaviour 
{ 
    보호 BaseInput m_InputOverride을;
    // 
    // 摘要:
     //      현재 BaseInput은 입력 모듈에 의해 사용된다. 
    공공 BaseInput 입력 { GET ; } 
    
    ... 
}

  같은 입력 외모와의 관계는, 윈도우 API 비트 등으로 변수의 내부를 볼 수 :

공공  클래스 BaseInput : UIBehaviour 
{ 
    공공 BaseInput (); 

    // 
    // 摘要:
     //      Input.imeCompositionMode에 인터페이스. 사용자 입력을 제공하기 위해 오버라이드 (override) 할 수
     //      대신 입력 클래스를 사용하는. 
    공공  가상 IMECompositionMode의 imeCompositionMode { 얻을 ; 설정 ; }
     // 
    // 摘要:
     //      Input.compositionCursorPos에 인터페이스. 사용자 정의 제공하기 위해 재정의 할 수 있습니다
     //      입력 클래스를 사용하는 대신 입력합니다. 
    공공  가상 Vector2 compositionCursorPos {얻을 ; 설정 ; } 
    
    ... 
}

  만큼 자신의 설정 compositionCursorPos이 원하는 효과를 얻을 직접 상속 유형을 만들 수있을 것입니다 상속 추정하고 StandaloneInputModule에 BaseInput을 설정 한 방식에 의해 반영 :

    [RequireComponent ( 대해서 typeof (InputField))]
     공용  클래스 IME_InputFollower : BaseInput 
    { 
        공개 InputField inputField;
        공공  재정의 Vector2 compositionCursorPos 
        { 
            GET 
            { 
                반환  기본 .compositionCursorPos; 
            } 
            집합 
            { 
                베이스 .compositionCursorPos = 새로운 Vector2 ( 200 , 200 );  // 테스트 
            } 
        }         
        
        개인  정적  무효SetCurrentInputFollower (IME_InputFollower 타겟) 
        { 
            VAR inputModule = EventSystem.current.currentInputModule;
            경우 (inputModule는) 
            { 
                var에 . 필드 inputModule.GetType () GetField (= " m_InputOverride " , BindingFlags.Instance | BindingFlags.NonPublic는)
                경우 (필드 =! ) 
                { 
                    field.SetValue (inputModule 대상); 
                    경우 (목표) 
                    { 
                        target.inputField.OnPointerDown ( 새로운PointerEventData (EventSystem.current));
                        INT caretPosition = 문자열 .IsNullOrEmpty (target.inputField.text) == 거짓 ? target.inputField.text.Length : 0 ; 
                        target.inputField.caretPosition = caretPosition; 
                    } 
                } 
            } 
        } 
    }

  초점이 InputField을 때, SetCurrentInputFollower BaseInput 사용하여 반사가 상자 또는 입력을 새로 고침 할 수있을 것입니다 그래서, 현재 InputModule로 설정하고, 수동으로 설정하고 OnPointerDown 커서 위치에 트리거 창은 InputField을 전환하지 않을 것이다 따라하지. 편집기 창에서 창 크기가 너무 편집기 창 크기가 다르고 위치가 잘못 계산하는 렌더링 시간을 게임이 아닌 렌더링 부분 크기의 크기가 존재이다.

  PS : 나는 Windows에서 테스트 할 때, compositionCursorPos 창 좌표, 윈도우와 시작 왼쪽 모서리 좌표 (0, 0)을 계산 DX 플랫폼의 특성을 모르는 것으로 나타났다.

 

 

   원래의 상자를 볼 수있는 창을 기입하는 대체 입력 방법 :

  그것은 인터페이스의 범위를 넘어, 이제 입력 상자의 왼쪽 아래에있는 다른 위치 메이크업 상자가 나타납니다을 계산하는 IME_InputFollower 구성 요소를 추가 :

    공공  재정의 Vector2 compositionCursorPos 
    { 
        GET 
        { 
            반환  기본 .compositionCursorPos; 
        } 
        집합 
        { 
# 만약 UNITY_STANDALONE의
             VAR의 크기 = 새로운 Vector2 (Screen.width, Screen.height); 
            Vector3 [] coners = 새로운 Vector3 [ 4 ]; 
            (inputField.transform 같은 RectTransform) .GetWorldCorners (coners); 
            Vector2 leftBottom = coners [ 0 ];
            VAR compositionCursorPos는 = 새로운Vector2 (leftBottom.x, size.y - leftBottom.y);
            베이스 .compositionCursorPos = compositionCursorPos;
#else 
            베이스 .compositionCursorPos = 값;
#endif 다음 
        } 
    }

  증거 실제로 가능, 모든 플랫폼에서 실행되어야한다는 논리가 그대로 compositionCursorPos 라인에 설정 로직 및 플랫폼의 차이를 추가 할 수 있도록 긴 좌표의 계산에 관심이있을 수있는 (그러나 윈도우 나 플랫폼의 다른 요구에 추가) .

 

추천

출처www.cnblogs.com/tiancaiwrk/p/12603955.html