first commit
This commit is contained in:
commit
aa44d3ad70
1585 changed files with 277994 additions and 0 deletions
8
Assets/Bhaptics/SDK2/Scripts/AutoGenerated.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/AutoGenerated.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9359fedb808df2941a6930749a3f9dcc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
64
Assets/Bhaptics/SDK2/Scripts/AutoGenerated/BhapticsEvent.cs
Normal file
64
Assets/Bhaptics/SDK2/Scripts/AutoGenerated/BhapticsEvent.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
public class BhapticsEvent
|
||||
{
|
||||
|
||||
public const string WAIST_LEFT = "waist_left";
|
||||
|
||||
public const string DRINKPOTION = "drinkpotion";
|
||||
|
||||
public const string SHOULDER_RIGHT = "shoulder_right";
|
||||
|
||||
public const string FLAMEBURNING = "flameburning";
|
||||
|
||||
public const string EXPLOSION = "explosion";
|
||||
|
||||
public const string FOREARM_RIGHT = "forearm_right";
|
||||
|
||||
public const string HEALING = "healing";
|
||||
|
||||
public const string CHEST_RIGHT = "chest_right";
|
||||
|
||||
public const string STEP_LINK = "step_link";
|
||||
|
||||
public const string FOREARM_LEFT = "forearm_left";
|
||||
|
||||
public const string HEARTBEAT_FAST = "heartbeat_fast";
|
||||
|
||||
public const string HEAD_RIGHT = "head_right";
|
||||
|
||||
public const string GAME_START = "game_start";
|
||||
|
||||
public const string SHOULDER_LEFT = "shoulder_left";
|
||||
|
||||
public const string HEARTBEAT = "heartbeat";
|
||||
|
||||
public const string HEAD_ALL = "head_all";
|
||||
|
||||
public const string HAPTIC_STEP_LINK_PERFECT = "haptic_step_link_perfect";
|
||||
|
||||
public const string HEAD_LEFT = "head_left";
|
||||
|
||||
public const string ELECTRICSHOCK = "electricshock";
|
||||
|
||||
public const string EATFOOD = "eatfood";
|
||||
|
||||
public const string WAIST_RIGHT = "waist_right";
|
||||
|
||||
public const string CHEST_LEFT = "chest_left";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b056a440d2364c140bc4ab0a8bd2cc6c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Bhaptics/SDK2/Scripts/Core.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/Core.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a57afe0846bbb0a48ba2f8aae6134ed3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
13
Assets/Bhaptics/SDK2/Scripts/Core/Bhaptics.SDK2.asmdef
Normal file
13
Assets/Bhaptics/SDK2/Scripts/Core/Bhaptics.SDK2.asmdef
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Bhaptics.SDK2",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 464dd5f1479658c42bf2844d11534e1e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
314
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsHelpers.cs
Normal file
314
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsHelpers.cs
Normal file
|
@ -0,0 +1,314 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
[Serializable]
|
||||
internal class Device
|
||||
{
|
||||
public bool paired;
|
||||
public string deviceName;
|
||||
public int position;
|
||||
public bool connected;
|
||||
public string address;
|
||||
public int battery;
|
||||
public bool audioJackIn;
|
||||
}
|
||||
|
||||
public enum PositionType
|
||||
{
|
||||
Vest, ForearmL, ForearmR, Head, HandL, HandR, FootL, FootR, GloveL, GloveR
|
||||
}
|
||||
public enum GloveShapeValue
|
||||
{
|
||||
Constant = 0,
|
||||
Decreasing = 1,
|
||||
Increasing = 2
|
||||
}
|
||||
public enum GlovePlayTime
|
||||
{
|
||||
None = 0,
|
||||
FiveMS = 1,
|
||||
TenMS = 2,
|
||||
TwentyMS = 4,
|
||||
ThirtyMS = 6,
|
||||
FortyMS = 8
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MappingMetaData
|
||||
{
|
||||
public int durationMillis;
|
||||
public string key;
|
||||
public string description;
|
||||
public bool isAudio;
|
||||
public long updateTime;
|
||||
public string[] positions;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal class MappingMessage
|
||||
{
|
||||
public bool status;
|
||||
public List<MappingMetaData> message;
|
||||
|
||||
public static MappingMessage CreateFromJSON(string jsonString)
|
||||
{
|
||||
return JsonUtility.FromJson<MappingMessage>(jsonString);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DeployMessage
|
||||
{
|
||||
public string name;
|
||||
public int version;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DeployHttpMessage
|
||||
{
|
||||
public bool status;
|
||||
public DeployMessage message;
|
||||
|
||||
public static DeployHttpMessage CreateFromJSON(string jsonString)
|
||||
{
|
||||
return JsonUtility.FromJson<DeployHttpMessage>(jsonString);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class HapticDevice
|
||||
{
|
||||
public bool IsPaired;
|
||||
public bool IsConnected;
|
||||
public string DeviceName;
|
||||
public PositionType Position;
|
||||
public string Address;
|
||||
public PositionType[] Candidates;
|
||||
public bool IsAudioJack;
|
||||
public int Battery;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class DeviceListMessage
|
||||
{
|
||||
public Device[] devices;
|
||||
}
|
||||
|
||||
public class BhapticsHelpers
|
||||
{
|
||||
[Serializable]
|
||||
private class AndroidDeviceMessage
|
||||
{
|
||||
public Device[] items;
|
||||
}
|
||||
|
||||
private static readonly HapticDevice[] HapticDevices =
|
||||
{
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
new HapticDevice(),
|
||||
};
|
||||
|
||||
public static float Angle(Vector3 fwd, Vector3 targetDir)
|
||||
{
|
||||
var fwd2d = new Vector3(fwd.x, 0, fwd.z);
|
||||
var targetDir2d = new Vector3(targetDir.x, 0, targetDir.z);
|
||||
|
||||
float angle = Vector3.Angle(fwd2d, targetDir2d);
|
||||
|
||||
if (AngleDir(fwd, targetDir, Vector3.up) == -1)
|
||||
{
|
||||
angle = 360.0f - angle;
|
||||
if (angle > 359.9999f)
|
||||
angle -= 360.0f;
|
||||
return angle;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
private static int AngleDir(Vector3 fwd, Vector3 targetDir, Vector3 up)
|
||||
{
|
||||
Vector3 perp = Vector3.Cross(fwd, targetDir);
|
||||
float dir = Vector3.Dot(perp, up);
|
||||
|
||||
if (dir > 0.0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dir < 0.0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static string ErrorCodeToMessage(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 0:
|
||||
return "BHAPTICS_SETTINGS_SUCCESS";
|
||||
case 1:
|
||||
return "NETWORK_ERROR";
|
||||
case 2:
|
||||
return "API_KEY_INVALID";
|
||||
case 3:
|
||||
return "APP_ID_INVALID";
|
||||
case 4:
|
||||
return "APPLICATION_NOT_DEPLOY";
|
||||
case 100:
|
||||
return "NOT_CHANGED";
|
||||
case 999:
|
||||
return "UNKNOWN_ISSUES";
|
||||
}
|
||||
|
||||
return "UNKNOWN CODE";
|
||||
}
|
||||
|
||||
public static List<HapticDevice> ConvertToBhapticsDevices(string deviceJson)
|
||||
{
|
||||
var res = new List<HapticDevice>();
|
||||
|
||||
var devices = JsonUtility.FromJson<AndroidDeviceMessage>(deviceJson);
|
||||
for (var i = 0; i < devices.items.Length; i++)
|
||||
{
|
||||
var hDevice = HapticDevices[i];
|
||||
var d = devices.items[i];
|
||||
if (i >= 15)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
hDevice.IsPaired = d.paired;
|
||||
hDevice.IsConnected = d.connected;
|
||||
hDevice.Address = d.address;
|
||||
hDevice.Position = ToDeviceType(d.position);
|
||||
hDevice.DeviceName = d.deviceName;
|
||||
hDevice.Candidates = ToCandidates(d.position);
|
||||
hDevice.Battery = d.battery;
|
||||
hDevice.IsAudioJack = d.audioJackIn;
|
||||
res.Add(hDevice);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
internal static List<HapticDevice> Convert(Device[] deviceJson)
|
||||
{
|
||||
var res = new List<HapticDevice>();
|
||||
|
||||
for (var i = 0; i < deviceJson.Length; i++)
|
||||
{
|
||||
res.Add(Convert(deviceJson[i]));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static HapticDevice Convert(Device d)
|
||||
{
|
||||
var isConnected = d.connected;
|
||||
|
||||
return new HapticDevice()
|
||||
{
|
||||
IsPaired = d.paired,
|
||||
IsConnected = isConnected,
|
||||
Address = d.address,
|
||||
Position = ToDeviceType(d.position),
|
||||
DeviceName = d.deviceName,
|
||||
Candidates = ToCandidates(d.position),
|
||||
Battery = d.battery,
|
||||
IsAudioJack = d.audioJackIn,
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly PositionType[] HeadCandidates = { PositionType.Head };
|
||||
private static readonly PositionType[] VestCandidates = { PositionType.Vest };
|
||||
private static readonly PositionType[] ArmCandidates = { PositionType.ForearmL, PositionType.ForearmR };
|
||||
private static readonly PositionType[] HandCandidates = { PositionType.HandL, PositionType.HandR };
|
||||
private static readonly PositionType[] FootCandidates = { PositionType.FootR, PositionType.FootL };
|
||||
private static readonly PositionType[] GloveLCandidates = { PositionType.GloveL };
|
||||
private static readonly PositionType[] GloveRCandidates = { PositionType.GloveR };
|
||||
private static readonly PositionType[] EmptyCandidates = { };
|
||||
|
||||
private static PositionType[] ToCandidates(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 3:
|
||||
return HeadCandidates;
|
||||
case 0:
|
||||
return VestCandidates;
|
||||
case 1:
|
||||
return ArmCandidates;
|
||||
case 2:
|
||||
return ArmCandidates;
|
||||
case 4:
|
||||
return HandCandidates;
|
||||
case 5:
|
||||
return HandCandidates;
|
||||
case 6:
|
||||
return FootCandidates;
|
||||
case 7:
|
||||
return FootCandidates;
|
||||
case 8:
|
||||
return GloveLCandidates;
|
||||
case 9:
|
||||
return GloveRCandidates;
|
||||
|
||||
}
|
||||
|
||||
return EmptyCandidates;
|
||||
}
|
||||
|
||||
private static PositionType ToDeviceType(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
return PositionType.Vest;
|
||||
|
||||
case 1:
|
||||
return PositionType.ForearmL;
|
||||
case 2:
|
||||
return PositionType.ForearmR;
|
||||
case 3:
|
||||
return PositionType.Head;
|
||||
case 4:
|
||||
return PositionType.HandL;
|
||||
case 5:
|
||||
return PositionType.HandR;
|
||||
case 6:
|
||||
return PositionType.FootL;
|
||||
case 7:
|
||||
return PositionType.FootR;
|
||||
case 8:
|
||||
return PositionType.GloveL;
|
||||
case 9:
|
||||
return PositionType.GloveR;
|
||||
|
||||
}
|
||||
|
||||
return PositionType.Vest;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsHelpers.cs.meta
Normal file
11
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsHelpers.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5770e2ca1fe6669488682dfa2cbc8936
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
125
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsSDK2.cs
Normal file
125
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsSDK2.cs
Normal file
|
@ -0,0 +1,125 @@
|
|||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
public class BhapticsSDK2 : MonoBehaviour
|
||||
{
|
||||
private static BhapticsSDK2 instance;
|
||||
|
||||
[Header("Only for PC")]
|
||||
[Tooltip("If bHaptics Player(PC) is not turned on when this program starts, it automatically runs bHaptics Player.")]
|
||||
[SerializeField] private bool autoRunBhapticsPlayer = false;
|
||||
private bool autoRequestBluetoothPermission = true;
|
||||
|
||||
private BhapticsSettings bhapticsSettings;
|
||||
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (instance != null)
|
||||
{
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
instance = this;
|
||||
DontDestroyOnLoad(this);
|
||||
|
||||
bhapticsSettings = BhapticsSettings.Instance;
|
||||
|
||||
var hapticDevices = BhapticsLibrary.GetDevices();
|
||||
BhapticsLogManager.LogFormat("[bHaptics] devices {0}", hapticDevices.Count);
|
||||
|
||||
if (string.IsNullOrEmpty(bhapticsSettings.AppId))
|
||||
{
|
||||
Debug.LogError("[bHaptics] Please set API_ID.");
|
||||
return;
|
||||
}
|
||||
|
||||
BhapticsLogManager.LogFormat("[bHaptics] {0} {1}", bhapticsSettings.AppId, bhapticsSettings.ApiKey);
|
||||
BhapticsLibrary.Initialize(bhapticsSettings.AppId, bhapticsSettings.ApiKey, bhapticsSettings.DefaultDeploy, autoRequestBluetoothPermission);
|
||||
|
||||
var playerSetup = BhapticsLibrary.IsBhapticsAvailable(autoRunBhapticsPlayer);
|
||||
BhapticsLogManager.LogFormat("[bHaptics] player IsBhapticsAvailable {0}", playerSetup);
|
||||
BhapticsLogManager.LogFormat("[bHaptics] Initialized. ");
|
||||
}
|
||||
|
||||
private void OnApplicationFocus(bool pauseStatus)
|
||||
{
|
||||
if (pauseStatus)
|
||||
{
|
||||
BhapticsLibrary.OnApplicationFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
BhapticsLibrary.OnApplicationPause();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (instance.GetInstanceID() == this.GetInstanceID())
|
||||
{
|
||||
BhapticsLibrary.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
BhapticsLibrary.OnApplicationQuit();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static string GetBhapticsFolderParentPath(bool localToAssetsFolder = false)
|
||||
{
|
||||
BhapticsSettings asset = ScriptableObject.CreateInstance<BhapticsSettings>();
|
||||
UnityEditor.MonoScript scriptAsset = UnityEditor.MonoScript.FromScriptableObject(asset);
|
||||
|
||||
string scriptPath = UnityEditor.AssetDatabase.GetAssetPath(scriptAsset);
|
||||
|
||||
FileInfo settingsScriptFileInfo = new FileInfo(scriptPath);
|
||||
|
||||
string fullPath = settingsScriptFileInfo.Directory.Parent.Parent.FullName;
|
||||
|
||||
if (localToAssetsFolder == false)
|
||||
{
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
DirectoryInfo assetsDirectoryInfo = new DirectoryInfo(Application.dataPath);
|
||||
string localPath = fullPath.Substring(assetsDirectoryInfo.Parent.FullName.Length + 1);
|
||||
return localPath;
|
||||
}
|
||||
|
||||
public static string GetResourcePath(bool localToAssetsFolder = false)
|
||||
{
|
||||
string path = Path.Combine(GetBhapticsFolderParentPath(localToAssetsFolder), "Resources");
|
||||
|
||||
if (Directory.Exists(path) == false)
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static string GetScriptPath(bool localToAssetsFolder = false)
|
||||
{
|
||||
string path = Path.Combine(GetBhapticsFolderParentPath(localToAssetsFolder), "Scripts");
|
||||
|
||||
if (Directory.Exists(path) == false)
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
11
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsSDK2.cs.meta
Normal file
11
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsSDK2.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 23aca228b96921048bd497757f5bca2a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
163
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsSettings.cs
Normal file
163
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsSettings.cs
Normal file
|
@ -0,0 +1,163 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
[Serializable]
|
||||
public class BhapticsConfig
|
||||
{
|
||||
public string appId = "";
|
||||
public string apiKey = "";
|
||||
}
|
||||
|
||||
public class BhapticsSettings : ScriptableObject
|
||||
{
|
||||
private static BhapticsSettings instance;
|
||||
|
||||
[SerializeField] private string appName = "";
|
||||
[SerializeField] private string appId = "";
|
||||
[SerializeField] private string apiKey = "";
|
||||
[SerializeField] private int lastDeployVersion = -1;
|
||||
[SerializeField] private MappingMetaData[] eventData;
|
||||
[HideInInspector, SerializeField] private string defaultDeploy = "";
|
||||
|
||||
|
||||
#region Properties
|
||||
public static BhapticsSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
LoadInstance();
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public string AppName
|
||||
{
|
||||
get
|
||||
{
|
||||
return appName;
|
||||
}
|
||||
set
|
||||
{
|
||||
appName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string AppId
|
||||
{
|
||||
get
|
||||
{
|
||||
return appId;
|
||||
}
|
||||
set
|
||||
{
|
||||
appId = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string ApiKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return apiKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
apiKey = value;
|
||||
}
|
||||
}
|
||||
|
||||
public MappingMetaData[] EventData
|
||||
{
|
||||
get
|
||||
{
|
||||
return eventData;
|
||||
}
|
||||
set
|
||||
{
|
||||
eventData = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int LastDeployVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return lastDeployVersion;
|
||||
}
|
||||
set
|
||||
{
|
||||
lastDeployVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string DefaultDeploy
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultDeploy;
|
||||
}
|
||||
set
|
||||
{
|
||||
defaultDeploy = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void VerifyScriptableObject()
|
||||
{
|
||||
LoadInstance();
|
||||
}
|
||||
|
||||
public static void ResetInstance()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BhapticsLogManager.LogFormat("[bHaptics] Reset App Setup: {0}", instance.AppName);
|
||||
instance.appName = "";
|
||||
instance.appId = "";
|
||||
instance.apiKey = "";
|
||||
instance.eventData = null;
|
||||
instance.lastDeployVersion = -1;
|
||||
instance.defaultDeploy = "";
|
||||
#if UNITY_EDITOR
|
||||
var localFolderPath = BhapticsSDK2.GetResourcePath(true);
|
||||
var assetPath = System.IO.Path.Combine(localFolderPath, "BhapticsSettings.asset");
|
||||
UnityEditor.EditorUtility.SetDirty(instance);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void LoadInstance()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
BhapticsLogManager.LogFormat("Load BhapticsSettings.asset");
|
||||
instance = Resources.Load<BhapticsSettings>("BhapticsSettings");
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
instance = CreateInstance<BhapticsSettings>();
|
||||
#if UNITY_EDITOR
|
||||
var localFolderPath = BhapticsSDK2.GetResourcePath(true);
|
||||
var assetPath = System.IO.Path.Combine(localFolderPath, "BhapticsSettings.asset");
|
||||
|
||||
UnityEditor.AssetDatabase.CreateAsset(instance, assetPath);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsSettings.cs.meta
Normal file
11
Assets/Bhaptics/SDK2/Scripts/Core/BhapticsSettings.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2b3b9d9689fae93418e33472f9eccaa7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Bhaptics/SDK2/Scripts/Core/Plugins.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/Core/Plugins.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ff8d7d6352ce564880dd5f34265ba94
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Bhaptics/SDK2/Scripts/Core/Plugins/Android.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/Core/Plugins/Android.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 09b951e214c53814ba1ab357433fa414
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.unity3d.player"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
|
||||
<!--If your Android Target API Level is API Level 30 or above,
|
||||
you need to add the following <queries> syntax to your AndroidManifest.-->
|
||||
<queries>
|
||||
<package android:name="com.bhaptics.player"/>
|
||||
</queries>
|
||||
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true" >
|
||||
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:screenOrientation="landscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="com.oculus.intent.category.VR" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||
</activity>
|
||||
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
|
||||
</application>
|
||||
|
||||
<!--
|
||||
Important Notes
|
||||
1. If your project contains a custom AndroidManifest.xml file, add permissions
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" android:minSdkVersion="31" />
|
||||
|
||||
2. Otherwise, copy this file to this location in your project:
|
||||
Assets/Plugins/Android/AndroidManifest.xml.
|
||||
-->
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" android:minSdkVersion="31" />
|
||||
</manifest>
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a83632b59de13ea4baf3d06d31b2bf16
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,32 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ef161821b3ddad24abba5b8882c3e557
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,32 @@
|
|||
fileFormatVersion: 2
|
||||
guid: abe726f1745d2314e9b7dea2b3dbd909
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,32 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f5e3094bd6a10bd45867b4cf61e15907
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,32 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 66466aff6b8a126419a08f2737000387
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,32 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8caffa37d6e0be84486b14da52771369
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
516
Assets/Bhaptics/SDK2/Scripts/Core/Plugins/AndroidHaptic.cs
Normal file
516
Assets/Bhaptics/SDK2/Scripts/Core/Plugins/AndroidHaptic.cs
Normal file
|
@ -0,0 +1,516 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
public class AndroidHaptic
|
||||
{
|
||||
protected static AndroidJavaObject androidJavaObject;
|
||||
|
||||
private readonly Dictionary<string, int> eventDictionary = new Dictionary<string, int>();
|
||||
|
||||
private static readonly object[] GetEventIdParams = new object[1];
|
||||
private static readonly object[] PlayGloveParams = new object[5];
|
||||
private static readonly jvalue[] PlayEventParams = new jvalue[6];
|
||||
private static readonly jvalue[] PlayLoopParams = new jvalue[8];
|
||||
private static readonly jvalue[] EmptyParams = new jvalue[0];
|
||||
private static readonly object[] PlayMotorsParams = new object[3];
|
||||
private static readonly jvalue[] IsPlayingParams = new jvalue[1];
|
||||
private static readonly jvalue[] IsPlayingByEventIdParams = new jvalue[1];
|
||||
private static readonly jvalue[] StopByRequestIdParams = new jvalue[1];
|
||||
private static readonly jvalue[] StopByEventIdParams = new jvalue[1];
|
||||
private static readonly object[] PingParams = new object[1];
|
||||
|
||||
|
||||
private List<HapticDevice> deviceList;
|
||||
|
||||
private readonly IntPtr bhapticsWrapperObjectPtr;
|
||||
private readonly IntPtr bhapticsWrapperClassPtr;
|
||||
|
||||
private readonly IntPtr initializeRequestPermissionPtr;
|
||||
|
||||
private readonly IntPtr playEventPtr;
|
||||
private readonly IntPtr playMotorsPtr;
|
||||
private readonly IntPtr playLoopPtr;
|
||||
private readonly IntPtr playGlovePtr;
|
||||
|
||||
private readonly IntPtr getEventIdPtr;
|
||||
|
||||
private readonly IntPtr stopIntPtr;
|
||||
private readonly IntPtr stopByEventIdPtr;
|
||||
private readonly IntPtr stopAllPtr;
|
||||
private readonly IntPtr pingPtr;
|
||||
private readonly IntPtr pingAllPtr;
|
||||
|
||||
// bool methods
|
||||
private readonly IntPtr isPlayingAnythingPtr;
|
||||
private readonly IntPtr isBhapticsUserPtr;
|
||||
private readonly IntPtr isPlayingByEventIdPtr;
|
||||
private readonly IntPtr isPlayingByRequestIdPtr;
|
||||
|
||||
private readonly IntPtr refreshPairingInfoPtr;
|
||||
private readonly IntPtr getDeviceListPtr;
|
||||
|
||||
public AndroidHaptic()
|
||||
{
|
||||
try
|
||||
{
|
||||
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
|
||||
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
|
||||
androidJavaObject =
|
||||
new AndroidJavaObject("com.bhaptics.bhapticsunity.BhapticsManagerWrapper", currentActivity);
|
||||
|
||||
bhapticsWrapperObjectPtr = androidJavaObject.GetRawObject();
|
||||
bhapticsWrapperClassPtr = androidJavaObject.GetRawClass();
|
||||
|
||||
initializeRequestPermissionPtr = AndroidJNIHelper.GetMethodID(
|
||||
androidJavaObject.GetRawClass(),
|
||||
"initializeWithPermissionOption",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
|
||||
|
||||
|
||||
playEventPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "playEvent", "(IIFFFF)I");
|
||||
playGlovePtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "playGlove", "(I[I[I[II)I");
|
||||
getEventIdPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "getEventId", "(Ljava/lang/String;)I");
|
||||
playLoopPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "playLoop", "(IIFFFFII)I");
|
||||
playMotorsPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "playMotors", "(II[I)I");
|
||||
stopIntPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "stopInt");
|
||||
stopByEventIdPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "stopByEventId", "(I)Z");
|
||||
stopAllPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "stopAll");
|
||||
|
||||
pingPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "ping", "(Ljava/lang/String;)V");
|
||||
pingAllPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "pingAll");
|
||||
|
||||
isPlayingAnythingPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "isAnythingPlaying", "()Z");
|
||||
isPlayingByEventIdPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "isPlayingByEventId", "(I)Z");
|
||||
isPlayingByRequestIdPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "isPlayingByRequestId", "(I)Z");
|
||||
isBhapticsUserPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "isBhapticsUser");
|
||||
|
||||
refreshPairingInfoPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "refreshPairing");
|
||||
getDeviceListPtr = AndroidJNIHelper.GetMethodID(bhapticsWrapperClassPtr, "getDeviceListString", "()Ljava/lang/String;");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("AndroidHaptic {0} {1} ", e.Message, e);
|
||||
}
|
||||
|
||||
deviceList = GetDevices();
|
||||
}
|
||||
|
||||
public bool CheckBhapticsAvailable()
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return AndroidUtils.CallNativeBoolMethod(bhapticsWrapperObjectPtr, isBhapticsUserPtr, EmptyParams);
|
||||
}
|
||||
|
||||
public void RefreshPairing()
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AndroidUtils.CallNativeVoidMethod(bhapticsWrapperObjectPtr, refreshPairingInfoPtr, EmptyParams);
|
||||
|
||||
}
|
||||
private int GetEventId(string eventId)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
GetEventIdParams[0] = eventId;
|
||||
return AndroidUtils.CallNativeIntMethod(bhapticsWrapperObjectPtr, getEventIdPtr, GetEventIdParams);
|
||||
}
|
||||
|
||||
public List<HapticDevice> GetDevices()
|
||||
{
|
||||
try
|
||||
{
|
||||
string result = AndroidUtils.CallNativeStringMethod(bhapticsWrapperObjectPtr, getDeviceListPtr, EmptyParams);
|
||||
deviceList = BhapticsHelpers.ConvertToBhapticsDevices(result);
|
||||
|
||||
return deviceList;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] GetDevices() {0}", e.Message);
|
||||
}
|
||||
|
||||
return new List<HapticDevice>();
|
||||
}
|
||||
|
||||
public void InitializeWithPermission(string workspaceId, string sdkKey, string json, bool requestPermission)
|
||||
{
|
||||
BhapticsLogManager.LogFormat("[bHaptics] InitializeWithPermission() {0} {1}", workspaceId, json);
|
||||
AndroidUtils.CallNativeVoidMethod(
|
||||
bhapticsWrapperObjectPtr, initializeRequestPermissionPtr,
|
||||
new object[] { workspaceId, sdkKey, json, requestPermission ? 1 : 0 });
|
||||
}
|
||||
|
||||
public bool IsConnect()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsPlaying()
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return AndroidUtils.CallNativeBoolMethod(bhapticsWrapperObjectPtr, isPlayingAnythingPtr, EmptyParams);
|
||||
}
|
||||
|
||||
public bool IsPlayingByEventId(string eventId)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int eventIntValue = TryGetEventIntValue(eventId);
|
||||
IsPlayingByEventIdParams[0].i = eventIntValue;
|
||||
return AndroidUtils.CallNativeBoolMethod(bhapticsWrapperObjectPtr, isPlayingByEventIdPtr, IsPlayingParams);
|
||||
}
|
||||
|
||||
public bool IsPlayingByRequestId(int requestId)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IsPlayingParams[0].i = requestId;
|
||||
return AndroidUtils.CallNativeBoolMethod(bhapticsWrapperObjectPtr, isPlayingByRequestIdPtr, IsPlayingParams);
|
||||
}
|
||||
|
||||
public void RefreshPairingInfo()
|
||||
{
|
||||
if(androidJavaObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AndroidUtils.CallNativeVoidMethod(bhapticsWrapperObjectPtr, refreshPairingInfoPtr, EmptyParams);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int Play(string eventId)
|
||||
{
|
||||
return PlayParam(eventId, 1f, 1f, 0f, 0f);
|
||||
}
|
||||
|
||||
public int PlayParam(string eventId, float intensity, float duration, float angleX, float offsetY)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int eventIntValue = TryGetEventIntValue(eventId);
|
||||
int requestId = UnityEngine.Random.Range(0, int.MaxValue);
|
||||
|
||||
PlayEventParams[0].i = eventIntValue;
|
||||
PlayEventParams[1].i = requestId;
|
||||
PlayEventParams[2].f = intensity;
|
||||
PlayEventParams[3].f = duration;
|
||||
PlayEventParams[4].f = angleX;
|
||||
PlayEventParams[5].f = offsetY;
|
||||
|
||||
return AndroidUtils.CallNativeIntMethod(bhapticsWrapperObjectPtr, playEventPtr, PlayEventParams);
|
||||
|
||||
}
|
||||
|
||||
public int PlayMotors(int position, int[] motors, int durationMillis)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
PlayMotorsParams[0] = position;
|
||||
PlayMotorsParams[1] = durationMillis;
|
||||
PlayMotorsParams[2] = motors;
|
||||
|
||||
return AndroidUtils.CallNativeIntMethod(bhapticsWrapperObjectPtr, playMotorsPtr, PlayMotorsParams);
|
||||
}
|
||||
|
||||
public int PlayGlove(int position, int[] motors, int[] playTimeValues, int[] shapeValues)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
PlayGloveParams[0] = position;
|
||||
PlayGloveParams[1] = motors;
|
||||
PlayGloveParams[2] = playTimeValues;
|
||||
PlayGloveParams[3] = shapeValues;
|
||||
PlayGloveParams[4] = 6;
|
||||
|
||||
return AndroidUtils.CallNativeIntMethod(bhapticsWrapperObjectPtr, playGlovePtr, PlayGloveParams);
|
||||
}
|
||||
|
||||
public int PlayPath(int position, float[] xValues, float[] yValues, int[] intensityValues, int duration)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
androidJavaObject.Call("submitPath", "key?", position, xValues, yValues, intensityValues, duration);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int PlayLoop(string eventId, float intensity, float duration, float angleX, float offsetY, int interval, int maxCount)
|
||||
{
|
||||
if(androidJavaObject == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int eventIntValue = TryGetEventIntValue(eventId);
|
||||
int requestId = UnityEngine.Random.Range(0, int.MaxValue);
|
||||
|
||||
PlayLoopParams[0].i = eventIntValue;
|
||||
PlayLoopParams[1].i = requestId;
|
||||
PlayLoopParams[2].f = intensity;
|
||||
PlayLoopParams[3].f = duration;
|
||||
PlayLoopParams[4].f = angleX;
|
||||
PlayLoopParams[5].f = offsetY;
|
||||
PlayLoopParams[6].i = interval;
|
||||
PlayLoopParams[7].i = maxCount;
|
||||
return AndroidUtils.CallNativeIntMethod(bhapticsWrapperObjectPtr, playLoopPtr, PlayLoopParams);
|
||||
}
|
||||
|
||||
public bool StopByRequestId(int key)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
StopByRequestIdParams[0].i = key;
|
||||
return AndroidUtils.CallNativeBoolMethod(bhapticsWrapperObjectPtr, stopIntPtr, StopByRequestIdParams);
|
||||
}
|
||||
|
||||
public bool StopByEventId(string eventId)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int eventIntValue = TryGetEventIntValue(eventId);
|
||||
StopByEventIdParams[0].i = eventIntValue;
|
||||
return AndroidUtils.CallNativeBoolMethod(bhapticsWrapperObjectPtr, stopByEventIdPtr, StopByEventIdParams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] StopByEventId() : {0}", e.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int TryGetEventIntValue(string eventId)
|
||||
{
|
||||
int eventIntValue = -1;
|
||||
if (eventDictionary.TryGetValue(eventId, out var value))
|
||||
{
|
||||
eventIntValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
eventIntValue = GetEventId(eventId);
|
||||
eventDictionary[eventId] = eventIntValue;
|
||||
}
|
||||
|
||||
return eventIntValue;
|
||||
}
|
||||
|
||||
public bool Stop()
|
||||
{
|
||||
if (androidJavaObject != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return AndroidUtils.CallNativeBoolMethod(bhapticsWrapperObjectPtr, stopAllPtr, EmptyParams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] Stop() : {0}", e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (androidJavaObject != null)
|
||||
{
|
||||
androidJavaObject.Call("quit");
|
||||
androidJavaObject = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void TogglePosition(string address)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (androidJavaObject != null)
|
||||
{
|
||||
androidJavaObject.Call("togglePosition", address);
|
||||
}
|
||||
}
|
||||
|
||||
public void PingAll()
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AndroidUtils.CallNativeVoidMethod(bhapticsWrapperObjectPtr, pingAllPtr, EmptyParams);
|
||||
}
|
||||
|
||||
public void Ping(string address)
|
||||
{
|
||||
if (androidJavaObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PingParams[0] = address;
|
||||
AndroidUtils.CallNativeVoidMethod(bhapticsWrapperObjectPtr, pingPtr, PingParams);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class AndroidUtils
|
||||
{
|
||||
internal static void CallNativeVoidMethod(IntPtr androidObjPtr, IntPtr methodPtr, object[] param)
|
||||
{
|
||||
jvalue[] args = AndroidJNIHelper.CreateJNIArgArray(param);
|
||||
try
|
||||
{
|
||||
CallNativeVoidMethod(androidObjPtr, methodPtr, args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] CallNativeVoidMethod() : {0}", e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
AndroidJNIHelper.DeleteJNIArgArray(param, args);
|
||||
}
|
||||
}
|
||||
internal static void CallNativeVoidMethod(IntPtr androidObjPtr, IntPtr methodPtr, jvalue[] param)
|
||||
{
|
||||
try
|
||||
{
|
||||
AndroidJNI.CallVoidMethod(androidObjPtr, methodPtr, param);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] CallNativeVoidMethod() : {0}", e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string CallNativeStringMethod(IntPtr androidObjPtr, IntPtr methodPtr, jvalue[] param)
|
||||
{
|
||||
try
|
||||
{
|
||||
return AndroidJNI.CallStringMethod(androidObjPtr, methodPtr, param);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] CallNativeStringMethod() : {0}", e.Message);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
internal static bool CallNativeBoolMethod(IntPtr androidObjPtr, IntPtr methodPtr, object[] param)
|
||||
{
|
||||
jvalue[] args = AndroidJNIHelper.CreateJNIArgArray(param);
|
||||
bool res = false;
|
||||
try
|
||||
{
|
||||
res = CallNativeBoolMethod(androidObjPtr, methodPtr, args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] CallNativeBoolMethod() : {0}", e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
AndroidJNIHelper.DeleteJNIArgArray(param, args);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
internal static bool CallNativeBoolMethod(IntPtr androidObjPtr, IntPtr methodPtr, jvalue[] param)
|
||||
{
|
||||
bool res = false;
|
||||
try
|
||||
{
|
||||
res = AndroidJNI.CallBooleanMethod(androidObjPtr, methodPtr, param);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] CallNativeBoolMethod() : {0}", e.Message);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
internal static int CallNativeIntMethod(IntPtr androidObjPtr, IntPtr methodPtr, object[] param)
|
||||
{
|
||||
jvalue[] args = AndroidJNIHelper.CreateJNIArgArray(param);
|
||||
int res = -1;
|
||||
try
|
||||
{
|
||||
res = CallNativeIntMethod(androidObjPtr, methodPtr, args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] CallNativeIntMethod() : {0}", e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
AndroidJNIHelper.DeleteJNIArgArray(param, args);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
internal static int CallNativeIntMethod(IntPtr androidObjPtr, IntPtr methodPtr, jvalue[] param)
|
||||
{
|
||||
int res = -1;
|
||||
try
|
||||
{
|
||||
res = AndroidJNI.CallIntMethod(androidObjPtr, methodPtr, param);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] CallNativeIntMethod() : {0}", e.Message);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 88a498f451437f4438d6e3b26b6baf85
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
717
Assets/Bhaptics/SDK2/Scripts/Core/Plugins/BhapticsLibrary.cs
Normal file
717
Assets/Bhaptics/SDK2/Scripts/Core/Plugins/BhapticsLibrary.cs
Normal file
|
@ -0,0 +1,717 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
public class BhapticsLibrary
|
||||
{
|
||||
private static readonly object Lock = new object();
|
||||
private static readonly List<HapticDevice> EmptyDevices = new List<HapticDevice>();
|
||||
|
||||
private static AndroidHaptic android = null;
|
||||
private static bool _initialized = false;
|
||||
private static bool isAvailable = false;
|
||||
private static bool isAvailableChecked = false;
|
||||
|
||||
private static bool enableUniversal = false;
|
||||
|
||||
private static Universal.BhapticsTcpClient _client = new Universal.BhapticsTcpClient();
|
||||
|
||||
|
||||
public static bool IsBhapticsAvailable(bool isAutoRunPlayer)
|
||||
{
|
||||
if (isAvailableChecked)
|
||||
{
|
||||
return isAvailable;
|
||||
}
|
||||
|
||||
return IsBhapticsAvailableForce(isAutoRunPlayer);
|
||||
}
|
||||
|
||||
public static bool IsBhapticsAvailableForce(bool isAutoRunPlayer)
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android == null)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("IsBhapticsAvailable() android object not initialized.");
|
||||
isAvailable = false;
|
||||
return isAvailable;
|
||||
}
|
||||
|
||||
android.RefreshPairing();
|
||||
isAvailable = android.CheckBhapticsAvailable();
|
||||
isAvailableChecked = true;
|
||||
return isAvailable;
|
||||
}
|
||||
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
if (!bhaptics_library.isPlayerInstalled())
|
||||
{
|
||||
isAvailable = false;
|
||||
isAvailableChecked = true;
|
||||
return isAvailable;
|
||||
}
|
||||
|
||||
if (!bhaptics_library.isPlayerRunning() && isAutoRunPlayer)
|
||||
{
|
||||
BhapticsLogManager.LogFormat("bHaptics Player(PC) is not running, so try launch it.");
|
||||
bhaptics_library.launchPlayer(true);
|
||||
}
|
||||
|
||||
#endif
|
||||
isAvailable = true;
|
||||
isAvailableChecked = true;
|
||||
|
||||
return isAvailable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static bool Initialize(string appId, string apiKey, string json, bool autoRequestBluetoothPermission = true)
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
if (_initialized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
_client.Initialize(appId, apiKey, json);
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android == null)
|
||||
{
|
||||
BhapticsLogManager.Log("BhapticsLibrary - Initialize ");
|
||||
android = new AndroidHaptic();
|
||||
android.InitializeWithPermission(appId, apiKey, json, autoRequestBluetoothPermission);
|
||||
_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
|
||||
if (bhaptics_library.wsIsConnected())
|
||||
{
|
||||
BhapticsLogManager.Log("BhapticsLibrary - connection already opened");
|
||||
//return false; // NOTE-230117 Temporary comment out for IL2CPP
|
||||
}
|
||||
|
||||
BhapticsLogManager.LogFormat("BhapticsLibrary - Initialize() {0} {1}", apiKey, appId);
|
||||
return bhaptics_library.registryAndInit(apiKey, appId, json);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Destroy()
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
android.Dispose();
|
||||
android = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
BhapticsLogManager.LogFormat("Destroy()");
|
||||
bhaptics_library.wsClose();
|
||||
#endif
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
_client.Destroy();
|
||||
}
|
||||
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
public static bool IsConnect(PositionType type)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return GetConnectedDevices(type).Count > 0;
|
||||
}
|
||||
|
||||
public static int Play(string eventId)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eventId == null || eventId.Equals(string.Empty))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
_client.Play(eventId);
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.Play(eventId);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.play(eventId);
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int PlayParam(string eventId, float intensity, float duration, float angleX, float offsetY)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eventId == null || eventId.Equals(string.Empty))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
_client.Play(eventId, intensity, duration, angleX, offsetY);
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.PlayParam(eventId, intensity, duration, angleX, offsetY);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.playPosParam(eventId, 0, intensity, duration, angleX, offsetY);
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int PlayMotors(int position, int[] motors, int durationMillis)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.PlayMotors(position, motors, durationMillis);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.playDot(position, durationMillis, motors, motors.Length);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int PlayWaveform(PositionType positionType, int[] motorValues, GlovePlayTime[] playTimeValues, GloveShapeValue[] shapeValues)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (motorValues.Length != 6 || playTimeValues.Length != 6 || shapeValues.Length != 6)
|
||||
{
|
||||
BhapticsLogManager.LogError("[bHaptics] BhapticsLibrary - PlayWaveform() 'motorValues, playTimeValues, shapeValues' necessarily require 6 values each.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
var playTimes = new int[playTimeValues.Length];
|
||||
var shapeVals = new int[shapeValues.Length];
|
||||
|
||||
for (int i = 0; i < playTimes.Length; i++)
|
||||
{
|
||||
playTimes[i] = (int)playTimeValues[i];
|
||||
}
|
||||
for (int i = 0; i < shapeVals.Length; i++)
|
||||
{
|
||||
shapeVals[i] = (int)shapeValues[i];
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.PlayGlove((int)positionType, motorValues, playTimes, shapeVals);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.playWaveform((int)positionType, motorValues, playTimes, shapeVals, 6);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int PlayPath(int position, float[] xValues, float[] yValues, int[] intensityValues, int duration)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.PlayPath(position, xValues, yValues, intensityValues, duration);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.playPath(position, xValues, yValues, intensityValues, duration);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int PlayLoop(string eventId, float intensity, float duration, float angleX, float offsetY, int interval, int maxCount)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eventId == null || eventId.Equals(string.Empty))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.PlayLoop(eventId, intensity, duration, angleX, offsetY, interval, maxCount);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.playLoop(eventId, intensity, duration, angleX, offsetY, interval, maxCount);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static bool StopByEventId(string eventId)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
_client.StopByEventId(eventId);
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.StopByEventId(eventId);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.stopByEventId(eventId);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool StopInt(int requestId)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
_client.StopByRequestId(requestId);
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.StopByRequestId(requestId);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.stop(requestId);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool StopAll()
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
_client.StopAll();
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.Stop();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.stopAll();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsPlaying()
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
// TODO ;
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.IsPlaying();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.isPlaying();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
public static bool IsPlayingByEventId(string eventId)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
// TODO ;
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.IsPlayingByEventId(eventId);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.isPlayingByEventId(eventId);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsPlayingByRequestId(int requestId)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.IsPlayingByRequestId(requestId);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.isPlayingByRequestId(requestId);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<HapticDevice> GetDevices()
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return EmptyDevices;
|
||||
}
|
||||
|
||||
|
||||
if (enableUniversal)
|
||||
{
|
||||
// TODO ;
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
return android.GetDevices();
|
||||
}
|
||||
|
||||
return EmptyDevices;
|
||||
}
|
||||
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
return bhaptics_library.GetDevices();
|
||||
#endif
|
||||
|
||||
return EmptyDevices;
|
||||
}
|
||||
|
||||
public static List<HapticDevice> GetConnectedDevices(PositionType pos)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return EmptyDevices;
|
||||
}
|
||||
|
||||
var pairedDeviceList = new List<HapticDevice>();
|
||||
var devices = GetDevices();
|
||||
foreach (var device in devices)
|
||||
{
|
||||
if (device.IsPaired && device.Position == pos && device.IsConnected)
|
||||
{
|
||||
pairedDeviceList.Add(device);
|
||||
}
|
||||
}
|
||||
|
||||
return pairedDeviceList;
|
||||
}
|
||||
|
||||
public static List<HapticDevice> GetPairedDevices(PositionType pos)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return EmptyDevices;
|
||||
}
|
||||
|
||||
var res = new List<HapticDevice>();
|
||||
var devices = GetDevices();
|
||||
foreach (var device in devices)
|
||||
{
|
||||
if (device.IsPaired && device.Position == pos)
|
||||
{
|
||||
res.Add(device);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void Ping(PositionType pos)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var currentDevices = GetConnectedDevices(pos);
|
||||
|
||||
foreach (var device in currentDevices)
|
||||
{
|
||||
Ping(device);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Ping(HapticDevice targetDevice)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
android.Ping(targetDevice.Address);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
bhaptics_library.ping(targetDevice.Address);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void PingAll()
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
android.PingAll();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
bhaptics_library.pingAll();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void TogglePosition(HapticDevice targetDevice)
|
||||
{
|
||||
if (!isAvailable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
if (android != null)
|
||||
{
|
||||
android.TogglePosition(targetDevice.Address);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
bhaptics_library.swapPosition(targetDevice.Address);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void OnApplicationFocus()
|
||||
{
|
||||
IsBhapticsAvailableForce(false);
|
||||
}
|
||||
|
||||
public static void OnApplicationPause()
|
||||
{
|
||||
StopAll();
|
||||
}
|
||||
|
||||
public static void OnApplicationQuit()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static List<MappingMetaData> EditorGetEventList(string appId, string apiKey, int lastVersion, out int status)
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
status = 0;
|
||||
return new List<MappingMetaData>();
|
||||
}
|
||||
|
||||
var res = bhaptics_library.EditorGetEventList(appId, apiKey, lastVersion, out int code);
|
||||
status = code;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static string EditorGetSettings(string appId, string apiKey, int lastVersion, out int status)
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
status = 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
var bytes = bhaptics_library.EditorGetSettings(appId, apiKey, lastVersion, out int code);
|
||||
BhapticsLogManager.LogFormat("EditorGetSettings {0} {1}", code, bytes);
|
||||
status = code;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static bool EditorReInitialize(string appId, string apiKey, string json)
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BhapticsLogManager.LogFormat("[bHaptics] BhapticsLibrary - ReInitialize() {0} {1}", apiKey, appId);
|
||||
return bhaptics_library.reInitMessage(apiKey, appId, json);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1fbce4ef5d424c3429eced6b184b893d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
|
||||
public static class BhapticsLogManager
|
||||
{
|
||||
public static void Log(string format)
|
||||
{
|
||||
// UnityEngine.Debug.Log("[bHaptics]" + format);
|
||||
return;
|
||||
}
|
||||
public static void LogFormat(string format, params object[] args)
|
||||
{
|
||||
// UnityEngine.Debug.LogFormat("[bHaptics]" + format, args);
|
||||
return;
|
||||
}
|
||||
public static void LogErrorFormat(string format, params object[] args)
|
||||
{
|
||||
// UnityEngine.Debug.LogErrorFormat("[bHaptics]" + format, args);
|
||||
return;
|
||||
}
|
||||
public static void LogError(string format)
|
||||
{
|
||||
// UnityEngine.Debug.LogErrorFormat("[bHaptics]" + format);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7b342bc04df079344adaceb30a43b27d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Bhaptics/SDK2/Scripts/Core/Plugins/x86_64.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/Core/Plugins/x86_64.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c6fbc97baa602c84dbb23c82903f5bfc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,158 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
public class bhaptics_library
|
||||
{
|
||||
private const string ModuleName = "bhaptics_library";
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool registryAndInit(string sdkAPIKey, string workspaceId, string initData);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool registryAndInitHost(string sdkAPIKey, string workspaceId, string initData, string url);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool wsIsConnected();
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static void wsClose();
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool reInitMessage(string sdkAPIKey, string workspaceId, string initData);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static int play(string key);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static int playPosParam(string key, int position, float intensity, float duration, float angleX, float offsetY);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool stop(int key);
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool stopByEventId(string eventId);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool stopAll();
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool isPlaying();
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool isPlayingByRequestId(int key);
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool isPlayingByEventId(string eventId);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool isbHapticsConnected(int position);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool ping(string address);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool pingAll();
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool swapPosition(string address);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static IntPtr getDeviceInfoJson();
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool isPlayerInstalled();
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool isPlayerRunning();
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static bool launchPlayer(bool b);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static IntPtr bHapticsGetHapticMessage(string apiKey, string appId, int lastVersion,
|
||||
out int status);
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static IntPtr bHapticsGetHapticMappings(string apiKey, string appId, int lastVersion,
|
||||
out int status);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static int playDot(int position, int durationMillis, int[] motors, int size);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static int playWaveform(int position, int[] motorValues, int[] playTimeValues, int[] shapeValues, int motorLen);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int playPath(int position, float[] xValues, float[] yValues, int[] intensityValues, int Len);
|
||||
|
||||
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
|
||||
extern public static int playLoop(string key, float intensity, float duration, float angleX, float offsetY, int interval, int maxCount);
|
||||
|
||||
// https://stackoverflow.com/questions/36239705/serialize-and-deserialize-json-and-json-array-in-unity
|
||||
public static List<HapticDevice> GetDevices()
|
||||
{
|
||||
IntPtr ptr = getDeviceInfoJson();
|
||||
|
||||
var devicesStr = PtrToStringUtf8(ptr);
|
||||
|
||||
if (devicesStr.Length == 0)
|
||||
{
|
||||
BhapticsLogManager.LogFormat("GetDevices() empty. {0}", devicesStr);
|
||||
return new List<HapticDevice>();
|
||||
}
|
||||
var hapticDevices = JsonUtility.FromJson<DeviceListMessage>("{\"devices\":" + devicesStr + "}");
|
||||
|
||||
return BhapticsHelpers.Convert(hapticDevices.devices);
|
||||
}
|
||||
|
||||
public static List<MappingMetaData> EditorGetEventList(string appId, string apiKey, int lastVersion, out int status)
|
||||
{
|
||||
var bytes = bHapticsGetHapticMappings(apiKey, appId, lastVersion, out int code);
|
||||
status = code;
|
||||
if (code == 0)
|
||||
{
|
||||
string str = PtrToStringUtf8(bytes);
|
||||
var mappingMessage = MappingMessage.CreateFromJSON(str);
|
||||
return mappingMessage.message;
|
||||
}
|
||||
|
||||
BhapticsLogManager.LogFormat("EditorGetEventList {0}", status);
|
||||
return new List<MappingMetaData>();
|
||||
}
|
||||
|
||||
public static string EditorGetSettings(string appId, string apiKey, int lastVersion, out int status2)
|
||||
{
|
||||
var bytes = bHapticsGetHapticMessage(apiKey, appId, lastVersion, out int status);
|
||||
|
||||
status2 = status;
|
||||
if (status == 0)
|
||||
{
|
||||
|
||||
string str = PtrToStringUtf8(bytes);
|
||||
return str;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private static string PtrToStringUtf8(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int len = 0;
|
||||
while (Marshal.ReadByte(ptr, len) != 0)
|
||||
len++;
|
||||
if (len == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
byte[] array = new byte[len];
|
||||
Marshal.Copy(ptr, array, 0, len);
|
||||
return System.Text.Encoding.UTF8.GetString(array);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 029629b776f364f4ba0813bff3c21752
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,76 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 82a3cd61707f8444e9c7f2590ebdaf88
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86_64
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86_64
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Bhaptics/SDK2/Scripts/Core/Samples.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/Core/Samples.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a302fec275492bc43b93371aa7c6dd31
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
306
Assets/Bhaptics/SDK2/Scripts/Core/Samples/PlayParamSample.cs
Normal file
306
Assets/Bhaptics/SDK2/Scripts/Core/Samples/PlayParamSample.cs
Normal file
|
@ -0,0 +1,306 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
public class PlayParamSample : MonoBehaviour
|
||||
{
|
||||
private readonly string SampleAppID = "p4fZNOU6ShHYBxos8Zmr";
|
||||
private readonly string SampleApiKey = "BJ4Sacbew0qVfqONoMSM";
|
||||
|
||||
|
||||
[Header("Canvas")]
|
||||
[SerializeField] private Canvas initCanvas;
|
||||
[SerializeField] private Canvas mainCanvas;
|
||||
|
||||
[Header("Dropdown")]
|
||||
[SerializeField] private Dropdown eventsDropdown;
|
||||
|
||||
[Header("Slider")]
|
||||
[SerializeField] private Slider sliderIntensity;
|
||||
[SerializeField] private Slider sliderDuration;
|
||||
[SerializeField] private Slider sliderAngleX;
|
||||
[SerializeField] private Slider sliderOffsetY;
|
||||
|
||||
[Header("Text")]
|
||||
[SerializeField] private Text intensityValueText;
|
||||
[SerializeField] private Text durationValueText;
|
||||
[SerializeField] private Text angleXValueText;
|
||||
[SerializeField] private Text offsetYValueText;
|
||||
[SerializeField] private Text playButtonText;
|
||||
|
||||
[Header("Button")]
|
||||
[SerializeField] private Button intensityResetButton;
|
||||
[SerializeField] private Button durationResetButton;
|
||||
[SerializeField] private Button angleXResetButton;
|
||||
[SerializeField] private Button offsetYResetButton;
|
||||
|
||||
[Header("Sample")]
|
||||
[SerializeField] private BhapticsSettings sampleSettings;
|
||||
|
||||
|
||||
|
||||
|
||||
private int requestId = -1;
|
||||
private string eventName = "";
|
||||
private MappingMetaData[] events;
|
||||
private Coroutine onClickPlayCoroutine;
|
||||
private BhapticsSettings currentSettings;
|
||||
|
||||
|
||||
#region Properties
|
||||
private float intensity = 1f;
|
||||
private float duration = 1f;
|
||||
private float angleX = 0f;
|
||||
private float offsetY = 0.5f;
|
||||
private int selectedIndex = -1;
|
||||
|
||||
|
||||
public float Intensity
|
||||
{
|
||||
get
|
||||
{
|
||||
return intensity;
|
||||
}
|
||||
set
|
||||
{
|
||||
intensity = value;
|
||||
if (intensityValueText != null)
|
||||
{
|
||||
intensityValueText.text = intensity.ToString("0.0");
|
||||
}
|
||||
if (intensityResetButton != null)
|
||||
{
|
||||
intensityResetButton.gameObject.SetActive(!intensity.Equals(1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
set
|
||||
{
|
||||
duration = value;
|
||||
if (durationValueText != null)
|
||||
{
|
||||
durationValueText.text = duration.ToString("0.0");
|
||||
}
|
||||
if (durationResetButton != null)
|
||||
{
|
||||
durationResetButton.gameObject.SetActive(!duration.Equals(1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float AngleX
|
||||
{
|
||||
get
|
||||
{
|
||||
return angleX;
|
||||
}
|
||||
set
|
||||
{
|
||||
angleX = value;
|
||||
if (angleXValueText != null)
|
||||
{
|
||||
angleXValueText.text = angleX.ToString("0");
|
||||
}
|
||||
if (angleXResetButton != null)
|
||||
{
|
||||
angleXResetButton.gameObject.SetActive(!angleX.Equals(0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float OffsetY
|
||||
{
|
||||
get
|
||||
{
|
||||
return offsetY;
|
||||
}
|
||||
set
|
||||
{
|
||||
offsetY = value;
|
||||
if (offsetYValueText != null)
|
||||
{
|
||||
offsetYValueText.text = offsetY.ToString("0.00");
|
||||
}
|
||||
if (offsetYResetButton != null)
|
||||
{
|
||||
offsetYResetButton.gameObject.SetActive(!offsetY.Equals(0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectedIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
selectedIndex = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
currentSettings = BhapticsSettings.Instance;
|
||||
CheckApplicationSetting();
|
||||
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
|
||||
onClickPlayCoroutine = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void OnClickPlay()
|
||||
{
|
||||
if (onClickPlayCoroutine == null)
|
||||
{
|
||||
onClickPlayCoroutine = StartCoroutine(OnClickPlayCor());
|
||||
}
|
||||
else
|
||||
{
|
||||
StopHaptic();
|
||||
|
||||
playButtonText.text = "Play";
|
||||
}
|
||||
}
|
||||
|
||||
public void SetOffsetY(string offsetYStr)
|
||||
{
|
||||
if (float.TryParse(offsetYStr, out float res))
|
||||
{
|
||||
OffsetY = res;
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenDeveloperPortal()
|
||||
{
|
||||
Application.OpenURL("https://developer.bhaptics.com");
|
||||
}
|
||||
|
||||
public void OpenGuideLink()
|
||||
{
|
||||
Application.OpenURL("https://bhaptics.notion.site/How-to-Start-bHaptics-Unity-SDK2-Beta-33cc33dcfa44426899a3f21c62adf66d");
|
||||
}
|
||||
|
||||
public void UseSampleSettings()
|
||||
{
|
||||
currentSettings = sampleSettings;
|
||||
BhapticsLibrary.Initialize(currentSettings.AppId, currentSettings.ApiKey, currentSettings.DefaultDeploy);
|
||||
CheckApplicationSetting();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void PlayHaptic(string eventName, float intensity, float duration, float angleX, float offsetY)
|
||||
{
|
||||
this.eventName = eventName;
|
||||
requestId = BhapticsLibrary.PlayParam(eventName, intensity, duration, angleX, offsetY);
|
||||
}
|
||||
|
||||
private void StopHaptic()
|
||||
{
|
||||
BhapticsLogManager.LogFormat("Stop {0}", requestId);
|
||||
BhapticsLibrary.StopInt(requestId);
|
||||
|
||||
if (onClickPlayCoroutine != null)
|
||||
{
|
||||
StopCoroutine(onClickPlayCoroutine);
|
||||
onClickPlayCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetValues()
|
||||
{
|
||||
Duration = 1f;
|
||||
Intensity = 1f;
|
||||
AngleX = 0f;
|
||||
OffsetY = 0f;
|
||||
|
||||
sliderDuration.value = Duration;
|
||||
sliderIntensity.value = Intensity;
|
||||
sliderAngleX.value = AngleX;
|
||||
sliderOffsetY.value = OffsetY;
|
||||
}
|
||||
|
||||
private IEnumerator OnClickPlayCor()
|
||||
{
|
||||
playButtonText.text = "Stop";
|
||||
|
||||
// You can also use the const value "BhapticsEvent.OOO" instead of "eventsDropdown.options[SelectedIndex].text".
|
||||
PlayHaptic(eventsDropdown.options[SelectedIndex].text, Duration, Intensity, AngleX, OffsetY);
|
||||
|
||||
yield return null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!BhapticsLibrary.IsPlayingByRequestId(requestId))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
playButtonText.text = "Play";
|
||||
onClickPlayCoroutine = null;
|
||||
}
|
||||
|
||||
private void SetupApplicationData()
|
||||
{
|
||||
events = currentSettings.EventData;
|
||||
BhapticsLogManager.LogFormat("[bHaptics] eventSize {0}", events.Length);
|
||||
|
||||
eventsDropdown.options = new List<Dropdown.OptionData>();
|
||||
|
||||
foreach (var ev in events)
|
||||
{
|
||||
var option = new Dropdown.OptionData(ev.key);
|
||||
eventsDropdown.options.Add(option);
|
||||
}
|
||||
|
||||
if (events.Length > 0)
|
||||
{
|
||||
SelectedIndex = 0;
|
||||
eventsDropdown.value = SelectedIndex;
|
||||
}
|
||||
|
||||
ResetValues();
|
||||
}
|
||||
|
||||
private void CheckApplicationSetting()
|
||||
{
|
||||
if (currentSettings.LastDeployVersion <= 0)
|
||||
{
|
||||
initCanvas.gameObject.SetActive(true);
|
||||
mainCanvas.gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SetupApplicationData();
|
||||
|
||||
initCanvas.gameObject.SetActive(false);
|
||||
mainCanvas.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7d17bcd23407e38428a737982cb82b3c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Bhaptics/SDK2/Scripts/Core/UI.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/Core/UI.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7d83e8320bb8f244b8a1ccb4840ddaf3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
300
Assets/Bhaptics/SDK2/Scripts/Core/UI/BhapticsDeviceUI.cs
Normal file
300
Assets/Bhaptics/SDK2/Scripts/Core/UI/BhapticsDeviceUI.cs
Normal file
|
@ -0,0 +1,300 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
[Serializable]
|
||||
public class PositonIconSetting
|
||||
{
|
||||
public Sprite connect;
|
||||
public Sprite disconnect;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class IconSetting
|
||||
{
|
||||
[Header("Setting Icons")]
|
||||
public PositonIconSetting Vest;
|
||||
public PositonIconSetting Head;
|
||||
public PositonIconSetting Arm;
|
||||
public PositonIconSetting Foot;
|
||||
public PositonIconSetting Hand;
|
||||
public PositonIconSetting GloveL;
|
||||
public PositonIconSetting GloveR;
|
||||
}
|
||||
|
||||
public class BhapticsDeviceUI : MonoBehaviour
|
||||
{
|
||||
private static string SelectHexColor = "#5267F9FF";
|
||||
private static string SelectHoverHexColor = "#697CFFFF";
|
||||
private static string DisableHexColor = "#525466FF";
|
||||
private static string DisableHoverHexColor = "#63646FFF";
|
||||
|
||||
|
||||
[Header("UI")]
|
||||
[SerializeField] private Image icon;
|
||||
|
||||
[SerializeField] private IconSetting widgetSetting;
|
||||
[SerializeField] private Sprite TactsuitWiredIcon;
|
||||
[SerializeField] private Image batteryLowImage;
|
||||
|
||||
[Header("Connect Menu")]
|
||||
[SerializeField] private GameObject ConnectMenu;
|
||||
[SerializeField] private Button pingButton;
|
||||
[SerializeField] private Button lButton;
|
||||
[SerializeField] private Button rButton;
|
||||
[SerializeField] private GameObject wiredNotification;
|
||||
|
||||
[Header("Disconnect Menu")]
|
||||
[SerializeField] private GameObject DisconnectMenu;
|
||||
|
||||
|
||||
|
||||
private HapticDevice device;
|
||||
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (pingButton != null)
|
||||
{
|
||||
pingButton.onClick.AddListener(Ping);
|
||||
}
|
||||
|
||||
if (lButton != null)
|
||||
{
|
||||
lButton.onClick.AddListener(ToLeft);
|
||||
}
|
||||
|
||||
if (rButton != null)
|
||||
{
|
||||
rButton.onClick.AddListener(ToRight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void RefreshDevice(HapticDevice d)
|
||||
{
|
||||
device = d;
|
||||
|
||||
if (device == null)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gameObject.activeSelf)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
UpdateIcon(d);
|
||||
|
||||
if (d.IsConnected)
|
||||
{
|
||||
RenderConnectMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderDisconnectMenu();
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderConnectMenu()
|
||||
{
|
||||
ConnectMenu.gameObject.SetActive(true);
|
||||
DisconnectMenu.gameObject.SetActive(false);
|
||||
batteryLowImage.gameObject.SetActive(device.Battery < 20 && device.Battery >= 0);
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private void RenderDisconnectMenu()
|
||||
{
|
||||
ConnectMenu.gameObject.SetActive(false);
|
||||
DisconnectMenu.gameObject.SetActive(true);
|
||||
batteryLowImage.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void UpdateButtons()
|
||||
{
|
||||
if (device.IsAudioJack)
|
||||
{
|
||||
wiredNotification.SetActive(true);
|
||||
pingButton.gameObject.SetActive(false);
|
||||
rButton.gameObject.SetActive(false);
|
||||
lButton.gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
wiredNotification.SetActive(false);
|
||||
|
||||
if (IsLeft(device.Position) || IsRight(device.Position))
|
||||
{
|
||||
pingButton.gameObject.SetActive(false);
|
||||
lButton.gameObject.SetActive(true);
|
||||
rButton.gameObject.SetActive(true);
|
||||
|
||||
var isLeft = IsLeft(device.Position);
|
||||
ChangeButtonColor(lButton, isLeft);
|
||||
ChangeButtonColor(rButton, !isLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
pingButton.gameObject.SetActive(true);
|
||||
lButton.gameObject.SetActive(false);
|
||||
rButton.gameObject.SetActive(false);
|
||||
|
||||
ChangeButtonColor(pingButton, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateIcon(HapticDevice d)
|
||||
{
|
||||
switch (d.Position)
|
||||
{
|
||||
case PositionType.Vest:
|
||||
if (d.IsAudioJack)
|
||||
{
|
||||
icon.sprite = TactsuitWiredIcon;
|
||||
return;
|
||||
}
|
||||
|
||||
icon.sprite = GetSprite(widgetSetting.Vest, d.IsConnected);
|
||||
break;
|
||||
case PositionType.FootL:
|
||||
case PositionType.FootR:
|
||||
icon.sprite = GetSprite(widgetSetting.Foot, d.IsConnected);
|
||||
break;
|
||||
case PositionType.HandL:
|
||||
case PositionType.HandR:
|
||||
icon.sprite = GetSprite(widgetSetting.Hand, d.IsConnected);
|
||||
break;
|
||||
case PositionType.ForearmL:
|
||||
case PositionType.ForearmR:
|
||||
icon.sprite = GetSprite(widgetSetting.Arm, d.IsConnected);
|
||||
break;
|
||||
case PositionType.GloveL:
|
||||
icon.sprite = GetSprite(widgetSetting.GloveL, d.IsConnected);
|
||||
break;
|
||||
case PositionType.GloveR:
|
||||
icon.sprite = GetSprite(widgetSetting.GloveR, d.IsConnected);
|
||||
break;
|
||||
case PositionType.Head:
|
||||
icon.sprite = GetSprite(widgetSetting.Head, d.IsConnected);
|
||||
break;
|
||||
default:
|
||||
icon.sprite = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private Sprite GetSprite(PositonIconSetting icon, bool connected)
|
||||
{
|
||||
if (icon == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return connected ? icon.connect : icon.disconnect;
|
||||
}
|
||||
|
||||
private void Ping()
|
||||
{
|
||||
if (device == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BhapticsLibrary.Ping(device);
|
||||
}
|
||||
|
||||
private void ToLeft()
|
||||
{
|
||||
if (device == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsRight(device.Position))
|
||||
{
|
||||
BhapticsLibrary.TogglePosition(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ping();
|
||||
}
|
||||
}
|
||||
|
||||
private void ToRight()
|
||||
{
|
||||
if (device == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsLeft(device.Position))
|
||||
{
|
||||
BhapticsLibrary.TogglePosition(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ping();
|
||||
}
|
||||
}
|
||||
|
||||
private Color ToColor(string hex)
|
||||
{
|
||||
Color res = Color.white;
|
||||
|
||||
if (ColorUtility.TryParseHtmlString(hex, out res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private void ChangeButtonColor(Button targetButton, bool isSelect)
|
||||
{
|
||||
var defaultColor = ToColor(isSelect ? SelectHexColor : DisableHexColor);
|
||||
var hoverColor = ToColor(isSelect ? SelectHoverHexColor : DisableHoverHexColor);
|
||||
|
||||
var buttonColors = targetButton.colors;
|
||||
buttonColors.normalColor = defaultColor;
|
||||
buttonColors.highlightedColor = hoverColor;
|
||||
buttonColors.pressedColor = defaultColor;
|
||||
targetButton.colors = buttonColors;
|
||||
}
|
||||
|
||||
private static bool IsLeft(PositionType pos)
|
||||
{
|
||||
switch (pos)
|
||||
{
|
||||
case PositionType.ForearmL:
|
||||
case PositionType.HandL:
|
||||
case PositionType.FootL:
|
||||
case PositionType.GloveL:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsRight(PositionType pos)
|
||||
{
|
||||
switch (pos)
|
||||
{
|
||||
case PositionType.ForearmR:
|
||||
case PositionType.HandR:
|
||||
case PositionType.FootR:
|
||||
case PositionType.GloveR:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 90919fd69ea2be746bb71c8eb3228019
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
234
Assets/Bhaptics/SDK2/Scripts/Core/UI/BhapticsUI.cs
Normal file
234
Assets/Bhaptics/SDK2/Scripts/Core/UI/BhapticsUI.cs
Normal file
|
@ -0,0 +1,234 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
public class BhapticsUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float intervalRefreshTime = 1f;
|
||||
[SerializeField] private RectTransform mainPanel;
|
||||
|
||||
[Header("Devices UI")]
|
||||
[SerializeField] private Transform devicesContainer;
|
||||
[SerializeField] private Transform deviceListPageUi;
|
||||
[SerializeField] private Button deviceListNextPageButton;
|
||||
[SerializeField] private Button deviceListBackPageButton;
|
||||
[SerializeField] private Text deviceListPageText;
|
||||
[SerializeField] private BhapticsDeviceUI devicePrefab;
|
||||
|
||||
[Header("No Paired Device UI")]
|
||||
[SerializeField] private GameObject noPairedDeviceUi;
|
||||
[SerializeField] private Button helpButton;
|
||||
[SerializeField] private Button bHapticsLinkButton;
|
||||
[SerializeField] private GameObject helpUi;
|
||||
[SerializeField] private GameObject helpDescriptionPC;
|
||||
[SerializeField] private GameObject helpDescriptionQuest;
|
||||
[SerializeField] private Button helpCloseButton;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private List<BhapticsDeviceUI> controllers = new List<BhapticsDeviceUI>();
|
||||
private BoxCollider mainPanelCollider;
|
||||
private Vector2 defaultMainPanelSize;
|
||||
private Vector2 defaultDeviceContainerSize;
|
||||
private int deviceListSize = 5;
|
||||
private int deviceListPageIndex = 0;
|
||||
private int expandHeight = 78;
|
||||
private int expandDeviceCount = 4;
|
||||
private int pageActivateDeviceCount = 6;
|
||||
private int pageExpandHeight = 28;
|
||||
private int maxPageIndex;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
for (int i = 0; i < deviceListSize; i++)
|
||||
{
|
||||
var go = Instantiate(devicePrefab, devicesContainer.transform);
|
||||
go.gameObject.SetActive(false);
|
||||
controllers.Add(go);
|
||||
}
|
||||
|
||||
InvokeRepeating("Refresh", 1f, intervalRefreshTime);
|
||||
|
||||
#region AddListener
|
||||
if (helpButton != null)
|
||||
{
|
||||
helpButton.onClick.AddListener(OnHelp);
|
||||
}
|
||||
|
||||
if (helpCloseButton != null)
|
||||
{
|
||||
helpCloseButton.onClick.AddListener(CloseHelpNotification);
|
||||
}
|
||||
|
||||
if (bHapticsLinkButton != null)
|
||||
{
|
||||
bHapticsLinkButton.onClick.AddListener(OpenLink);
|
||||
}
|
||||
|
||||
if (deviceListNextPageButton != null)
|
||||
{
|
||||
deviceListNextPageButton.onClick.AddListener(NextPage);
|
||||
}
|
||||
|
||||
if (deviceListBackPageButton != null)
|
||||
{
|
||||
deviceListBackPageButton.onClick.AddListener(BackPage);
|
||||
}
|
||||
|
||||
if (mainPanel != null)
|
||||
{
|
||||
defaultMainPanelSize = mainPanel.sizeDelta;
|
||||
mainPanelCollider = mainPanel.GetComponent<BoxCollider>();
|
||||
}
|
||||
|
||||
if (devicesContainer != null)
|
||||
{
|
||||
defaultDeviceContainerSize = defaultMainPanelSize;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
CancelInvoke("Refresh");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
var devices = BhapticsLibrary.GetDevices();
|
||||
|
||||
maxPageIndex = Mathf.FloorToInt(devices.Count / (float)deviceListSize);
|
||||
|
||||
if (devices.Count == 0)
|
||||
{
|
||||
noPairedDeviceUi.SetActive(true);
|
||||
|
||||
var deviceContainerRect = devicesContainer as RectTransform;
|
||||
|
||||
deviceContainerRect.sizeDelta = defaultDeviceContainerSize;
|
||||
|
||||
var sizeDelta = mainPanel.sizeDelta;
|
||||
mainPanel.sizeDelta = defaultMainPanelSize;
|
||||
mainPanelCollider.center = new Vector3(0f, - sizeDelta.y * 0.5f, 0f);
|
||||
mainPanelCollider.size = new Vector3(sizeDelta.x, sizeDelta.y, 1f);
|
||||
|
||||
deviceListPageIndex = 0;
|
||||
deviceListPageUi.gameObject.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 currentExpandSize = Vector2.zero;
|
||||
|
||||
if (devices.Count >= pageActivateDeviceCount)
|
||||
{
|
||||
currentExpandSize = new Vector2(0f, expandHeight * (pageActivateDeviceCount - expandDeviceCount) + pageExpandHeight);
|
||||
deviceListPageUi.gameObject.SetActive(true);
|
||||
deviceListPageText.text = (deviceListPageIndex + 1) + " / " + (maxPageIndex + 1);
|
||||
|
||||
deviceListBackPageButton.interactable = deviceListPageIndex != 0;
|
||||
deviceListNextPageButton.interactable = deviceListPageIndex != maxPageIndex;
|
||||
|
||||
if (deviceListPageIndex > maxPageIndex)
|
||||
{
|
||||
deviceListPageIndex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (devices.Count >= expandDeviceCount)
|
||||
{
|
||||
currentExpandSize = new Vector2(0f, expandHeight * (1 + devices.Count - expandDeviceCount));
|
||||
}
|
||||
|
||||
deviceListPageIndex = 0;
|
||||
deviceListPageUi.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
var deviceContainerRect = devicesContainer as RectTransform;
|
||||
deviceContainerRect.sizeDelta = defaultDeviceContainerSize + currentExpandSize;
|
||||
|
||||
mainPanel.sizeDelta = defaultMainPanelSize + currentExpandSize;
|
||||
mainPanelCollider.center = new Vector3(0f, -mainPanel.sizeDelta.y * 0.5f, 0f);
|
||||
mainPanelCollider.size = new Vector3(mainPanel.sizeDelta.x, mainPanel.sizeDelta.y, 1f);
|
||||
|
||||
noPairedDeviceUi.SetActive(false);
|
||||
SetActiveHelpGameObject(false);
|
||||
}
|
||||
|
||||
for (int i = 0; i < deviceListSize; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (i <= devices.Count - 1)
|
||||
{
|
||||
controllers[i].RefreshDevice(devices[i + deviceListPageIndex * deviceListSize]);
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[i].gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
controllers[i].gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHelp()
|
||||
{
|
||||
SetActiveHelpGameObject(true);
|
||||
}
|
||||
|
||||
private void CloseHelpNotification()
|
||||
{
|
||||
SetActiveHelpGameObject(false);
|
||||
}
|
||||
|
||||
private void OpenLink()
|
||||
{
|
||||
Application.OpenURL("https://www.bhaptics.com/support/download");
|
||||
}
|
||||
|
||||
private void NextPage()
|
||||
{
|
||||
deviceListPageIndex = Mathf.Clamp(deviceListPageIndex + 1, 0, maxPageIndex);
|
||||
}
|
||||
|
||||
private void BackPage()
|
||||
{
|
||||
deviceListPageIndex = Mathf.Clamp(deviceListPageIndex - 1, 0, maxPageIndex);
|
||||
}
|
||||
|
||||
private void SetActiveHelpGameObject(bool value)
|
||||
{
|
||||
helpUi.SetActive(value);
|
||||
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
helpDescriptionQuest.SetActive(value);
|
||||
helpDescriptionPC.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
helpDescriptionQuest.SetActive(false);
|
||||
helpDescriptionPC.SetActive(value);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Bhaptics/SDK2/Scripts/Core/UI/BhapticsUI.cs.meta
Normal file
11
Assets/Bhaptics/SDK2/Scripts/Core/UI/BhapticsUI.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1e73d40d7fdd56646a3cb99deaea917f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Bhaptics/SDK2/Scripts/Core/Universal.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/Core/Universal.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e6765208bb5c0b34c84554f2d5213ab9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
358
Assets/Bhaptics/SDK2/Scripts/Core/Universal/BhapticsTcpClient.cs
Normal file
358
Assets/Bhaptics/SDK2/Scripts/Core/Universal/BhapticsTcpClient.cs
Normal file
|
@ -0,0 +1,358 @@
|
|||
using System.Collections;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using System.Net;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Bhaptics.SDK2.Universal
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
public class UdpMessage
|
||||
{
|
||||
public string userId = "";
|
||||
public int port = 8000;
|
||||
}
|
||||
|
||||
public class BhapticsTcpClient
|
||||
{
|
||||
public bool connected = false;
|
||||
public bool connecting = false;
|
||||
private volatile bool _isListening = false;
|
||||
private volatile bool _isTcpLoop = false;
|
||||
|
||||
#region private members
|
||||
private TcpClient socketConnection;
|
||||
private Thread sdkThread;
|
||||
private Thread udpThread;
|
||||
private Thread pingThread;
|
||||
|
||||
private string _apiKey;
|
||||
private string _appId;
|
||||
private string _serverIp = "";
|
||||
private int _serverPort;
|
||||
|
||||
private DateTime last = new DateTime();
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
public void Initialize(string appId, string apiKey, string defaultConfig)
|
||||
{
|
||||
_appId = appId;
|
||||
_apiKey = apiKey;
|
||||
|
||||
StartUdpListener();
|
||||
}
|
||||
|
||||
public int Play(string eventName)
|
||||
{
|
||||
return Play(eventName, 1f, 1f, 0f, 0f);
|
||||
}
|
||||
|
||||
public int Play(string eventName, float intensity, float duration, float angleX, float offsetY)
|
||||
{
|
||||
BhapticsLogManager.Log("[bhaptics-universal] Play: " + eventName + ", " + DateTime.UtcNow.Millisecond);
|
||||
|
||||
int requesetId = UnityEngine.Random.Range(1, int.MaxValue);
|
||||
|
||||
var playMessage = new PlayMessage
|
||||
{
|
||||
eventName = eventName,
|
||||
requestId = requesetId,
|
||||
intensity = intensity,
|
||||
duration = duration,
|
||||
offsetAngleX = angleX,
|
||||
offsetY = offsetY,
|
||||
};
|
||||
var message = TactHubMessage.SdkPlay(playMessage);
|
||||
|
||||
SendMessageToTactHub(JsonUtility.ToJson(message));
|
||||
|
||||
return requesetId;
|
||||
}
|
||||
|
||||
public void StopAll()
|
||||
{
|
||||
BhapticsLogManager.Log("[bhaptics-universal] StopAll: ");
|
||||
var message = TactHubMessage.StopAll;
|
||||
|
||||
SendMessageToTactHub(JsonUtility.ToJson(message));
|
||||
}
|
||||
|
||||
public void StopByEventId(string eventName)
|
||||
{
|
||||
BhapticsLogManager.Log("[bhaptics-universal] StopByEventId: " + eventName);
|
||||
var message = TactHubMessage.SdkStopByEventId(eventName);
|
||||
|
||||
SendMessageToTactHub(JsonUtility.ToJson(message));
|
||||
}
|
||||
|
||||
public void StopByRequestId(int requestId)
|
||||
{
|
||||
BhapticsLogManager.Log("[bhaptics-universal] StopByEventId: " + requestId);
|
||||
var message = TactHubMessage.SdkStopByRequestId(requestId);
|
||||
|
||||
SendMessageToTactHub(JsonUtility.ToJson(message));
|
||||
}
|
||||
|
||||
public void Ping()
|
||||
{
|
||||
var message = TactHubMessage.SdkPingServer();
|
||||
SendMessageToTactHub(JsonUtility.ToJson(message));
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
StopUdpListener();
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
_isTcpLoop = false;
|
||||
_isListening = false;
|
||||
}
|
||||
|
||||
|
||||
private void StartUdpListener()
|
||||
{
|
||||
if (_isListening)
|
||||
{
|
||||
BhapticsLogManager.LogFormat("[bhaptics-universal] StartUdpListener listening...");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_isListening = true;
|
||||
BhapticsLogManager.Log("[bhaptics-universal] StartUdpListener ");
|
||||
udpThread = new Thread(UdpBroadcastingListenLoop);
|
||||
udpThread.IsBackground = true;
|
||||
udpThread.Start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogFormat("[bhaptics-universal] ReceiveUDP exception {0}", e.Message);
|
||||
_isListening = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void StopUdpListener()
|
||||
{
|
||||
_isListening = false;
|
||||
}
|
||||
|
||||
private void ConnectToTactHub(string ip, int port)
|
||||
{
|
||||
if (connected) {
|
||||
BhapticsLogManager.LogFormat("[bhaptics-universal] ConnectToTactHub: connected {0}:{1}", ip, port);
|
||||
return;
|
||||
}
|
||||
if (connecting) {
|
||||
BhapticsLogManager.LogFormat("[bhaptics-universal] ConnectToTactHub: connecting {0}:{1}", ip, port);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
connecting = true;
|
||||
_serverIp = ip;
|
||||
_serverPort = port;
|
||||
BhapticsLogManager.LogFormat("[bhaptics-universal] ConnectToTactHub {0}:{1}", ip, port);
|
||||
_isTcpLoop = true;
|
||||
sdkThread = new Thread(TactHubLoop)
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
sdkThread.Start();
|
||||
pingThread = new Thread(PingLoop)
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
pingThread.Start();
|
||||
|
||||
connected = true;
|
||||
connecting = false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BhapticsLogManager.Log("ConnectToTactHub exception " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void PingLoop()
|
||||
{
|
||||
while (connected) {
|
||||
var current = DateTime.Now;
|
||||
long diffTicks = current.Ticks - last.Ticks;
|
||||
var diffSpan = new TimeSpan(diffTicks);
|
||||
// 1s = 10,000,000 ticks
|
||||
if (diffSpan.TotalSeconds > 1)
|
||||
{
|
||||
Ping();
|
||||
last = current;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void UdpBroadcastingListenLoop()
|
||||
{
|
||||
BhapticsLogManager.Log("[bhaptics-universal] UdpBroadcastingListenLoop");
|
||||
var udpEndPoint = new IPEndPoint(IPAddress.Any, 15884);
|
||||
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
||||
socket.Bind(udpEndPoint);
|
||||
|
||||
while (_isListening)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
BhapticsLogManager.Log("[bhaptics-universal] UdpBroadcastingListenLoop: connected");
|
||||
StopUdpListener();
|
||||
break;
|
||||
}
|
||||
|
||||
var sender = new IPEndPoint(IPAddress.Any, 0);
|
||||
EndPoint remote = sender;
|
||||
|
||||
var data = new byte[1024];
|
||||
|
||||
int receivedSize = socket.ReceiveFrom(data, ref remote);
|
||||
|
||||
var endPoint = remote as IPEndPoint;
|
||||
|
||||
var str = (Encoding.UTF8.GetString(data, 0, receivedSize));
|
||||
|
||||
UdpMessage message = JsonUtility.FromJson<UdpMessage>(str);
|
||||
|
||||
if (connected || connecting) {
|
||||
continue;
|
||||
}
|
||||
BhapticsLogManager.LogFormat("[bhaptics-universal] UdpBroadcastingListenLoop Message received from {0}:", remote.ToString());
|
||||
|
||||
ConnectToTactHub(endPoint.Address.ToString(), message.port);
|
||||
|
||||
BhapticsLogManager.LogFormat("[bhaptics-universal] UdpBroadcastingListenLoop ip: {0}:{1}, userId: {2}", endPoint.Address.ToString(), endPoint.Port , message.userId);
|
||||
}
|
||||
|
||||
udpThread = null;
|
||||
}
|
||||
|
||||
private void TactHubLoop()
|
||||
{
|
||||
try
|
||||
{
|
||||
socketConnection = new TcpClient(_serverIp, _serverPort);
|
||||
|
||||
var bytes = new byte[1024];
|
||||
while (_isTcpLoop)
|
||||
{
|
||||
using (var stream = socketConnection.GetStream()) {
|
||||
InitializeSdk();
|
||||
|
||||
if (!stream.CanRead)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int length;
|
||||
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
|
||||
{
|
||||
var incomingData = new byte[length];
|
||||
Array.Copy(bytes, 0, incomingData, 0, length);
|
||||
string serverMessage = Encoding.UTF8.GetString(incomingData);
|
||||
BhapticsLogManager.Log("[bhaptics-universal] TactHubLoop received as: " + DateTime.UtcNow.Second + ":" + DateTime.UtcNow.Millisecond + " " + serverMessage);
|
||||
|
||||
var message = JsonUtility.FromJson<TactHubMessage>(serverMessage);
|
||||
|
||||
|
||||
switch (message.type)
|
||||
{
|
||||
case MessageType.ServerTokenMessage:
|
||||
var token = JsonUtility.FromJson<TokenMessage>(message.message);
|
||||
|
||||
UnityMainThreadDispatcher.Instance().Enqueue(CheckAPI(token.token, token.tokenKey));
|
||||
break;
|
||||
default:
|
||||
BhapticsLogManager.Log("[bhaptics-universal] Unknown message " + message.message);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (SocketException socketException)
|
||||
{
|
||||
BhapticsLogManager.Log("Socket exception: " + socketException);
|
||||
}
|
||||
catch (Exception e) {
|
||||
BhapticsLogManager.Log("Exception: " + e);
|
||||
}
|
||||
|
||||
_isTcpLoop = false;
|
||||
connected = false;
|
||||
connecting = false;
|
||||
socketConnection = null;
|
||||
|
||||
StartUdpListener();
|
||||
}
|
||||
|
||||
private void InitializeSdk()
|
||||
{
|
||||
var message = TactHubMessage.InitializeMessage(_appId, _apiKey);
|
||||
|
||||
SendMessageToTactHub(JsonUtility.ToJson(message));
|
||||
}
|
||||
|
||||
private void SendMessageToTactHub(string message = "message")
|
||||
{
|
||||
if (socketConnection == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
//Debug.Log("SendMessageToTactHub: " + DateTime.UtcNow.Second + ":" + DateTime.UtcNow.Millisecond);
|
||||
var stream = socketConnection.GetStream();
|
||||
if (stream.CanWrite)
|
||||
{
|
||||
byte[] clientMessageAsByteArray = Encoding.UTF8.GetBytes($"{message}\n");
|
||||
stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length);
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{ }
|
||||
}
|
||||
|
||||
|
||||
IEnumerator CheckAPI(string token, string tokenKey)
|
||||
{
|
||||
string url = "https://dev-sdk-apis.bhaptics.com/api/v1/tacthub-api/verify?token=" + token + "&token-key=" + tokenKey;
|
||||
|
||||
UnityWebRequest www = UnityWebRequest.Get(url);
|
||||
|
||||
yield return www.SendWebRequest();
|
||||
|
||||
if (www.error == null)
|
||||
{
|
||||
BhapticsLogManager.Log(www.downloadHandler.text);
|
||||
}
|
||||
else
|
||||
{
|
||||
BhapticsLogManager.Log("[bhaptics-universal] CheckAPI() error " + www.error);
|
||||
BhapticsLogManager.Log(www.downloadHandler.text);
|
||||
|
||||
// TactHub App is not valid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7d896ac2a7d138243a70bc481e2cc324
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
128
Assets/Bhaptics/SDK2/Scripts/Core/Universal/TactHubMessage.cs
Normal file
128
Assets/Bhaptics/SDK2/Scripts/Core/Universal/TactHubMessage.cs
Normal file
|
@ -0,0 +1,128 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bhaptics.SDK2.Universal
|
||||
{
|
||||
|
||||
public static class MessageType
|
||||
{
|
||||
public const string ServerTokenMessage = "ServerTokenMessage";
|
||||
|
||||
public const string SdkPlay = "SdkPlay";
|
||||
public const string SdkPing = "SdkPing";
|
||||
public const string SdkPingToServer = "SdkPingToServer";
|
||||
public const string SdkPingAll = "SdkPingAll";
|
||||
public const string SdkPlayDotMode = "SdkPlayDotMode";
|
||||
public const string SdkStopByRequestId = "SdkStopByRequestId";
|
||||
public const string SdkStopByEventId = "SdkStopByEventId";
|
||||
public const string SdkStopAll = "SdkStopAll";
|
||||
public const string SdkRequestAuthInit = "SdkRequestAuthInit";
|
||||
|
||||
|
||||
public const string SdkPlayLoop = "SdkPlayLoop";
|
||||
public const string SdkPlayGloveMode = "SdkPlayGloveMode";
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class PlayMessage
|
||||
{
|
||||
public string eventName;
|
||||
public int requestId;
|
||||
public float intensity = 1f;
|
||||
public float duration = 1f;
|
||||
public float offsetAngleX = 0f;
|
||||
public float offsetY = 0f;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AuthenticationMessage
|
||||
{
|
||||
public string sdkApiKey;
|
||||
public string applicationId;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class TokenMessage
|
||||
{
|
||||
public string token;
|
||||
public string tokenKey;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class TactHubMessage
|
||||
{
|
||||
public string type;
|
||||
public string message;
|
||||
|
||||
public static TactHubMessage SdkPlay(PlayMessage message)
|
||||
{
|
||||
return new TactHubMessage()
|
||||
{
|
||||
message = JsonUtility.ToJson(message),
|
||||
type = MessageType.SdkPlay
|
||||
};
|
||||
}
|
||||
public static TactHubMessage InitializeMessage(string appId, string apiKey)
|
||||
{
|
||||
return new TactHubMessage()
|
||||
{
|
||||
message = JsonUtility.ToJson(new AuthenticationMessage()
|
||||
{
|
||||
applicationId = appId,
|
||||
sdkApiKey = apiKey,
|
||||
}),
|
||||
type = MessageType.SdkRequestAuthInit
|
||||
};
|
||||
}
|
||||
|
||||
public static TactHubMessage SdkStopByRequestId(int requestId)
|
||||
{
|
||||
return new TactHubMessage()
|
||||
{
|
||||
message = requestId.ToString(),
|
||||
type = MessageType.SdkStopByRequestId,
|
||||
};
|
||||
}
|
||||
public static TactHubMessage SdkStopByEventId(string eventId)
|
||||
{
|
||||
return new TactHubMessage()
|
||||
{
|
||||
message = eventId,
|
||||
type = MessageType.SdkStopByEventId,
|
||||
};
|
||||
}
|
||||
|
||||
public static TactHubMessage SdkPingServer()
|
||||
{
|
||||
return new TactHubMessage()
|
||||
{
|
||||
message = "",
|
||||
type = MessageType.SdkPingToServer,
|
||||
};
|
||||
}
|
||||
public static TactHubMessage SdkPing(string address)
|
||||
{
|
||||
return new TactHubMessage()
|
||||
{
|
||||
message = address,
|
||||
type = MessageType.SdkPing,
|
||||
};
|
||||
}
|
||||
public static TactHubMessage SdkPingAll()
|
||||
{
|
||||
return new TactHubMessage()
|
||||
{
|
||||
type = MessageType.SdkPingAll,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static readonly TactHubMessage StopAll = new TactHubMessage()
|
||||
{
|
||||
type = MessageType.SdkStopAll,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7833598fe27a4a44086be4f5612dfe76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
Copyright 2015 Pim de Witte All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bhaptics.SDK2.Universal
|
||||
{
|
||||
|
||||
/// Author: Pim de Witte (pimdewitte.com) and contributors, https://github.com/PimDeWitte/UnityMainThreadDispatcher
|
||||
/// <summary>
|
||||
/// A thread-safe class which holds a queue with actions to execute on the next Update() method. It can be used to make calls to the main thread for
|
||||
/// things such as UI Manipulation in Unity. It was developed for use in combination with the Firebase Unity plugin, which uses separate threads for event handling
|
||||
/// </summary>
|
||||
public class UnityMainThreadDispatcher : MonoBehaviour
|
||||
{
|
||||
|
||||
private static readonly Queue<Action> _executionQueue = new Queue<Action>();
|
||||
|
||||
public void Update()
|
||||
{
|
||||
lock (_executionQueue)
|
||||
{
|
||||
while (_executionQueue.Count > 0)
|
||||
{
|
||||
_executionQueue.Dequeue().Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locks the queue and adds the IEnumerator to the queue
|
||||
/// </summary>
|
||||
/// <param name="action">IEnumerator function that will be executed from the main thread.</param>
|
||||
public void Enqueue(IEnumerator action)
|
||||
{
|
||||
lock (_executionQueue)
|
||||
{
|
||||
_executionQueue.Enqueue(() =>
|
||||
{
|
||||
StartCoroutine(action);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locks the queue and adds the Action to the queue
|
||||
/// </summary>
|
||||
/// <param name="action">function that will be executed from the main thread.</param>
|
||||
public void Enqueue(Action action)
|
||||
{
|
||||
Enqueue(ActionWrapper(action));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locks the queue and adds the Action to the queue, returning a Task which is completed when the action completes
|
||||
/// </summary>
|
||||
/// <param name="action">function that will be executed from the main thread.</param>
|
||||
/// <returns>A Task that can be awaited until the action completes</returns>
|
||||
public Task EnqueueAsync(Action action)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
|
||||
void WrappedAction()
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
tcs.TrySetResult(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.TrySetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
Enqueue(ActionWrapper(WrappedAction));
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
|
||||
IEnumerator ActionWrapper(Action a)
|
||||
{
|
||||
a();
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
private static UnityMainThreadDispatcher _instance = null;
|
||||
|
||||
public static bool Exists()
|
||||
{
|
||||
return _instance != null;
|
||||
}
|
||||
|
||||
public static UnityMainThreadDispatcher Instance()
|
||||
{
|
||||
if (!Exists())
|
||||
{
|
||||
throw new Exception("UnityMainThreadDispatcher could not find the UnityMainThreadDispatcher object. Please ensure you have added the MainThreadExecutor Prefab to your scene.");
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = this;
|
||||
DontDestroyOnLoad(this.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
_instance = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d3309bbcfda3ce549b09ebc27e2d6f02
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Bhaptics/SDK2/Scripts/Editor.meta
Normal file
8
Assets/Bhaptics/SDK2/Scripts/Editor.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9bdee2cb3d256c349b2fe66406f032a1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "Bhaptics.SDK2.Editor",
|
||||
"references": [
|
||||
"GUID:464dd5f1479658c42bf2844d11534e1e"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1c8442bf8580b9246a99702a6e88c576
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
134
Assets/Bhaptics/SDK2/Scripts/Editor/BhapticsEventGenerator.cs
Normal file
134
Assets/Bhaptics/SDK2/Scripts/Editor/BhapticsEventGenerator.cs
Normal file
|
@ -0,0 +1,134 @@
|
|||
using System.CodeDom;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.IO;
|
||||
using Microsoft.CSharp;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
// https://github.com/ValveSoftware/steamvr_unity_plugin/blob/master/Assets/SteamVR/Input/Editor/SteamVR_Input_Generator.cs
|
||||
public class BhapticsEventGenerator
|
||||
{
|
||||
private const string secretKey = "bhaptics";
|
||||
|
||||
private static bool fileChanged = false;
|
||||
|
||||
|
||||
public static void CreateEventCsFile(string fileName, string[] eventList)
|
||||
{
|
||||
CodeCompileUnit compileUnit = new CodeCompileUnit();
|
||||
CodeNamespace codeNamespace = new CodeNamespace(typeof(BhapticsLibrary).Namespace);
|
||||
codeNamespace.Imports.Add(new CodeNamespaceImport("System"));
|
||||
codeNamespace.Imports.Add(new CodeNamespaceImport("UnityEngine"));
|
||||
compileUnit.Namespaces.Add(codeNamespace);
|
||||
|
||||
|
||||
CodeTypeDeclaration setClass = new CodeTypeDeclaration(fileName);
|
||||
setClass.Attributes = MemberAttributes.Public;
|
||||
codeNamespace.Types.Add(setClass);
|
||||
|
||||
foreach (var s in eventList)
|
||||
{
|
||||
CodeMemberField field = new CodeMemberField(typeof(string), s.Replace("-", "_").Replace(".", "_").ToUpper());
|
||||
field.Attributes = MemberAttributes.Public | MemberAttributes.Const;
|
||||
field.InitExpression = new CodePrimitiveExpression(s);
|
||||
|
||||
setClass.Members.Add(field);
|
||||
}
|
||||
|
||||
string folderPath = Path.Combine(BhapticsSDK2.GetScriptPath(), "AutoGenerated");
|
||||
|
||||
BhapticsLogManager.LogFormat("{0}", folderPath);
|
||||
|
||||
string fullSourceFilePath = Path.Combine(folderPath, setClass.Name + ".cs");
|
||||
|
||||
if (Directory.Exists(folderPath) == false)
|
||||
{
|
||||
Directory.CreateDirectory(folderPath);
|
||||
|
||||
}
|
||||
|
||||
CreateFile(fullSourceFilePath, compileUnit);
|
||||
}
|
||||
|
||||
private static void CreateFile(string fullPath, CodeCompileUnit compileUnit)
|
||||
{
|
||||
// Generate the code with the C# code provider.
|
||||
CSharpCodeProvider provider = new CSharpCodeProvider();
|
||||
|
||||
// Build the output file name.
|
||||
string fullSourceFilePath = fullPath;
|
||||
BhapticsLogManager.Log("[bHaptics] Success App Setup\nWriting class to: " + fullSourceFilePath);
|
||||
|
||||
string path = BhapticsSDK2.GetScriptPath();
|
||||
|
||||
string priorMD5 = null;
|
||||
FileInfo file = new FileInfo(fullSourceFilePath);
|
||||
if (file.Exists)
|
||||
{
|
||||
file.IsReadOnly = false;
|
||||
priorMD5 = GetBadMD5HashFromFile(fullSourceFilePath);
|
||||
}
|
||||
|
||||
// Create a TextWriter to a StreamWriter to the output file.
|
||||
using (StreamWriter sw = new StreamWriter(fullSourceFilePath, false))
|
||||
{
|
||||
IndentedTextWriter tw = new IndentedTextWriter(sw, " ");
|
||||
|
||||
// Generate source code using the code provider.
|
||||
provider.GenerateCodeFromCompileUnit(compileUnit, tw,
|
||||
new CodeGeneratorOptions() { BracingStyle = "C" });
|
||||
|
||||
// Close the output file.
|
||||
tw.Close();
|
||||
|
||||
string newMD5 = GetBadMD5HashFromFile(fullSourceFilePath);
|
||||
|
||||
if (priorMD5 != newMD5)
|
||||
fileChanged = true;
|
||||
}
|
||||
|
||||
if (fileChanged)
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
BhapticsLogManager.Log("class created at: " + fullSourceFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetBadMD5HashFromFile(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath) == false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string data = File.ReadAllText(filePath);
|
||||
|
||||
return GetBadMD5Hash(data + secretKey);
|
||||
}
|
||||
|
||||
public static string GetBadMD5Hash(string usedString)
|
||||
{
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(usedString + secretKey);
|
||||
|
||||
return GetBadMD5Hash(bytes);
|
||||
}
|
||||
|
||||
public static string GetBadMD5Hash(byte[] bytes)
|
||||
{
|
||||
System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
|
||||
byte[] hash = md5.ComputeHash(bytes);
|
||||
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||
|
||||
for (int i = 0; i < hash.Length; i++)
|
||||
{
|
||||
sb.Append(hash[i].ToString("x2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 76372ec39f31fdb45b8a231d91e5dee0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
957
Assets/Bhaptics/SDK2/Scripts/Editor/BhapticsSettingWindow.cs
Normal file
957
Assets/Bhaptics/SDK2/Scripts/Editor/BhapticsSettingWindow.cs
Normal file
|
@ -0,0 +1,957 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bhaptics.SDK2.Editor
|
||||
{
|
||||
public class BhapticsSettingWindow : EditorWindow
|
||||
{
|
||||
private enum NavigationButtonType
|
||||
{
|
||||
Home = 0, Events = 1, Documentation = 2
|
||||
}
|
||||
|
||||
public enum DocumentationButtonType
|
||||
{
|
||||
Unity, bHaptics, MetaQuest2
|
||||
}
|
||||
|
||||
private const string DeveloperPortalGuideUrl = "https://bhaptics.notion.site/Create-haptic-events-using-bHaptics-Developer-Portal-b056c5a56e514afeb0ed436873dd87c6";
|
||||
private const string UnityHowToStartUrl = "https://bhaptics.notion.site/Plug-in-deployed-events-to-Unity-33cc33dcfa44426899a3f21c62adf66d";
|
||||
private const string UnityMigrateUrl = "https://bhaptics.notion.site/How-to-migrate-from-SDK1-old-to-SDK2-new-007c00b65129404287d9175b71fa029c";
|
||||
|
||||
private const string WindowTitle = "bHaptics Developer Window";
|
||||
private const float WindowWidth = 1000f;
|
||||
private const float WindowHeight = 650f;
|
||||
private const float WindowPositionX = 300f;
|
||||
private const float WindowPositionY = 150f;
|
||||
|
||||
private const float EventsButtonWidth = 335f;
|
||||
private const float EventsButtonHeight = 86f;
|
||||
private const float EventsButtonDetailWidth = 680f;
|
||||
private const float EventsButtonDetailHeight = 72f;
|
||||
private const float EventsButtonSpacing = 10f;
|
||||
|
||||
private const float DocumentationButtonWidth = 580f;
|
||||
private const float DocumentationButtonHeight = 70f;
|
||||
private const float DocumentationButtonSpacing = 16f;
|
||||
|
||||
private static NavigationButtonType SelectedNavigationButtionType = NavigationButtonType.Home;
|
||||
private static Vector2 CurrentEventsScrollPos = Vector2.zero;
|
||||
private static bool IsSortLastUpdated = false;
|
||||
private static bool IsViewGrid = true;
|
||||
|
||||
private SerializedProperty appIdProperty;
|
||||
private SerializedProperty apiKeyProperty;
|
||||
|
||||
private BhapticsSettings settings;
|
||||
private SerializedObject so;
|
||||
|
||||
#region Images
|
||||
private Texture2D whiteImage;
|
||||
private Texture2D latestDeployedVersionBox;
|
||||
private Texture2D homeIcon;
|
||||
private Texture2D hapticEventsIcon;
|
||||
private Texture2D documentationIcon;
|
||||
private Texture2D homeSelectedIcon;
|
||||
private Texture2D hapticEventsSelectedIcon;
|
||||
private Texture2D documentationSelectedIcon;
|
||||
private Texture2D sampleGuidesImage;
|
||||
private Texture2D appIdApiKeyOutlineImage;
|
||||
private Texture2D eventsButtonAudioIcon;
|
||||
private Texture2D unityDocumentationImage;
|
||||
private Texture2D bHapticsDocumentationImage;
|
||||
private Texture2D metaQuest2DocumentationImage;
|
||||
#endregion
|
||||
|
||||
#region GUIStyle
|
||||
private GUIStyle fontBoldStyle;
|
||||
private GUIStyle fontMediumStyle;
|
||||
private GUIStyle fontRegularStyle;
|
||||
private GUIStyle fontLightStyle;
|
||||
private GUIStyle divideStyle;
|
||||
private GUIStyle navigationButtonStyle;
|
||||
private GUIStyle selectedNavigationButtonStyle;
|
||||
private GUIStyle tempAreaStyle;
|
||||
private GUIStyle setupInputFieldStyle;
|
||||
private GUIStyle setupButtonStyle;
|
||||
private GUIStyle visitTextButtonStyle;
|
||||
private GUIStyle visitButtonStyle;
|
||||
private GUIStyle resetButtonStyle;
|
||||
private GUIStyle hapticEventsButtonStyle;
|
||||
private GUIStyle setupErrorTextStyle;
|
||||
private GUIStyle appTitleTextStyle;
|
||||
private GUIStyle blackBackgroundStyle;
|
||||
private GUIStyle latestDeployedVersionTextStyle;
|
||||
private GUIStyle refreshDeployedVersionButtonStyle;
|
||||
private GUIStyle mainTapTitleStyle;
|
||||
private GUIStyle sampleGuideButtonStyle;
|
||||
private GUIStyle copyClipboardButtonStyle;
|
||||
private GUIStyle viewAllTextStyle;
|
||||
private GUIStyle eventsButtonDetailStyle;
|
||||
private GUIStyle eventsButtonDetailSelectedStyle;
|
||||
private GUIStyle eventsButtonStyle;
|
||||
private GUIStyle eventsButtonSelectedStyle;
|
||||
private GUIStyle eventsButtonTitleStyle;
|
||||
private GUIStyle eventsButtonDeviceStyle;
|
||||
private GUIStyle eventsButtonDurationStyle;
|
||||
private GUIStyle documentationButtonStyle;
|
||||
private GUIStyle lastUpdatedToggleStyle;
|
||||
private GUIStyle lastUpdatedToggleSelectedStyle;
|
||||
private GUIStyle aZToggleStyle;
|
||||
private GUIStyle aZToggleSelectedStyle;
|
||||
private GUIStyle viewGridStyle;
|
||||
private GUIStyle viewGridSelectedStyle;
|
||||
private GUIStyle viewListStyle;
|
||||
private GUIStyle viewListSelectedStyle;
|
||||
#endregion
|
||||
|
||||
private GUISkin bHapticsSkin;
|
||||
|
||||
private Action OnChangePage;
|
||||
private MappingMetaData selectedEvent = null;
|
||||
private MappingMetaData[] sortedEventData;
|
||||
private string setupErrorText = string.Empty;
|
||||
private bool isValidState = false;
|
||||
private double nextForceRepaint;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem("bHaptics/Developer Window &b")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
// we need internet access
|
||||
if (!PlayerSettings.Android.forceInternetPermission)
|
||||
{
|
||||
PlayerSettings.Android.forceInternetPermission = true;
|
||||
BhapticsLogManager.Log("[bHaptics] Internet Access is set to Require");
|
||||
}
|
||||
|
||||
var windowSize = new Vector2(WindowWidth, WindowHeight);
|
||||
var bHapticsWindow = EditorWindow.GetWindowWithRect(typeof(BhapticsSettingWindow), new Rect(new Vector2(WindowPositionX, WindowPositionY), windowSize), true, WindowTitle);
|
||||
bHapticsWindow.position = new Rect(new Vector2(WindowPositionX, WindowPositionY), windowSize);
|
||||
bHapticsWindow.minSize = windowSize;
|
||||
bHapticsWindow.Show();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
settings = BhapticsSettings.Instance;
|
||||
so = new SerializedObject(settings);
|
||||
wantsMouseMove = true;
|
||||
|
||||
so.Update();
|
||||
|
||||
appIdProperty = so.FindProperty("appId");
|
||||
apiKeyProperty = so.FindProperty("apiKey");
|
||||
|
||||
InitializeImages();
|
||||
|
||||
bHapticsSkin = Resources.Load<GUISkin>(BhapticsSettingWindowAssets.GUISkin);
|
||||
|
||||
InitializeGUIStyles(bHapticsSkin);
|
||||
|
||||
isValidState = settings.LastDeployVersion > 0;
|
||||
|
||||
OnChangePage += ResetOnChangePage;
|
||||
|
||||
BhapticsLibrary.Initialize(settings.AppId, settings.ApiKey, settings.DefaultDeploy);
|
||||
BhapticsLibrary.IsBhapticsAvailable(true);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
BhapticsLibrary.Destroy();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
GUI.DrawTexture(new Rect(0f, 0f, WindowWidth, WindowHeight), whiteImage);
|
||||
|
||||
if (!isValidState)
|
||||
{
|
||||
DrawSetupPage();
|
||||
|
||||
ResetMainPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawAppTitle();
|
||||
|
||||
DrawNavigationTap();
|
||||
|
||||
DrawMainPage();
|
||||
}
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
DelayRepaint();
|
||||
}
|
||||
|
||||
#region Initialize Method
|
||||
private void InitializeImages()
|
||||
{
|
||||
whiteImage = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.WhiteImage, typeof(Texture2D));
|
||||
latestDeployedVersionBox = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.LatestDeployedVersionBox, typeof(Texture2D));
|
||||
homeIcon = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.HomeIcon, typeof(Texture2D));
|
||||
hapticEventsIcon = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.EventsIcon, typeof(Texture2D));
|
||||
documentationIcon = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.DocumentationIcon, typeof(Texture2D));
|
||||
homeSelectedIcon = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.HomeSelectedIcon, typeof(Texture2D));
|
||||
hapticEventsSelectedIcon = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.EventsSelectedIcon, typeof(Texture2D));
|
||||
documentationSelectedIcon = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.DocumentationSelectedIcon, typeof(Texture2D));
|
||||
sampleGuidesImage = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.SampleGuidesImage, typeof(Texture2D));
|
||||
appIdApiKeyOutlineImage = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.AppIdApiKeyOutlineImage, typeof(Texture2D));
|
||||
eventsButtonAudioIcon = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.EventsButtonAudioIcon, typeof(Texture2D));
|
||||
unityDocumentationImage = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.UnityDocumentationImage, typeof(Texture2D));
|
||||
bHapticsDocumentationImage = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.BhapticsDocumentationImage, typeof(Texture2D));
|
||||
metaQuest2DocumentationImage = (Texture2D)Resources.Load(BhapticsSettingWindowAssets.MetaQuest2DocumentationImage, typeof(Texture2D));
|
||||
}
|
||||
|
||||
private void InitializeGUIStyles(GUISkin targetSkin)
|
||||
{
|
||||
tempAreaStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.TempAreaStyle));
|
||||
|
||||
fontBoldStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.FontBold));
|
||||
fontMediumStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.FontMedium));
|
||||
fontRegularStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.FontRegular));
|
||||
fontLightStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.FontLight));
|
||||
divideStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.DivideStyle));
|
||||
navigationButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.NavigationButtonStyle));
|
||||
selectedNavigationButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.SelectedNavigationButtonStyle));
|
||||
setupInputFieldStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.SetupInputFieldStyle));
|
||||
setupButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.SetupButtonStyle));
|
||||
visitTextButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.VisitTextButtonStyle));
|
||||
visitButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.VisitButtonStyle));
|
||||
resetButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.ResetButtonStyle));
|
||||
hapticEventsButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.HapticEventsButtonStyle));
|
||||
setupErrorTextStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.SetupErrorTextStyle));
|
||||
appTitleTextStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.AppTitleTextStyle));
|
||||
blackBackgroundStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.BlackBackgroundStyle));
|
||||
latestDeployedVersionTextStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.LatestDeployedVersionTextStyle));
|
||||
refreshDeployedVersionButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.RefreshDeployedVersionButtonStyle));
|
||||
mainTapTitleStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.MainTapTitleStyle));
|
||||
sampleGuideButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.SampleGuideButtonStyle));
|
||||
copyClipboardButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.CopyClipboardButtonStyle));
|
||||
viewAllTextStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.ViewAllTextStyle));
|
||||
eventsButtonDetailStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.EventsButtonDetailStyle));
|
||||
eventsButtonDetailSelectedStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.EventsButtonDetailSelectedStyle));
|
||||
eventsButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.EventsButtonStyle));
|
||||
eventsButtonSelectedStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.EventsButtonSelectedStyle));
|
||||
eventsButtonTitleStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.EventsButtonTitleStyle));
|
||||
eventsButtonDeviceStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.EventsButtonDeviceStyle));
|
||||
eventsButtonDurationStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.EventsButtonDurationStyle));
|
||||
documentationButtonStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.DocumentationButtonStyle));
|
||||
lastUpdatedToggleStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.LastUpdatedToggleStyle));
|
||||
lastUpdatedToggleSelectedStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.LastUpdatedToggleSelectedStyle));
|
||||
aZToggleStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.AZToggleStyle));
|
||||
aZToggleSelectedStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.AZToggleSelectedStyle));
|
||||
viewGridStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.ViewGridStyle));
|
||||
viewGridSelectedStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.ViewGridSelectedStyle));
|
||||
viewListStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.ViewListStyle));
|
||||
viewListSelectedStyle = new GUIStyle(GetCustomGUIStyle(targetSkin, BhapticsSettingWindowAssets.ViewListSelectedStyle));
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void DrawSetupPage()
|
||||
{
|
||||
GUILayout.BeginArea(new Rect(295f, 122f, 410f, 402f));
|
||||
|
||||
var originCursorFlashSpeed = GUI.skin.settings.cursorFlashSpeed;
|
||||
GUI.skin.settings.cursorFlashSpeed = bHapticsSkin.settings.cursorFlashSpeed;
|
||||
|
||||
GUILayout.Label("Setup", new GUIStyle(fontBoldStyle) { fontSize = 24 }, GUILayout.Height(36f));
|
||||
GUILayout.Space(40f);
|
||||
|
||||
GUILayout.Label("App ID", new GUIStyle(fontBoldStyle) { fontSize = 14 });
|
||||
GUILayout.Space(14f);
|
||||
appIdProperty.stringValue = EditorGUILayout.TextField(appIdProperty.stringValue, setupInputFieldStyle, GUILayout.Height(setupInputFieldStyle.fixedHeight));
|
||||
if (appIdProperty.stringValue.Equals(string.Empty))
|
||||
{
|
||||
GUI.Label(new Rect(14f, 124f, 111f, 18f), "<color=#cccccc>Enter your App ID</color>", new GUIStyle(fontRegularStyle) { fontSize = 14 });
|
||||
}
|
||||
|
||||
GUILayout.Space(14f);
|
||||
|
||||
GUILayout.Label("API Key", new GUIStyle(fontBoldStyle) { fontSize = 14 });
|
||||
GUILayout.Space(14f);
|
||||
apiKeyProperty.stringValue = EditorGUILayout.TextField(apiKeyProperty.stringValue, setupInputFieldStyle, GUILayout.Height(setupInputFieldStyle.fixedHeight));
|
||||
if (apiKeyProperty.stringValue.Equals(string.Empty))
|
||||
{
|
||||
GUI.Label(new Rect(14f, 220f, 111f, 18f), "<color=#cccccc>Enter your API Key</color>", new GUIStyle(fontRegularStyle) { fontSize = 14 });
|
||||
}
|
||||
|
||||
if (!setupErrorText.Equals(string.Empty))
|
||||
{
|
||||
GUILayout.Space(10f);
|
||||
GUILayout.Label(setupErrorText, setupErrorTextStyle);
|
||||
GUILayout.Space(22f);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Space(50f);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("LINK", setupButtonStyle))
|
||||
{
|
||||
GetAppSettings(out setupErrorText);
|
||||
}
|
||||
|
||||
GUILayout.Space(20f);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(138f - 12f);
|
||||
|
||||
if (GUILayout.Button("Forgot your App ID & API Key?", visitTextButtonStyle, GUILayout.Width(138f + 12f), GUILayout.Height(18f)))
|
||||
{
|
||||
Application.OpenURL("https://developer.bhaptics.com");
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUI.skin.settings.cursorFlashSpeed = originCursorFlashSpeed;
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private void DrawAppTitle()
|
||||
{
|
||||
GUILayout.BeginArea(new Rect(0f, 0f, WindowWidth, 54f), blackBackgroundStyle);
|
||||
|
||||
GUILayout.Space(15f);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(20f);
|
||||
GUILayout.Label(settings.AppName, appTitleTextStyle);
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(" ", visitButtonStyle))
|
||||
{
|
||||
Application.OpenURL("https://developer.bhaptics.com");
|
||||
}
|
||||
GUILayout.Space(20f);
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private void DrawNavigationTap()
|
||||
{
|
||||
GUILayout.BeginArea(new Rect(10f, 74f, 230f, 455f));
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
if (DrawNavigationButton("Home", NavigationButtonType.Home))
|
||||
{
|
||||
SelectNavigationButton(NavigationButtonType.Home);
|
||||
}
|
||||
|
||||
if (DrawNavigationButton("Events", NavigationButtonType.Events))
|
||||
{
|
||||
sortedEventData = GetSortedEventData(0);
|
||||
SelectNavigationButton(NavigationButtonType.Events);
|
||||
}
|
||||
|
||||
if (DrawNavigationButton("Documentation", NavigationButtonType.Documentation))
|
||||
{
|
||||
SelectNavigationButton(NavigationButtonType.Documentation);
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndArea();
|
||||
|
||||
GUILayout.BeginArea(new Rect(20f, 529f, 220f, 120f));
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
GUILayout.Label("", divideStyle);
|
||||
GUILayout.Space(10f);
|
||||
|
||||
GUI.DrawTexture(new Rect(0f, 10f, 220f, 42f), latestDeployedVersionBox);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(159f);
|
||||
GUILayout.Label(settings.LastDeployVersion.ToString(), latestDeployedVersionTextStyle);
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(new GUIContent("", "Refresh"), refreshDeployedVersionButtonStyle))
|
||||
{
|
||||
if (GetAppSettings(out setupErrorText) != 0)
|
||||
{
|
||||
ResetAppSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
BhapticsLibrary.EditorReInitialize(settings.AppId, settings.ApiKey, settings.DefaultDeploy);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(4f);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(22f);
|
||||
|
||||
if (GUILayout.Button("", resetButtonStyle))
|
||||
{
|
||||
ResetAppSettings();
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private GUIStyle GetCustomGUIStyle(GUISkin targetSkin, string styleName)
|
||||
{
|
||||
for (int i = 0; i < targetSkin.customStyles.Length; ++i)
|
||||
{
|
||||
if (targetSkin.customStyles[i].name.Equals(styleName))
|
||||
{
|
||||
return targetSkin.customStyles[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void DelayRepaint()
|
||||
{
|
||||
var timeSinceStartup = Time.realtimeSinceStartup;
|
||||
if (Event.current.type == EventType.MouseMove && timeSinceStartup > nextForceRepaint)
|
||||
{
|
||||
nextForceRepaint = timeSinceStartup + .05f;
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetMainPage()
|
||||
{
|
||||
SelectedNavigationButtionType = NavigationButtonType.Home;
|
||||
CurrentEventsScrollPos = Vector2.zero;
|
||||
IsViewGrid = true;
|
||||
IsSortLastUpdated = false;
|
||||
sortedEventData = null;
|
||||
}
|
||||
|
||||
private bool DrawNavigationButton(string title, NavigationButtonType buttonType)
|
||||
{
|
||||
bool isSelected = SelectedNavigationButtionType == buttonType;
|
||||
Texture2D targetIcon = homeIcon;
|
||||
GUIStyle targetStyle = isSelected ? selectedNavigationButtonStyle : navigationButtonStyle;
|
||||
|
||||
switch (buttonType)
|
||||
{
|
||||
case NavigationButtonType.Home:
|
||||
targetIcon = isSelected ? homeSelectedIcon : homeIcon;
|
||||
break;
|
||||
case NavigationButtonType.Events:
|
||||
targetIcon = isSelected ? hapticEventsSelectedIcon : hapticEventsIcon;
|
||||
break;
|
||||
case NavigationButtonType.Documentation:
|
||||
targetIcon = isSelected ? documentationSelectedIcon : documentationIcon;
|
||||
break;
|
||||
}
|
||||
|
||||
return GUILayout.Button(new GUIContent(" " + title, targetIcon), targetStyle);
|
||||
}
|
||||
|
||||
private void SelectNavigationButton(NavigationButtonType targetType)
|
||||
{
|
||||
if (!SelectedNavigationButtionType.Equals(targetType))
|
||||
{
|
||||
OnChangePage?.Invoke();
|
||||
}
|
||||
|
||||
SelectedNavigationButtionType = targetType;
|
||||
}
|
||||
|
||||
private void DrawMainPage()
|
||||
{
|
||||
GUILayout.BeginArea(new Rect(280f, 90f, 720f, 560f));
|
||||
|
||||
switch (SelectedNavigationButtionType)
|
||||
{
|
||||
case NavigationButtonType.Home:
|
||||
ShowHomeTap();
|
||||
break;
|
||||
case NavigationButtonType.Events:
|
||||
ShowHapticEventsTap();
|
||||
break;
|
||||
case NavigationButtonType.Documentation:
|
||||
ShowDocumentationTap();
|
||||
break;
|
||||
}
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private void ShowHomeTap()
|
||||
{
|
||||
GUILayout.Space(4f);
|
||||
GUILayout.Label("Welcome to bHaptics SDK2 !", mainTapTitleStyle);
|
||||
|
||||
GUILayout.BeginArea(new Rect(0f, 40f, 350f, 176f));
|
||||
GUI.DrawTexture(new Rect(0f, 0f, 350f, 176f), sampleGuidesImage);
|
||||
|
||||
GUILayout.Label("How to start",
|
||||
new GUIStyle(fontBoldStyle)
|
||||
{
|
||||
fontSize = 16,
|
||||
padding = new RectOffset(20, 0, 20, 0)
|
||||
});
|
||||
|
||||
GUILayout.Label("<color=#646464>It is recommended that you view the\nGuide documentation before you begin.</color>",
|
||||
new GUIStyle(fontRegularStyle)
|
||||
{
|
||||
fontSize = 14,
|
||||
wordWrap = true,
|
||||
padding = new RectOffset(20, 0, 10, 0)
|
||||
});
|
||||
GUILayout.Space(24f);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Developer Portal Guide", sampleGuideButtonStyle, GUILayout.Width(160f)))
|
||||
{
|
||||
Application.OpenURL(DeveloperPortalGuideUrl);
|
||||
}
|
||||
|
||||
GUILayout.Space(10f);
|
||||
|
||||
if (GUILayout.Button("Unity SDK2 Guide", sampleGuideButtonStyle, GUILayout.Width(140f)))
|
||||
{
|
||||
Application.OpenURL(UnityHowToStartUrl);
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndArea();
|
||||
|
||||
DrawAppIdApiKeyButton(new Rect(360f, 40f, 320f, 176f), "App ID", settings.AppId);
|
||||
GUILayout.Space(10f);
|
||||
DrawAppIdApiKeyButton(new Rect(360f, 133f, 320f, 176f), "API Key", settings.ApiKey);
|
||||
|
||||
GUILayout.BeginArea(new Rect(0f, 250f, 680f, 24f));
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Events", mainTapTitleStyle);
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("View All", viewAllTextStyle))
|
||||
{
|
||||
SelectNavigationButton(NavigationButtonType.Events);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndArea();
|
||||
|
||||
GUILayout.BeginArea(new Rect(0f, 284f, 680f, 236f));
|
||||
|
||||
if (settings.EventData != null)
|
||||
{
|
||||
int startIndex = 0;
|
||||
int endIndex = settings.EventData.Length > 3 ? startIndex + 3 : settings.EventData.Length;
|
||||
|
||||
for (int i = startIndex; i < endIndex; ++i)
|
||||
{
|
||||
DrawEventsButtonDetail(i, settings.EventData[i]);
|
||||
if (i != endIndex - 1)
|
||||
{
|
||||
GUILayout.Space(10f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndArea();
|
||||
|
||||
}
|
||||
|
||||
private void ShowHapticEventsTap()
|
||||
{
|
||||
if (settings.EventData == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Space(4f);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Events", new GUIStyle(mainTapTitleStyle) { fontSize = 22, });
|
||||
GUILayout.Space(6f);
|
||||
GUILayout.Label("<color=#959595>" + settings.EventData.Length.ToString() + "</color>",
|
||||
new GUIStyle(fontMediumStyle)
|
||||
{
|
||||
fontSize = 16,
|
||||
margin = new RectOffset(0, 0, 3, 0)
|
||||
});
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label("<color=#646464>Sortby:</color>",
|
||||
new GUIStyle(fontRegularStyle)
|
||||
{
|
||||
fontSize = 13,
|
||||
margin = new RectOffset(0, 0, 5, 0)
|
||||
});
|
||||
GUILayout.Space(10f);
|
||||
if (GUILayout.Button("", IsSortLastUpdated ? aZToggleStyle : aZToggleSelectedStyle))
|
||||
{
|
||||
IsSortLastUpdated = false;
|
||||
sortedEventData = GetSortedEventData(1);
|
||||
}
|
||||
GUI.Label(new Rect(452f, 9f, 79f, 16f), "A-Z", new GUIStyle(fontRegularStyle) { fontSize = 13 });
|
||||
GUILayout.Space(10f);
|
||||
if (GUILayout.Button("", IsSortLastUpdated ? lastUpdatedToggleSelectedStyle : lastUpdatedToggleStyle))
|
||||
{
|
||||
IsSortLastUpdated = true;
|
||||
sortedEventData = GetSortedEventData(0);
|
||||
}
|
||||
GUI.Label(new Rect(509f, 9f, 79f, 16f), "Last Updated", new GUIStyle(fontRegularStyle) { fontSize = 13 });
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Space(20f);
|
||||
if (GUILayout.Button("", IsViewGrid ? viewGridSelectedStyle : viewGridStyle))
|
||||
{
|
||||
IsViewGrid = true;
|
||||
}
|
||||
GUILayout.Space(4f);
|
||||
if (GUILayout.Button("", IsViewGrid ? viewListStyle : viewListSelectedStyle))
|
||||
{
|
||||
IsViewGrid = false;
|
||||
}
|
||||
|
||||
GUILayout.Space(40f);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(IsViewGrid ? 16f : 26f);
|
||||
|
||||
var originVerticalScrollbar = GUI.skin.verticalScrollbar;
|
||||
var originVerticalScrollbarUpButton = GUI.skin.verticalScrollbarUpButton;
|
||||
var originVerticalScrollbarDownButton = GUI.skin.verticalScrollbarDownButton;
|
||||
var originVerticalScrollbarThumb = GUI.skin.verticalScrollbarThumb;
|
||||
|
||||
GUI.skin.verticalScrollbar = bHapticsSkin.verticalScrollbar;
|
||||
GUI.skin.verticalScrollbarUpButton = bHapticsSkin.verticalScrollbarUpButton;
|
||||
GUI.skin.verticalScrollbarDownButton = bHapticsSkin.verticalScrollbarDownButton;
|
||||
GUI.skin.verticalScrollbarThumb = bHapticsSkin.verticalScrollbarThumb;
|
||||
|
||||
try
|
||||
{
|
||||
CurrentEventsScrollPos = GUILayout.BeginScrollView(CurrentEventsScrollPos, GUILayout.Width(695f));
|
||||
|
||||
var targetEventNames = sortedEventData;
|
||||
for (int i = 0; i < targetEventNames.Length; ++i)
|
||||
{
|
||||
if (IsViewGrid)
|
||||
{
|
||||
DrawEventsButton(i, targetEventNames[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawEventsButtonDetail(i, targetEventNames[i]);
|
||||
}
|
||||
|
||||
if (i != targetEventNames.Length - 1)
|
||||
{
|
||||
GUILayout.Space(10f);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(10f);
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
catch
|
||||
{
|
||||
sortedEventData = GetSortedEventData(0);
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
GUI.skin.verticalScrollbar = originVerticalScrollbar;
|
||||
GUI.skin.verticalScrollbarUpButton = originVerticalScrollbarUpButton;
|
||||
GUI.skin.verticalScrollbarDownButton = originVerticalScrollbarDownButton;
|
||||
GUI.skin.verticalScrollbarThumb = originVerticalScrollbarThumb;
|
||||
}
|
||||
|
||||
|
||||
private void ShowDocumentationTap()
|
||||
{
|
||||
GUILayout.Space(4f);
|
||||
GUILayout.Label("Documentation", new GUIStyle(mainTapTitleStyle) { fontSize = 22 });
|
||||
|
||||
GUILayout.BeginArea(new Rect(0f, 60f, 720f, 570f));
|
||||
DrawDocumentationButton(GetDocumentationButtonPos(0), DocumentationButtonType.bHaptics, "Create haptic events", "(bHaptics Developer Portal)", DeveloperPortalGuideUrl);
|
||||
DrawDocumentationButton(GetDocumentationButtonPos(1), DocumentationButtonType.Unity, "Plug in deployed events to Unity", "(Unity)", UnityHowToStartUrl);
|
||||
DrawDocumentationButton(GetDocumentationButtonPos(2), DocumentationButtonType.Unity, "How to migrate from SDK1(old) to SDK2(new)", "(Unity)", UnityMigrateUrl);
|
||||
//DrawDocumentationButton(GetDocumentationButtonPos(3), DocumentationButtonType.MetaQuest2, "Getting Started", "(Unity Meta Quest2)");
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private void ResetAppSettings()
|
||||
{
|
||||
BhapticsSettings.ResetInstance();
|
||||
isValidState = false;
|
||||
}
|
||||
|
||||
private int GetAppSettings(out string errorMessage)
|
||||
{
|
||||
var json = BhapticsLibrary.EditorGetSettings(appIdProperty.stringValue, apiKeyProperty.stringValue, -1, out int code);
|
||||
if (code == 0)
|
||||
{
|
||||
var events = BhapticsLibrary.EditorGetEventList(appIdProperty.stringValue, apiKeyProperty.stringValue, -1, out code);
|
||||
if (code == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rawMessage = DeployHttpMessage.CreateFromJSON(json);
|
||||
var message = rawMessage.message;
|
||||
if (message.version > 0)
|
||||
{
|
||||
settings.AppName = message.name;
|
||||
settings.AppId = appIdProperty.stringValue;
|
||||
settings.ApiKey = apiKeyProperty.stringValue;
|
||||
settings.LastDeployVersion = message.version;
|
||||
settings.DefaultDeploy = json;
|
||||
|
||||
var eventNames = new string[events.Count];
|
||||
var eventDataArr = new MappingMetaData[events.Count];
|
||||
for (var i = 0; i < events.Count; i++)
|
||||
{
|
||||
eventNames[i] = events[i].key;
|
||||
eventDataArr[i] = events[i];
|
||||
}
|
||||
settings.EventData = eventDataArr;
|
||||
|
||||
errorMessage = string.Empty;
|
||||
isValidState = settings.LastDeployVersion > 0;
|
||||
|
||||
BhapticsEventGenerator.CreateEventCsFile("BhapticsEvent", eventNames);
|
||||
EditorUtility.SetDirty(settings);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
else
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] Not Valid format.");
|
||||
errorMessage = "Not Valid format";
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] Exception: {0}", e.Message);
|
||||
errorMessage = "Exception: " + e.Message;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
BhapticsLogManager.LogErrorFormat("[bHaptics] Error: {0}", BhapticsHelpers.ErrorCodeToMessage(code));
|
||||
errorMessage = BhapticsHelpers.ErrorCodeToMessage(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
private void DrawAppIdApiKeyButton(Rect areaRect, string title, string value)
|
||||
{
|
||||
GUILayout.BeginArea(areaRect);
|
||||
|
||||
GUI.DrawTexture(new Rect(0f, 0f, 320f, 83f), appIdApiKeyOutlineImage);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(20f);
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Space(22f);
|
||||
GUILayout.Label(title, new GUIStyle(fontBoldStyle) { fontSize = 14 });
|
||||
GUILayout.Space(6f);
|
||||
|
||||
var valueStyle = new GUIStyle(fontLightStyle);
|
||||
valueStyle.normal.textColor = new Color(0f, 0f, 0f, 0.8f);
|
||||
valueStyle.fontSize = 13;
|
||||
GUILayout.Label(value, valueStyle);
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
if (GUILayout.Button("", copyClipboardButtonStyle))
|
||||
{
|
||||
GUIUtility.systemCopyBuffer = value;
|
||||
BhapticsLogManager.LogFormat("[bHaptics] Copy to Clipboard: {0}", value);
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Space(20f);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private void DrawEventsButtonDetail(int index, MappingMetaData eventData)
|
||||
{
|
||||
if (GUILayout.Button("", eventData.Equals(selectedEvent) ? eventsButtonDetailSelectedStyle : eventsButtonDetailStyle))
|
||||
{
|
||||
selectedEvent = eventData;
|
||||
|
||||
BhapticsLibrary.StopAll();
|
||||
BhapticsLibrary.Play(eventData.key);
|
||||
}
|
||||
|
||||
float additionalHeight = index * EventsButtonDetailHeight + index * EventsButtonSpacing;
|
||||
|
||||
GUI.Label(new Rect(64f, additionalHeight + 16f, 480f, 18f), eventData.key, eventsButtonTitleStyle);
|
||||
|
||||
string deviceString = ConvertOrderToDeviceType(eventData.positions);
|
||||
GUI.Label(new Rect(64f, additionalHeight + 44f, 500f, 12f), deviceString.TrimEnd(), eventsButtonDeviceStyle);
|
||||
|
||||
if (eventData.isAudio)
|
||||
{
|
||||
GUI.Label(new Rect(569f, additionalHeight + 28f, 40f * 1.2f, 16f * 1.2f), eventsButtonAudioIcon);
|
||||
}
|
||||
|
||||
GUI.Label(new Rect(629f, additionalHeight + 29f, 32f, 14f), (eventData.durationMillis * 0.001f).ToString("0.00") + " s", eventsButtonDurationStyle);
|
||||
}
|
||||
|
||||
private void DrawEventsButton(int index, MappingMetaData eventData)
|
||||
{
|
||||
int mtp1 = index % 2;
|
||||
int mtp2 = index / 2;
|
||||
|
||||
if (mtp1 == 0)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("", eventData.Equals(selectedEvent) ? eventsButtonSelectedStyle : eventsButtonStyle))
|
||||
{
|
||||
selectedEvent = eventData;
|
||||
|
||||
BhapticsLibrary.StopAll();
|
||||
BhapticsLibrary.Play(eventData.key);
|
||||
}
|
||||
|
||||
float additionalWidth = mtp1 * EventsButtonWidth + mtp1 * EventsButtonSpacing;
|
||||
float additionalHeight = mtp2 * EventsButtonHeight + mtp2 * EventsButtonSpacing;
|
||||
|
||||
GUI.Label(new Rect(additionalWidth + 16f, additionalHeight + 12f, 256f, 36f), eventData.key, eventsButtonTitleStyle);
|
||||
|
||||
string deviceString = ConvertOrderToDeviceType(eventData.positions);
|
||||
GUI.Label(new Rect(additionalWidth + 16f, additionalHeight + 54f, 310f, 26f), deviceString.TrimEnd(), eventsButtonDeviceStyle);
|
||||
|
||||
if (mtp1 == 1 || index == settings.EventData.Length - 1)
|
||||
{
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 GetDocumentationButtonPos(int index)
|
||||
{
|
||||
return new Vector2(0f, index * DocumentationButtonHeight + index * DocumentationButtonSpacing);
|
||||
}
|
||||
|
||||
private Texture2D GetDocumentationImage(DocumentationButtonType buttonType)
|
||||
{
|
||||
switch (buttonType)
|
||||
{
|
||||
case DocumentationButtonType.Unity:
|
||||
return unityDocumentationImage;
|
||||
|
||||
case DocumentationButtonType.bHaptics:
|
||||
return bHapticsDocumentationImage;
|
||||
|
||||
case DocumentationButtonType.MetaQuest2:
|
||||
return metaQuest2DocumentationImage;
|
||||
}
|
||||
|
||||
return unityDocumentationImage;
|
||||
}
|
||||
|
||||
private void DrawDocumentationButton(Vector2 pos, DocumentationButtonType buttonType, string mainText, string subText, string url)
|
||||
{
|
||||
GUILayout.BeginArea(new Rect(pos.x, pos.y, DocumentationButtonWidth, DocumentationButtonHeight));
|
||||
|
||||
var imageStyle = new GUIStyle();
|
||||
imageStyle.normal.background = GetDocumentationImage(buttonType);
|
||||
GUI.Label(new Rect(0f, 0f, 130f, 70f), "", imageStyle);
|
||||
|
||||
GUI.Label(new Rect(144f, 26f, 436f, 18f), mainText + " " + "<color=#959595>" + subText + "</color>", new GUIStyle(fontRegularStyle) { fontSize = 14 });
|
||||
|
||||
if (GUILayout.Button("", documentationButtonStyle))
|
||||
{
|
||||
if (url == string.Empty)
|
||||
{
|
||||
BhapticsLogManager.Log("[bHaptics] To be continue...");
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.OpenURL(url);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private MappingMetaData[] GetSortedEventData(int sortType)
|
||||
{
|
||||
if (settings.EventData == null)
|
||||
{
|
||||
return new MappingMetaData[0];
|
||||
}
|
||||
|
||||
MappingMetaData[] res = null;
|
||||
|
||||
var tempEventList = new List<MappingMetaData>();
|
||||
tempEventList.AddRange(settings.EventData);
|
||||
if (sortType == 0)
|
||||
{
|
||||
tempEventList.Sort(SortByUpdateTime);
|
||||
tempEventList.Reverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
tempEventList.Sort(SortByName);
|
||||
}
|
||||
|
||||
res = tempEventList.ToArray();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private void ResetOnChangePage()
|
||||
{
|
||||
selectedEvent = null;
|
||||
}
|
||||
|
||||
private int SortByUpdateTime(MappingMetaData x, MappingMetaData y)
|
||||
{
|
||||
return x.updateTime.CompareTo(y.updateTime);
|
||||
}
|
||||
|
||||
private int SortByName(MappingMetaData x, MappingMetaData y)
|
||||
{
|
||||
return x.key.CompareTo(y.key);
|
||||
}
|
||||
|
||||
private string ConvertOrderToDeviceType(string[] deviceArr)
|
||||
{
|
||||
string res = "";
|
||||
string interval = " ";
|
||||
string[] deviceListStr = new string[] { "Face", "Vest", "Arms", "Hands", "Feet", "Glove" };
|
||||
bool[] useDeviceArr = new bool[deviceListStr.Length];
|
||||
|
||||
for (int i = 0; i < deviceArr.Length; ++i)
|
||||
{
|
||||
for (int di = 0; di < deviceListStr.Length; ++di)
|
||||
{
|
||||
if (deviceArr[i].Contains(deviceListStr[di]))
|
||||
{
|
||||
useDeviceArr[di] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < useDeviceArr.Length; ++i)
|
||||
{
|
||||
if (useDeviceArr[i])
|
||||
{
|
||||
res += deviceListStr[i] + interval;
|
||||
}
|
||||
}
|
||||
|
||||
return res.Trim();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 739f6e78fe788644bb5e74725fe9e6d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,70 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
|
||||
namespace Bhaptics.SDK2.Editor
|
||||
{
|
||||
public class BhapticsSettingWindowAssets
|
||||
{
|
||||
public static string GUISkin = "bHapticsGUISkin";
|
||||
|
||||
public static string FontBold = "FontBold";
|
||||
public static string FontMedium = "FontMedium";
|
||||
public static string FontRegular = "FontRegular";
|
||||
public static string FontLight = "FontLight";
|
||||
public static string LabelStyle = "label";
|
||||
public static string DivideStyle = "Divide";
|
||||
public static string NavigationButtonStyle = "NavigationButton";
|
||||
public static string SelectedNavigationButtonStyle = "SelectedNavigationButton";
|
||||
public static string TempAreaStyle = "TEMP";
|
||||
public static string SetupButtonStyle = "SetupButton";
|
||||
public static string SetupInputFieldStyle = "SetupInputField";
|
||||
public static string VisitButtonStyle = "VisitButton";
|
||||
public static string VisitTextButtonStyle = "VisitTextButton";
|
||||
public static string ResetButtonStyle = "ResetButton";
|
||||
public static string HapticEventsButtonStyle = "HapticEventsButton";
|
||||
public static string SetupErrorTextStyle = "SetupErrorText";
|
||||
public static string AppTitleTextStyle = "AppTitleText";
|
||||
public static string BlackBackgroundStyle = "BlackBackground";
|
||||
public static string LatestDeployedVersionTextStyle = "LatestDeployedVersionText";
|
||||
public static string RefreshDeployedVersionButtonStyle = "RefreshDeployedVersionButton";
|
||||
public static string MainTapTitleStyle = "MainTapTitle";
|
||||
public static string SampleGuideButtonStyle = "SampleGuideButton";
|
||||
public static string CopyClipboardButtonStyle = "CopyClipboardButton";
|
||||
public static string ViewAllTextStyle = "ViewAllText";
|
||||
public static string EventsButtonDetailStyle = "EventsButtonDetail";
|
||||
public static string EventsButtonDetailSelectedStyle = "EventsButtonDetailSelected";
|
||||
public static string EventsButtonStyle = "EventsButton";
|
||||
public static string EventsButtonSelectedStyle = "EventsButtonSelected";
|
||||
public static string EventsButtonTitleStyle = "EventsButtonTitle";
|
||||
public static string EventsButtonDeviceStyle = "EventsButtonDevice";
|
||||
public static string EventsButtonDurationStyle = "EventsButtonDuration";
|
||||
public static string DocumentationButtonStyle = "DocumentationButton";
|
||||
public static string LastUpdatedToggleStyle = "LastUpdatedToggle";
|
||||
public static string LastUpdatedToggleSelectedStyle = "LastUpdatedToggleSelected";
|
||||
public static string AZToggleStyle = "AZToggle";
|
||||
public static string AZToggleSelectedStyle = "AZToggleSelected";
|
||||
public static string ViewGridStyle = "ViewGrid";
|
||||
public static string ViewGridSelectedStyle = "ViewGridSelected";
|
||||
public static string ViewListStyle = "ViewList";
|
||||
public static string ViewListSelectedStyle = "ViewListSelected";
|
||||
|
||||
public static string HomeIcon = "icons/icon-home-def";
|
||||
public static string HomeSelectedIcon = "icons/icon-home-fill";
|
||||
public static string EventsIcon = "icons/icon-event-def";
|
||||
public static string EventsSelectedIcon = "icons/icon-event-fill";
|
||||
public static string DocumentationIcon = "icons/icon-documentation-def";
|
||||
public static string DocumentationSelectedIcon = "icons/icon-documentation-fill";
|
||||
public static string WhiteImage = "WhiteBackground";
|
||||
public static string BlackBackground = "BlackBackground";
|
||||
public static string LatestDeployedVersionBox = "LatestDeployedVersionBox";
|
||||
public static string SampleGuidesImage = "sample-guides-background";
|
||||
public static string AppIdApiKeyOutlineImage = "outline-appId-apiKey";
|
||||
public static string EventsButtonAudioIcon = "icons/icon-events-audio";
|
||||
public static string UnityDocumentationImage = "img-documentation-unity-def";
|
||||
public static string BhapticsDocumentationImage = "img-documentation-bhaptics-def";
|
||||
public static string MetaQuest2DocumentationImage = "img-documentation-meta-def";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f388c59f103d5c744b9a44df01b3fa17
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,18 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Bhaptics.SDK2
|
||||
{
|
||||
[CustomEditor(typeof(BhapticsSettings))]
|
||||
public class BhapticsSettingsEditor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
GUI.enabled = false;
|
||||
base.OnInspectorGUI();
|
||||
GUI.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dedd661db77da6d42bccea01b15b1e87
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue