Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • Universal Windows Platform

  • Android
    NOTE: As a result of using the Windows BLE stack, Unity projects built with the VictoR SDK can only be run on the target platform during development. Running the application within the editor is currently not supported.

Introduction

To enable development for the VictoR device in the Unity engine, a Unity package is available which contains the relevant Android and Windows libraries used to communicate with a VictoR device, along with example C# scripts and Unity gameobjects and example scene that demonstrate one of many ways users could incorporate the VictoR SDK into their Unity project. The following will walk users through importing the Unity package into their project and give a general overview of the provided scripts, gameobjects, and example scene.

...

  1. A plugins folder containing the necessary libraries to build either a UWP application or an Android application

  2. Prefabs for a basic UI to allow for…

    1. Scanning for VictoR devices over USB or BLE

    2. Connecting to scanned devices

    3. Reading the Device Configuration and Device Information service on the device

    4. Writing to the Device Configuration service

    5. Disconnecting from connected VictoR devices

  3. Scripts utilizing the Windows and Android VictoR SDK, along with prefabs using said scripts

  4. An example scene bringing the above items together for a buildable UWP or Android application

...

When building a project for Android, the VictorSDK for Android requires an additional layer of bindings in order to interface with the SDK in C#. The VictorAndroidBLEDeviceManager VictorAndroidDeviceManager script under the Scripts folder provides these bindings and is what users should leverage when making calls to the Android SDK. The example code below simply gives users a look into how these bindings are done. The core of this layer resides in Unity’s AndroidJNIModule in the UnityEngine library. This allows for using android java objects and making calls on said objects. The following demonstrates how these calls are made as they relate to the VictoR SDK:

...

In order to scan for devices using the Android SDK from within a Unity project, users must first create an AndroidJavaObject representing the Java SDK’s VictorBleDeviceManager. In the example script, this is done inside the constructor. Once the device manager object has been created, the actual scan method is able to use the AndroidJavaObject to call the “scanForDevices” method. As this is a CompletableFuture on the Java side, this call is made inside of a Task on the C# side. An important item to note is that in order to properly call this function, users must first attach the current thread to a Java VM. Remember that the Unity package contains a VictorAndroidBLEDeviceManager VictorAndroidDeviceManager script that has performed this binding already for the user.

Code Block
languagec#
public class VictorAndroidBleDeviceManagerVictorAndroidDeviceManager : IVictorDeviceManager
{
    AndroidJavaClass m_AJCUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    AndroidJavaObject m_AJOActivity;
    AndroidJavaObject m_AJODeviceManager;
    
    public VictorAndroidBleDeviceManagerVictorAndroidDeviceManager(bool useUSB)
    {
        m_AJCUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        m_AJOActivity = m_AJCUnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        m_AJODeviceManagerstring classNamePrefix = new AndroidJavaObject("com.fn.victorcommunications.VictorBleDeviceManager", m_AJOActivity);;
      }  string className;
      public async Task<HashSet<VictorDeviceInfo>>if ScanForDevices(useUSB)
        {
         AndroidJavaObject ajoScannedDevices = await className = "VictorUsbDeviceManager";
        }
        else
        {
            className = "VictorBleDeviceManager";
        }
        m_AJODeviceManager = new AndroidJavaObject(classNamePrefix + className, m_AJOActivity);
        m_useUSB = useUSB;
    }
    
    public async Task<HashSet<VictorDeviceInfo>> ScanForDevices()
    {
        AndroidJavaObject ajoScannedDevices = await Task<AndroidJavaObject>.Run(() =>
        {
            AndroidJNI.AttachCurrentThread();
            AndroidJavaObject ajo = m_AJODeviceManager.Call<AndroidJavaObject>("scanForDevices");
            return ajo.Call<AndroidJavaObject>("get");
        });
    
        return ToHashSet(ajoScannedDevices);
    }
}

...

Connecting to a device follows a similar pattern as scanning for devices. A binding to the Android SDK must first be defined to call the connect method. This is already defined in the VictorAndroidBLEDeviceManager VictorAndroidDeviceManager script

Code Block
languagec#
public async Task<bool> Connect(string deviceAddress)
{
    return await Task<bool>.Run(() =>
    {
        AndroidJNI.AttachCurrentThread();
        AndroidJavaObject ajo = m_AJODeviceManager.Call<AndroidJavaObject>("connect", deviceAddress);
        return ajo.Call<AndroidJavaObject>("get").Call<bool>("booleanValue");
    });
}

...

Callbacks when using the Android SDK requires not only a binding to the underlying Java call, but also defining the Callback abstract class in the Android SDK. Once again, the VictorAndroidBLEDeviceManager VictorAndroidDeviceManager provides an example implementation for how both of these are handled. First, the VictorDeviceCallback in the Android SDK is defined on the C# side. In the provided example, the VictorEventHandler and VictorEventHandlerMap in the Windows SDK is leveraged to manage passed in events.

...

With both items defined, users can create their own Event to pass to the VictorAndroidBLEDeviceManager VictorAndroidDeviceManager to be notified of attribute changes (for attributes that have the Notify flag enabled), connection state events, and device found events. It is important to remember that these callbacks will occur in a separate thread and should be especially noted if working on Unity Gameobjects that rely on these callbacks for modifications, as many operations on Unity Gameobjects can only be done on the main thread.

...

The UI prefab consists of a collection of controls that allow for scanning for devices, connecting/disconnecting to/from the device, and reading/writing to the device. Additionally, a Log prefab is used by the VictorUIManager script to print out a number of informational, warning, and error logs in the scroll view of the UI. Any reads made on the device will be printed out in the scroll view, as well as notifications of the state of a scan, connect, or disconnect call.

...

state of a scan, connect, or disconnect call. One item of note is the USB toggle. If users wish to scan/connect to devices over USB, please ensure that the USB toggle has been turned on.

...

Building The Unity Project

...

NOTE: When attempting to build an app that intends to communicate with the device over USB, it is important that permissions for accessing serial devices has been added to the .appxmanifest for the resulting UWP build. Subsequent builds in the same folder will not overwrite this entry, however it is important to keep this in mind for any fresh builds. The best workflow for UWP builds is to perform an initial build and modify the .appxmanifest in the project’s build folder before running the application for the first time.

...

Android

Latest Android SDK Supported: 32

...