Hololens V1 – Falling star

Each airtap do: create object, add rigidbody (gravity) to the object, and finally delete the object.

Somehow, the GazeManager.Instance.HitObject hit the child obj that contain a mesh/box collider. Therefore, we need to check tag name on its parent.
Note that, Mesh Collider needs to check on Convex, otherwise when add a rigidbody, it will fall down eternity without colliding with the room floor.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HoloToolkit.Unity.InputModule;

public class SpawnDropObject : MonoBehaviour, IInputClickHandler
{
    //[SerializeField] private PanelDebug panelDebug;
    public GameObject iprefab;
    private int ObjCount;
    private List<GameObject> ObjList;
    void Start()
    {
        InputManager.Instance.PushFallbackInputHandler(gameObject);
        ObjList = new List<GameObject>();
    }

    public void OnInputClicked(InputClickedEventData eventData)
    {
        if (!GazeManager.Instance.HitObject) //airtap at nothing = create new obj
        {
            Debug.Log("!GazeManager.Instance.HitObject");
            Vector3 obj_position = Camera.main.transform.position + Camera.main.transform.forward;
            CreateNewObject(obj_position);
        }
        else
        {
            //panelDebug.ShowMessage(GazeManager.Instance.HitObject.name);
            Debug.Log("\n"+GazeManager.Instance.HitObject.name + " " + GazeManager.Instance.HitObject.tag + " " + GazeManager.Instance.HitObject.transform.parent.tag);

            // Airtap at floating object. Then, add gravity to the obj = drop it down
            if (GazeManager.Instance.HitObject.tag == "Floating") 
            {
                Debug.Log("HitObject.tag == Floating");
                GazeManager.Instance.HitObject.AddComponent<Rigidbody>();  
                GazeManager.Instance.HitObject.tag = "Falldown";
            }
            else if (GazeManager.Instance.HitObject.transform.parent.tag == "Floating")
            {
                Debug.Log("HitObject.parent.tag == Floating");
                GazeManager.Instance.HitObject.AddComponent<Rigidbody>(); 
                GazeManager.Instance.HitObject.transform.parent.tag = "Falldown";
            }

            // Airtap at object on floor. Then, remove it.
            else if (GazeManager.Instance.HitObject.tag == "Falldown") 
            {
                Debug.Log("HitObject.tag == Falldown");
                ObjList.Remove(GazeManager.Instance.HitObject);
                Destroy(GazeManager.Instance.HitObject);
            }
            else if (GazeManager.Instance.HitObject.transform.parent.tag == "Falldown") 
            {
                Debug.Log("HitObject.parent.tag == Falldown");
                ObjList.Remove(GazeManager.Instance.HitObject.transform.parent.gameObject);
                Destroy(GazeManager.Instance.HitObject.transform.parent.gameObject);
            }

            // Airtap at something (room mesh). Then, create new obj.
            else 
            {
                Debug.Log("HitObject.tag == ??");
                Debug.Log("HitObject" + GazeManager.Instance.HitObject.transform.position.ToString());
                Debug.Log("HitPosition" + GazeManager.Instance.HitObject.ToString());
                //CreateNewObject(GazeManager.Instance.HitObject.transform.position); // this position is not the world coordinate
                CreateNewObject(GazeManager.Instance.HitPosition);
            }
        }

        
        string objlistname = "\nObj in List";
        foreach (GameObject obj in ObjList)
        {
            string text = "\n"+obj.name + " " + obj.tag;
            objlistname += text;         
        }
        Debug.Log(objlistname);
    }
    private void CreateNewObject(Vector3 position)
    {
        Debug.Log("CreateNewObject at"+ position.ToString());
        GameObject newobj = Instantiate(iprefab, position, Quaternion.identity);
        newobj.tag = "Floating";

        ObjList.Add(newobj);
    }
}

Hololens V1 – Save text file

This application will record Hololens transformation overtime and save to any text file (my code is csv file) inside the device.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Linq;

#if WINDOWS_UWP
using Windows.Storage;
using Windows.System;
using System.Threading.Tasks;
using Windows.Storage.Streams;
#endif

// saved folder : User Folders \ LocalAppData \ Appname \ LocalState \
public class WriteCSVFile : MonoBehaviour
{
#if WINDOWS_UWP
    Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
    Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
#endif

    private string timeStamp;
    private string fileName;
    private string saveInformation;
 
    public void WriteTextToFile(string text)
    {
        timeStamp = System.DateTime.Now.ToString().Replace("/", "_").Replace(":", "-").Replace(" ", "_");
        fileName = "transform-" + timeStamp + ".csv";
        saveInformation = text;
        
#if WINDOWS_UWP
        WriteData();
#endif
    }

#if WINDOWS_UWP
    async void WriteData()
    {
        StorageFile saveFile = await localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
        string fileheader = "id,pos_x,pos_y,pos_z,rot_x,rot_y,rot_z" + "\r\n";
        await FileIO.AppendTextAsync(saveFile, fileheader + saveInformation);
    }
#endif

}

In another script file, we record transform data and call WriteTextToFile() to write a text.

[SerializeField] private WriteCSVFile writeCSVFile;
private StringBuilder csv;

private void PreparePositiontosave()
{
    csv.Remove(0, csv.Length);
    for (int i = 0; i < positions.Count; i++)
    {
        var newLine = string.Format("{0},{1},{2},{3},{4},{5},{6}", i,
                        positions[i].x, positions[i].y, positions[i].z,
                        rotations[i].x, rotations[i].y, rotations[i].z);
        csv.AppendLine(newLine);
        writeCSVFile.WriteTextToFile(csv.ToString());
    }
} 

Here is where the file was saved and its content.

Hololens V1 – UI Panel for showing message

I wanted something to show a program state message while I’m wearing Hololens. That is to add UI > Panel and UI > Text inside the Panel. You will get The Canvas gameobject as a parent object that contain Panel nested inside. Set the Canvas render mode to “World Space”

Then we need to attach Tagalong and Billboard scripts (from HoloToolkit 2017.4.3.0) to the Canvas.

Tagalong will move the Canvas to always be inside the Hololens view. The default setting it will move the Canvas to the border of the Hololens view, not exactly at the view center.

Billboard will change the Canvas orientation to face the Hololens Camera. Set Pivot axis to “free” so that the Canvas can rotate along all x,y,z axes.

While recording a video, the tagalong function did not work properly.
It let the Canvas to not come inside Hololens view when moved.
Normally, the Canvas will be around inner border of the view.