Slide 1

Slide 1 text

Unityでチャットに使える モバイルキーボードの実現 2020/01/19 CA.unity #1

Slide 2

Slide 2 text

Nakaji Kohki / なかじ Twitter: @nkjzm ・日本VR学会認定 上級VR技術者 ・専門学校の先生(VRエンジニア専攻) ・Podcast『xR.fm』のパーソナリティ ・エンジニア系勉強会のオーガナイザー 略歴: CyberAgent → メルカリ R4D XR → 現在 Unity / VR Engineer ~0:30

Slide 3

Slide 3 text

~1:00 ALTDEUS: Beyond Chronos ● VRゲーム開発してます! ○ アドベンチャー ○ マシンアクション ○ VRライブ ● Quest/Riftで好評配信中 ● Steam版 本日リリース!!  ● PSVR版 4/15発売

Slide 4

Slide 4 text

本日の内容 モバイルキーボードを 気持ちよく実装する方法 ~2:00 よくある実装 今回の実装 このアプリの開発で使用

Slide 5

Slide 5 text

アジェンダ ~2:30 1. キーボードの高さにチャット欄を調整する a. キーボード高さの取得 b. チャット欄に反映させる 2. ネイティブの入力フィールドを非表示に 3. ネイティブボタンのOKイベント取得 4. キーボードのハンドリング

Slide 6

Slide 6 text

キーボード高さの取得(1/2) iOSはそのままいける > Android では Rect は 0 です。 https://docs.unity3d.com/ja/current/ScriptReference/TouchScreenKeyboard-area.html → baba-s さんのスクリプトで対応 ~3:00 1. Rect area = UnityEngine.TouchScreenKeyboard.area; 2. int height = Mathf.RoundToInt(area.height);

Slide 7

Slide 7 text

キーボード高さの取得(2/2) 引用元: https://github.com/baba-s/UniSoftwareKeyboardArea/blob/master/Scripts/SoftwareKeyboardArea.cs ~3:30 1. var currentActivity = unityClass.GetStatic( "currentActivity" ); 2. var unityPlayer = currentActivity.Get( "mUnityPlayer" ); 3. var view = unityPlayer.Call( "getView" ); 4. 5. if ( view == null ) return 0; 6. 7. int result; 8. using ( var rect = new AndroidJavaObject( "android.graphics.Rect" ) ) 9. { 10. view.Call( "getWindowVisibleDisplayFrame", rect ); 11. result = Screen.height - rect.Call( "height" ); 12. }

Slide 8

Slide 8 text

チャット欄に反映させる(1/3) ● uGUIに反映させる処理 ○ 右図ならBottomに反映 ○ uGUIの組み方次第 ○ Debug表示で 実際の値が見られる ~4:00 1. chatContainer.sizeDelta = new Vector2(0, -margin);

Slide 9

Slide 9 text

チャット欄に反映させる(2/3) ● 解像度の調整 ○ キーボードの高さは端末の解像度で返ってくる ○ uGUIはCanvasの解像度で制御されている(ことが多い) ~4:30 1. // 解像度比を取得 2. var resolutionHeight = chatContainer 3. .GetComponentInParent() 4. .GetComponent().sizeDelta.y; 5. var rate = resolutionHeight / Screen.height; 6. 7. var margin = height * rate; 8. chatContainer.sizeDelta = new Vector2(0, -margin);

Slide 10

Slide 10 text

チャット欄に反映させる(3/3) ~5:00 ● SafeAreaの罠 ○ TouchScreenKeyboard.areaは SafeAreaの下部領域の高さを含む

Slide 11

Slide 11 text

ネイティブの入力 フィールドを非表示 ~6:00 変数が用意されている TouchScreenKeyboard.hideInput →InputFieldの HideMobileInputで上書きされる ※ネイティブのコピペ機能などが使えなくなる ※Androidだと疑似的な実装 https://docs.unity3d.com/ja/current/ScriptReference/TouchScreenKeyboard-hideInput.html)

Slide 12

Slide 12 text

ネイティブボタンの OKイベント取得 ● Androidだとキーボード表示中に キーボード外の入力が拾えない ○ →ネイティブのOKボタンで送信 ● keyboard.statusを監視で実現 ○ Done:OKを押した時 ○ LostFocus:フォーカスが外れた時 ~7:00

Slide 13

Slide 13 text

キーボードのハンドリング ~8:00 1. Keyboard = TouchScreenKeyboard.Open(string.Empty, TouchScreenKeyboardType.Search); 2. EventSystem.current.SetSelectedGameObject(chatInput.gameObject); ● Unity領域タップ or OKボタン押下でキーボードが閉じる ○ →チャットだと開きっぱなしにしたい ● 色々なタイミングで再表示/再フォーカス ○ チャット送信をした時 ○ Unityの送信ボタンを押した瞬間 ○ ボタンを押しかけて押さなかった時

Slide 14

Slide 14 text

できなかった事 ● キーボードの再表示 ○ Androidは微妙にチラつく(ちょっと妥協している) ● Androidで通知がくるとキーボードのheightに含まれる ○ ネイティブ部分の処理を見直せば改善しそう ~8:30 解決方法わかる人いたら教えてくださいmm

Slide 15

Slide 15 text

● キーボードの高さ周りの処理は少し複雑 ○ Android対応と解像度、SafeAreaを考慮しよう ● TouchScreenKeyboard.hideInputはInputFieldで上書きされる ● ネイティブのボタン:status監視で疑似的にハンドリング ● キーボードの常時表示:再フォーカスを繰り返して実現 ● (毎回ビルドして確認するのがめちゃくちゃ大変だった) ○ →なので・・・ まとめ ~9:00

Slide 16

Slide 16 text

公開しました UnityMobileKeyboardSample (Unlicense) https://github.com /nkjzm/UnityMobileKeyboardSample ~9:30

Slide 17

Slide 17 text

最後に

Slide 18

Slide 18 text

Roppongi.unity開催します ~10:00 Unityに関するLTイベント ● 2/24(水) 20:00〜 ● YouTube Live & cluster ● 協賛 ○ クラスター株式会社 ○ 株式会社ハシラス ● #roppongiunity

Slide 19

Slide 19 text

フォロー & チャンネル登録 お願いします!! ありがとうございました!! @nkjzm VRエンジニアなかじ

Slide 20

Slide 20 text

No content