【Unity】文字列範囲選択時にソフトウェアキーボードを非表示にする

Unityで文字列を範囲選択したい場合、uGUIのInputFieldを使うと文字列を選択できるようになりますが

<img src="https://qiita-image-store.s3.amazonaws.com/0/53200/df5a6378-5ff1-14cd-c6cc-ae749d3cf3e1.png" width="50%">

Android実機だとソフトウェアキーボードが表示されてしまいます

<img src="https://qiita-image-store.s3.amazonaws.com/0/53200/e20feb9c-62ba-d797-0aa8-026f17ec6ded.png" width="50%">

こいつをどうにかして表示されないようにしたい

## Hide Mobile Input

InputFieldのインスペクタ上に**Hide Mobile Input**とうチェックボックスがあるのでONにしてみました

<img src="https://qiita-image-store.s3.amazonaws.com/0/53200/038e38ae-3040-08f9-d9c5-a60fa05bfd5a.png" width="50%">

しかし、相変わらずキーボードが表示される・・・・

なんだこのプロパティということで公式のドキュメントを見ると

* [Unity - Manual: Input Field](https://docs.unity3d.com/Manual/script-InputField.html)

> Hide Mobile Input (iOS only)

Androidテメーはダメだ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/53200/56fb8bcb-cb7c-3527-9afc-8f3eb6555706.png)


ソースコード修正してみようとコード眺めてみましたが、これは無理だと思い他の方法を模索しました

* [Unity-Technologies / ui / UnityEngine.UI / UI / Core / InputField.cs — Bitbucket](https://bitbucket.org/Unity-Technologies/ui/src/2018.3.0f2/UnityEngine.UI/UI/Core/InputField.cs)

## Kindleアプリはそういや出来てるよな

であれば、Androidネイティブの機能でやればいいのかと思い、色々調べて**TextView**で実現出来そうだったのでさっそくUnityから呼び出せるAndroidのプラグインを作ってみました

## Plugin

Repository: https://github.com/satooon/unity_text_selectable

```java
package com.unity.plugin.ui;

import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.unity3d.player.UnityPlayer;

public class TextSelectable {

    private TextView textView;

    public static TextSelectable Make(final int width, final int height, final int left, final int top) {
        final TextSelectable textSelectable = new TextSelectable();

        UnityPlayer.currentActivity.runOnUiThread(new Runnable() {
            public void run() {
                RelativeLayout layout = new RelativeLayout(UnityPlayer.currentActivity);
                UnityPlayer.currentActivity.addContentView(layout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
                layout.setGravity(Gravity.TOP);

                textSelectable.textView = new TextView(UnityPlayer.currentActivity);
                textSelectable.SetTextIsSelectable(true);
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
                params.leftMargin = left;
                params.topMargin = top;
                layout.addView(textSelectable.textView, params);
            }
        });

        return textSelectable;
    }

    public void SetText(String text) {
        this.textView.setText(text);
    }

    public void SetTextIsSelectable(boolean selectable) {
        this.textView.setTextIsSelectable(selectable);
    }
}
```

表示中のアクティビティ上に直接配置させてます

あとはUnity側で呼び出す

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour
{
    void Start()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        this.ShowTextView();
#endif
    }

    void ShowTextView()
    {
        using (var cls = new AndroidJavaClass("com.unity.plugin.ui.TextSelectable")) {
            using (var textSelectable = cls.CallStatic<AndroidJavaObject>("Make", 500, 500, 0, 0)) {
                textSelectable.Call("SetText", "test test test test test test test");
            }
        }
    }
}
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/53200/2d0b4e1f-19d6-48e3-926c-91dce072710b.png" width="50%">

キーボードでてない…！

コンテキストメニューいじりたいなとなったら、それもプラグインでやらないといけないですが

---

開発中、UnityからAndroidのプラグインのパッケージ名が見つからない問題で数日悩みました

TextSelectableがTextViewを継承していたのが原因ぽかったです

何も継承してないクラスじゃないとUnityから呼べないのかなぁ