ChairInput. Пишемо гру в Unity, керовану за допомогою віртуальної клавіатури Android. Проблема з кутом огляду камери

Всім привіт, я написав клавіатурний тренажер під Android в Unity3D, він не сильно заточений під особливих дітей, а призначений для широкого користувача (ну я так думаю). І в цьому пості я хочу розповісти про проблему перекривання частині екрана клавіатурою і способи її вирішення.



Трохи про гру
Хоча це не має відношення до теми поста, розповім трохи про гру:

Принцип простий, Ви вибираєте один із запропонованих текстів чи вводите свій і починаєте тренуватися друкувати. При натисканні вірною кнопки в букву летить м'яч. Якщо ви помиляєтеся, відпускається зелена завіса і не піднімається до тих пір, поки Ви не видалите зайве.

Мене попросили педагоги зробити цю гру, так як популярні тренажери сильно заточені на швидкість друку сильно заточені на швидкість і правильну розстановку пальців. Це не дуже підходить для заняттями особливими людьми, так. як я можу друкувати тільки двома пальцями (інші не розгинаються), а моя подруга взагалі ногою. Про швидкості друку взагалі мовчу. Так що я не намагаюся переплюнути хлопців з klava.org або клавагонки, а пишу своє.



Робота з введенням
Роботу з введенням тексту я вирішив організувати через стандартний Unity UI InputField, подія про натисканні кнопки і останній символ виходить так.

InputField field;
public void Start()
{
field = GetComponent<InputField> ();
field.onValueChange.AddListener (delegate {ValueChangeCheck ();});
// focus on field loading on scene
field.Select ();
field.ActivateInputField ();

}

// Invoked when the value of the text field changes.
public void ValueChangeCheck()
{
string symbol = field.text.Length==0?null: field.text[field.text.Length-1]+"";
}

Далі відбувається нудна магія з кидання м'яча в літери, публікувати її не буду, бо там купа говнокода вона вимагає рефакторинг.

Проблема
На комп'ютері все працювало чудово, але коли я запустив гру на Android, побачив Бескрайное небо Аустерліца, що клавіатура наїхала на основний ігровий простір і перекрило всі.



В гуглі нічого доброго не знайшов (можливо, я просто гуглити не вмію) і я став сам колупати властивості камери.

Вирішення проблеми
В налаштуваннях я знайшов властивість Viewport Rect і виставив в ньому Y на 0.5, думав, що на цьому мої проблеми закінчилися, але немає.



У вертикальній орієнтації екрану клавіатура перестала наїжджати на екран, але в горизонтальній клавіатура все ще наїжджала на картинку, тоді я погрався з цифрами і підібрав значення для горизонтальної, 0.3. І правильно, все поїхало у вертикалі.

Подумавши, я зрозумів, що коефіцієнт висоти клавіатури на висоту екрану. Вирішив написати скрипт, який змінює цей коефіцієнт, розраховуючи з поточної висоти клавіатури. Знайшов на stackoverflow скрип отримання висоти і написав такий скрипт:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class CameraController : MonoBehaviour {
Camera cam;
// Use this for initialization
void Start () {
cam = GetComponent<Camera> ();
}

#if (UNITY_ANDROID)

Rect KeyBoardRect = new Rect(0, 0, 1,1);
void FixedUpdate () {
KeyBoardRect.y = ((float)GetKeyboardSize ()) / Screen.height;

cam.rect = KeyBoardRect;

}
public int GetKeyboardSize()
{
using (AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
AndroidJavaObject View = UnityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer").Call<AndroidJavaObject>("getView");

using (AndroidJavaObject Rct = new AndroidJavaObject("android.graphics.Rect"))
{
View.Call("getWindowVisibleDisplayFrame", Rct);

return Screen.height - Rct.Call<int>("height");
}
}
}
#endif

}

Всі чудово запрацювало судячи з Profiler'у без втрати FPS.

→ Гру можна скачати тут
→ Мій сайт: aacidov.ru
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.