Search Unity

Implementing Daydream Keyboard

Discussion in 'Daydream' started by duncangroberts, Jun 27, 2018.

  1. duncangroberts

    duncangroberts

    Joined:
    Jul 22, 2015
    Posts:
    69
    Hi there,

    I am attempting to implement the daydream keyboard into an app built in unity and am not able to get this to work. I'm massively lost if I'm honest, thinking it would be as simple as adding some input fields and the GVRKeyboard prefabs.

    I have added the keyboard prefab as a sibling of the main camera and added two input fields with the onpointerclick function added as instructed.

    I however get a null reference exception and assume this is due to the daydream keyboard delegate field being blank. The example scene in the sdk shows the daydream delegate example prefab but I am unsure how to implement this for two input fields.

    Also does the keyboard render in the unity editor or must it be built and run on a phone?

    Thanks,

    Duncan
     
    Last edited: Jun 27, 2018
  2. duncangroberts

    duncangroberts

    Joined:
    Jul 22, 2015
    Posts:
    69
    Just to say I am using Unity 2018.1.02f and GVR Sdk
     
  3. derekrocco

    derekrocco

    Joined:
    Mar 27, 2018
    Posts:
    4
    Hi Duncan,

    Sorry you've been having some trouble, and thanks for reaching out!

    Regarding Instant Preview (Rendering in the Unity Editor): no. The Keyboard unfortunately must be built and run on a phone.

    My apologies for the rough state of the Keyboard. We're planning on adding a couple of features to GvrKeyboard, revamping the demo scene, and fixing up a lot of the example prefabs - hopefully they will be as simple as you expected in the near future. Suffice to say it's not very easy to work with right now. That said, I do have a series of fixes to get it working (sort-of).

    Here's what I did:

    -Create a new script (I called it InputFieldHandler for now). This script will replace the EventHandler on the GvrKeyboardCanvas Unity object. More on it later.
    -Add the static keyword to KeyboardDelegateExample for the KeyboardText field (eg ```public static Text KeyboardText;```). This allows each InputFieldHandler to assign its associated input field's Text object to the singleton when it's "in focus".
    -Add a method in GvrKeyboard (I called it SetText, and added it below ClearText). This method allows resetting the Keyboard's "current" text whenever a new "focus" input field is assigned. Otherwise, it will keep the same buffer, and selecting a second input field will initially populate it with the string saved in the first.

    -Write the InputFieldHandler class as I did below. In the one-field demo, the Keyboard begins activated, so I added the "EditOnStart" boolean to set which field I want to be editing by default. The script should be otherwise fairly straightforward; it finds the Text object in its children, and passes that to the KeyboardDelegateExample's static KeyboardText field. It also sets the initial string in GvrKeyboard to the last value of the input field.

    EDIT: Sorry the tabbing is nonexistent in the code snippets below. Looks like the unity forum is removing excess whitespace :(

    ___GvrKeyboard.cs___

    ...

    public void SetText(string NewText) {
    if (keyboardProvider != null) {
    keyboardProvider.EditorText = NewText;
    }
    }

    ...

    ___InputFieldHandler.cs___

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.EventSystems;
    using UnityEngine.UI

    public class InputFieldHandler : MonoBehaviour, IPointerClickHandler {
    public GvrKeyboard Keyboard;
    public bool EditOnStart = true;
    private Text TextField = null;

    void Awake() {
    GetLocalTextField();
    if (EditOnStart) {
    GoogleVR.KeyboardDemo.KeyboardDelegateExample.KeyboardText = TextField;
    }
    }

    void Start() {
    if (Keyboard == null) {
    Debug.Log("No Keyboard found on InputFieldHandler; searching for an existing one...");
    GvrKeyboard SearchedKeyboard = FindObjectOfType<GvrKeyboard>();
    if (SearchedKeyboard == null) {
    Debug.Log("No Keyboard found in scene; creating a new one...");
    GameObject KeyboardGameObject = new GameObject();
    Keyboard = KeyboardGameObject.AddComponent<GvrKeyboard>();
    } else {
    Keyboard = SearchedKeyboard;
    }
    }
    }

    public void OnPointerClick(PointerEventData pointerEventData) {GoogleVR.KeyboardDemo.KeyboardDelegateExample.KeyboardText.gameObject.name);
    if (TextField == null) {
    GetLocalTextField();
    }
    GoogleVR.KeyboardDemo.KeyboardDelegateExample.KeyboardText = TextField;
    Keyboard.SetText(TextField.text);
    Keyboard.Show();
    }

    void GetLocalTextField() {
    TextField = GetComponent<Text>();
    if (!TextField) {
    TextField = GetComponentInChildren<Text>();
    if (!TextField) {
    Debug.LogError("No Text object in InputFieldHandler's GameObject or its children; disabling...");
    }
    }
    }
    }

    ___

    Some caveats:

    The Keyboard will still always appear at the origin (straight ahead when the headset is recentered), regardless of which field is being edited. Also, the reticle disappears when being used with the Keyboard; this is a known issue we're looking into. I'll let you know when I've gotten a fix for the origin problem.

    I'll write the official support for multi-input Keyboards shortly, but it will be a couple months before it makes the release cut. Hopefully this answers most of your questions! Let me know if this fix works for you! :)

    Best,
    Derek
     
  4. duncangroberts

    duncangroberts

    Joined:
    Jul 22, 2015
    Posts:
    69
    Hi @derekrocco

    Thanks so much for getting back to me! I will try these fixes and let you know how it goes. Look forward to the sdk updates but I understand that it might be a little while.

    Once again thank you so much!

    Duncan