Aphaena

Script UI Hololens pointer change color

UI and Hololens



So with working on the Voxel editor, I need a couple of UI elements. So I have had to look at using a canvas in World Space. The elements I need are 1) a Keyboard, and 2) a Color Picker. The Color picker is so that I can change the RGB values of all the voxels which can be placed. The Keyboard for being able to enter a filename and also to be able to enter RGB values directly.

I found a good or simple to use Color Picker for the Canvas, added it and ran the app. Things start well, air tapping, will allow the color to be selected and change the RGB Values. But there are issues. The main one, being when moving your head and where you are looking at, you cannot accurately see the location on the Canvas.

So first thing was to create a simple pointer, add it to the canvas, then create a small script that would detected if the current gaze position was on the canvas object I wanted to check.

Getting the cursor object to follow is not too bad.

// Update is called once per frame
void Update ()
{
    if (cursor != null)
    {
        bool ok = false;
        var pointer = new PointerEventData(EventSystem.current);

        // convert to a 2D position
        pointer.position = new Vector2 (Screen.width / 2, Screen.height / 2);

        var raycastResults = new List<RaycastResult>();

        EventSystem.current.RaycastAll(pointer, raycastResults);

        cursor.color = Color.white;

        if (raycastResults.Count > 0)
        {
            foreach (RaycastResult result in raycastResults)
            {
                // is the colliding object part of the main object
                if (result.gameObject.transform.IsChildOf (this.gameObject.transform) )
                {
                    Vector3 p = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width / 2, Screen.height / 2, result.distance));

                    cursor.color = Color.red;
                    cursor.transform.position = p;
                    ok = true;
                    cursor.gameObject.SetActive(true);
                }
            }
        }

        if (!ok)
        {
            cursor.gameObject.SetActive(false);
        }
    }
}

Here I’m basically using the EventSystem to cast a ray on all UI elements. Then depending on if they are part of the parent object, moving the cursor to the collect position.

This all works well. The cursor follows nicely and I can tell accurately where the cursor is.

The next I will be creating a simple keyboard using roughly the same follow code to all the user to be able to enter text.