Unity Universal Plugin For Remote
Introduction
This Unity plugin can establish communication with the Lovense Remote App available on the LAN to send toy control commands.
Note: Android and iOS Remote App requires "Game Mode" to be enabled, PC Remote App requires "Allow Control" to be enabled.
Compatibility
Unity version: >= 2018.4.0
Api Compatibility Level:
- For
.Net 4.x
, the import package name isremotePlugin_.Net4.x.unitypackage
. - For
.Net Framework
, the import package name isremotePlugin_.NetFramework.unitypackage
. - For
.Net Standard 2.0
, the import package name isremotePlugin_.NetStandard2.0.unitypackage
. - For
.Net Standard 2.1
, the import package name isremotePlugin_.NetStandard2.1.unitypackage
.
Import the plugin
Download the plugin package from here. The latest version of the current plugin is V1.8 click to view version records
remotePlugin_.Net4.x.unitypackage
remotePlugin_.NetFramework.unitypackage
Import the appropriate package based on your project's Api Compatibility Level.
Select all options and click import.
The file Assets/StreamingAssets/LovenseToySupportConfig.json is the configuration file for the toy support directive, and the version field represents the version of the information.
The current latest version is 1.4
. If it is older than this version, it is recommended to download and replace the file.
Dowload: LovenseToySupportConfig.json
The LovenseDemo folder is an example that you can refer to. Removing it won't affect the functionality.
Guide
1. Search for the local LAN Lovense Remote.
public class YourLovenseToyUI: MonoBehaviour {
// do search
private void DoSearch() {
LovenseRemote.GetInstance().SearchRemoteApp();
}
//callback function, parames is List<RemoteAppData>
private void OnSearchLocalApp(List<RemoteAppData> appDatas) {
// Show the Lovense Remote search result in the UI
}
private void OnGetAppsError(string errorMsg) {
//when get apps error
}
void Awake(){
// Add listener
LovenseRemote.onGetAppsEvent.AddListener(OnSearchLocalApp);
LovenseRemote.onGetAppsErrorEvent.AddListener(OnGetAppsError);
}
void OnDestory() {
// Remove listener
LovenseRemote.onGetAppsEvent.RemoveListener(OnSearchLocalApp);
LovenseRemote.onGetAppsErrorEvent.RemoveListener(OnGetAppsError);
}
}
2. List toys based on the specified IP and port
public class YourLovenseToyUI: MonoBehaviour {
//do search toys
private void DoSearchToys(string domain,int port) {
//The default value of useHttps is true, if set value to false, http will be used for data transfer.
LovenseRemote.GetInstance().GetToys(domin,post[,useHttps=true]);
}
private void OnGetToys(List<LovenseRemoteToy> toys) {
//when get toys
}
private void OnGetToysError(string errorMsg) {
//when get toys error
}
void Awake() {
// Add listener
LovenseRemote.onGotToysEvent.AddListener(OnGetToys);
LovenseRemote.onGetToysErrorEvent.AddListener(OnGetToysError);
}
void OnDestroy() {
// Remove listener
LovenseRemote.onGotToysEvent.AddListener(OnGetToys);
LovenseRemote.onGetToysErrorEvent.AddListener(OnGetToysError);
}
}
3. Send commands
3.1 Send functions commands
public class YourLovenseToyUI : MonoBehaviour {
private void DoSendCommands(List<LovenseRemoteToy> toys, List<LovenseCommand> commands, float timeSec, float loopRunningSec , float loopPauseSec,int stopPrevious, ) {
LovenseRemote.GetInstance().SendFunctions(toys,commands,timeSec[,loopRunningSec,loopPauseSec,stopPrevious]);
}
private void OnControlToysResult(string toyId,ControlToysResult result){
//...
}
void Awake() {
// Add listener
LovenseRemote.onControlToysEvent.AddListener(OnControlToysResult);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.onControlToysEvent.RemoveListener(OnControlToysResult);
}
}
3.2 Send pattern commands
public class YourLovenseToyUI : MonoBehaviour {
private void DoSendPattern(List<LovenseRemoteToy> toys, List<LovenseCommandType> types, List<int> strengthValues, float timeSec,int intervalsMs ) {
LovenseRemote.GetInstance().SendPattern(toys, types,strengthValues, timeSec,intervals );
}
private void OnControlToysResult(string id,ControlToysResult result){
//...
}
void Awake() {
// Add listener//
LovenseRemote.onControlToysEvent.AddListener(OnControlToysResult);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.onControlToysEvent.RemoveListener(OnControlToysResult);
}
}
values[]: Changes in intensity
personTimeMs: Time interval for intensity switching in milliseconds
timeSec: Total running time in seconds
3.3 Send preset commands
public class YourLovenseToyUI : MonoBehaviour {
private void DoSendPreset(List<LovenseRemoteToy> toys, string presetName, int timeSec) {
LovenseRemote.GetInstance().SendPreset(toys, presetName, timeSec);
}
//callback function, parames is ControlToysResult
private void OnControlToysResult(string id,ControlToysResult result){
//...
}
void Awake() {
// Add listener;
LovenseRemote.onControlToysEvent.AddListener(OnControlToysResult);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.onControlToysEvent.RemoveListener(OnControlToysResult);
}
}
Currently available preset names: "earthquake," "fireworks," "pulse," "wave"
3.4 Send stop command
public class YourLovenseToyUI : MonoBehaviour {
private void DoSendStop(List<LovenseRemoteToy> toys) {
LovenseRemote.GetInstance().SendStopFunction(toys);
}
//callback function, parames is ControlToysResult
private void OnControlToysResult(string id,ControlToysResult result){
//...
}
void Awake() {
// Add listener//
LovenseRemote.onControlToysEvent.AddListener(OnControlToysResult);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.onControlToysEvent.RemoveListener(OnControlToysResult);
}
}
3.5 SendPositionCommand
public class YourLovenseToyUI : MonoBehaviour {
private void DoSendPositionCommand(List<LovenseRemoteToy> toys,int position) {
LovenseRemote.GetInstance().SendPositionCommand(toys,position);
}
//callback function, parames is ControlToysResult
private void OnControlToysResult(string id,ControlToysResult result){
//...
}
void Awake() {
// Add listener//
LovenseRemote.onControlToysEvent.AddListener(OnControlToysResult);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.onControlToysEvent.RemoveListener(OnControlToysResult);
}
}
3.6 SendPatternSetup
public class YourLovenseToyUI : MonoBehaviour {
private void DoSendPatternV2(string domain,int port,List<PositionPatternValue> data,bool isUseHttps) {
LovenseRemote.GetInstance().SendPatternSetup(domain,port,data,isUseHttps);
}
//callback function, parames is ControlToysResult
private void OnControlToysResult(PatternV2_REQ_TYPE type,ControlToysResult result){
//...
}
void Awake() {
// Add listener//
LovenseRemote.onPatternV2Event.AddListener(OnControlToysResult);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.onPatternV2Event.RemoveListener(OnControlToysResult);
}
}
3.6 GetPatternV2SyncTime
public class YourLovenseToyUI : MonoBehaviour {
private void DoSendPatternV2(string domain,int port,bool isUseHttps) {
LovenseRemote.GetInstance().GetPatternV2SyncTime(domain,port,isUseHttps);
}
private void OnPatternV2Result(PatternV2_REQ_TYPE arg0, ControlToysResult arg1){
//...
}
private void OnGetSyncTime(float time){
//...
}
void Awake() {
// Add listener//
LovenseRemote.onPatternV2Event.AddListener(OnPatternV2Result);
LovenseRemote.onPatternSyncTimeEvent.AddListener(OnGetSyncTime);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.onPatternV2Event.RemoveListener(OnPatternV2Result);
LovenseRemote.onPatternSyncTimeEvent.RemoveListener(OnGetSyncTime);
}
}
3.7 Start/Stop PatternV2
public class YourLovenseToyUI : MonoBehaviour {
private void DoStartPatternV2(string domain,int port, int startTime,int offsetTime,string toyId,bool isUseHttps) {
LovenseRemote.GetInstance().StartPatternV2(domain,port,startTime,offsetTime,toyId,isUseHttps);
}
private void DoStopPatternV2(string domain,int port,string toyId, bool isUseHttps) {
LovenseRemote.GetInstance().StopPatternV2(domain,port,toyId,isUseHttps);
}
private void OnPatternV2Result(PatternV2_REQ_TYPE arg0, ControlToysResult arg1){
//...
}
void Awake() {
// Add listener//
LovenseRemote.onPatternV2Event.AddListener(OnPatternV2Result);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.onPatternV2Event.RemoveListener(OnPatternV2Result);
}
}
4. Events of toys
You need to enable the game mode in Lovense Remote and establish the connection before calling the following methods.
public class YourLovenseToyUI : MonoBehaviour {
private void DoSendStop(string ip,int port,bool isSSL) {
LovenseRemote.GetInstance().AddEventApiListener(ip, port, isSSL);
}
//callback function, parames is ControlToysResult
private void OnEventOfApi(string ip,EventApiType eve){
//...
}
private void OnEventOfGetToys(string ip,List<EventToy> toys) {
//...
}
private void OnEventOfButton(string ip,string id,int target,ButtonActionType type){
//...
}
private void OnEventOfFunction(string ip,string id,FunctionValue functionValue){
//...
}
private void OnEventOfFunctionWithShake(string ip,string id,float value){
//...
}
private void OnEventOfToyStatus(string ip,string id,bool connected){
//...
}
private void OnEveryShake(string ip,string id){
//...
}
void Awake() {
// Add listener
LovenseRemote.eventOfApi.AddListener(OnEventOfApi);
LovenseRemote.eventOfGetToys.AddListener(OnEventOfGetToys);
LovenseRemote.eventOfButton.AddListener(OnEventOfButton);
LovenseRemote.eventOfFunction.AddListener(OnEventOfFunction);
LovenseRemote.eventOfShakeFrequencyChanged.AddListener(OnEventOfFunctionWithShake);
LovenseRemote.eventOfToyStatus.AddListener(OnEventOfToyStatus);
LovenseRemote.eventOfEveryShake.AddListener(OnEveryShake);
}
void OnDestroy() {
// Remove listener:
LovenseRemote.eventOfApi.RemoveListener(OnEventOfApi);
LovenseRemote.eventOfGetToys.RemoveListener(OnEventOfGetToys);
LovenseRemote.eventOfButton.RemoveListener(OnEventOfButton);
LovenseRemote.eventOfFunction.RemoveListener(OnEventOfFunction);
LovenseRemote.eventOfShakeFrequencyChanged.RemoveListener(OnEventOfFunctionWithShake);
LovenseRemote.eventOfToyStatus.RemoveListener(OnEventOfToyStatus);
LovenseRemote.eventOfEveryShake.RemoveListener(OnEveryShake);
}
}
Interface
LovenseRemote
Method
GetInstance
Description:
Get the singleton instance of LovenseRemote
Parameters: None
Return:
LovenseRemote instance
SearchRemoteApp
Description:
Search for the Lovense Remote App and toys on the LAN, when the search is complete, the onSearchLocalAppEvent event will be triggered.
Parameters:
Name Type Default Required Description timeout int 5 no Set the HTTP/HTTPS timeout in seconds Return: None
GetToys
Description:
Get the active toy list through the Remote App domain and port, when the search is complete, the onGotToysEvent event will be triggered.
Parameters:
Name Type Default Required Description domain string yes The Domain of the Lovense Remote App port int 30010 no The port of the Lovense Remote App isUseHttps bool true
no Whether to use https or http to communicate with the Lovense Remote App timeout int 5 no Set the HTTP/HTTPS timeout in seconds Return: None
GetSupportCommandsByName
Description:
Obtain Command types supported by toys through their names
Parameters:
Name Type Description name string the name of toy Return: List<LovenseCommandType>
SendFunctions
Description:
Send function commands to the toys.
Parameters:
Name Type Default Required Description toys List<LovenseRemoteToy> yes The toys you want to control commands List<LovenseCommand> yes See LovenseCommand timeSec float yes The total runtime in second, "0" = indefinite time length. Otherwise, the value should be greater than or equal to 1. loopRunningSec float 0
no time running for each command loop in second,the value should be greater than or equal to 1. loopPauseSec float 0
no time gap for each command loop in second ,the value should be greater than or equal to 1. stopPrevious int 1
no Stop previous command, if set to 0
the previous command will not stoptimeout int 5 no Set the HTTP/HTTPS timeout in seconds Return: None
SendPattern
Description:
Send a series of functions to the toys, all the functions will be excecuted in
types
according to the order of the level instrengthValues
with the interval ofintervalsMs
.Parameters:
Name Type Default Required Description toys List<LovenseRemoteToy> yes The toys you want to control types List<LovenseCommandType> yes See LovenseCommandType strengthValues List<int> yes The order of the levels timeSec float yes The total runtime in second, "0" = indefinite time length. Otherwise, the value should be greater than or equal to 1. intervalsMs float 150 no The level interval in milliseconds ,Should be greater than 100 ,default 150 timeout int 5 no Set the HTTP/HTTPS timeout in seconds Return: None
SendPreset
Description:
Send a preset command to the toys.
Parameters:
Name Type Default Required Description toys List<LovenseRemoteToy> yes The toys you want to control presetName string yes The preset name to send, we provide four preset patterns in the Lovense Remote app: pulse
,wave
,fireworks
,earthquake
timeSec float yes The total runtime in second, "0" = indefinite time length. Otherwise, the value should be greater than or equal to 1. timeout int 5 no Set the HTTP/HTTPS timeout in seconds Return: None
SendStopFunction
Description:
Send a stop command to the toys.
Parameters:
Name Type Description toys List<LovenseRemoteToy> The toys you want to stop timeout int Set the HTTP/HTTPS timeout in seconds,default is 5 Return: None
AddEventApiListener
Description: Add events API listener, will trigger eventOfApi and eventOfGetToys if any toy under the local network supports Events API.
Parameters:
Name Type Description ip string The Lovense Remote App's ip port int The Lovense Remote App's port isSSL bool Determine whether to use SSL protocol, default value is false
Return: None
RemoveEventApiListener
Description:
Remove the event API listener under the specified local IP and port.
Parameters:
Name Type Description ip string The Lovense Remote App's ip port int The Lovense Remote App's port Return: None
CloseAllEventApi
Description:
Remove all event API connection.
Parameters:None
Return: None
SendPositionCommand
Description:
Controls the stroker to move to a specified position(0~100).
Parameters:
Name Type Description toys List<LovenseRemoteToy> The toys you want to control value int The position of the stroker timeout int Set the HTTP/HTTPS timeout in seconds Return: None
SendPatternSetup
Description:
Send a series of positions to Solace Pro.
Parameters:
Name Type Description domain string The domain of the Lovense Remote App port int The http/https port of the Lovense Remote App data List<PositionPatternValue> data the series value of PatternV2 isUseHttps bool Whether to use https or http to communicate with the Lovense Remote App Return: None
GetPatternV2SyncTime
Description:
Get the offset time from the server. The onPatternV2Event and onPatternSyncTimeEvent event will be triggered.
Parameters:
Name Type Description domain string The domain of the Lovense Remote App port int The http/https port of the Lovense Remote App isUseHttps bool Whether to use https or http to communicate with the Lovense Remote App Return: None
StartPatternV2
Description:
Play the predefined pattern. The onPatternV2Event event will be triggered.
Parameters:
Name Type Description domain string The domain of the Lovense Remote App port int The http/https port of the Lovense Remote App startTime int The start time of playback. The value range is 0~7200000 (in ms). If you don’t include this, it will start playing from 0. offsetTime int The client-server offset time. The value range is 0~15000 (in ms). If you don’t include this, it will be set to 0. toyId string The toy you want to control timeout int Set the HTTP/HTTPS timeout in seconds Return: None
StopPatternV2
Description:
Stop playing the predefined pattern. The onPatternV2Event event will be triggered.
Parameters:
Name Type Description domain string The domain of the Lovense Remote App port int The http/https port of the Lovense Remote App toyId string The toy you want to control isUseHttps bool Whether to use https or http to communicate with the Lovense Remote App Return: None
Event
onGetAppsEvent
Description:
Triggered when the search for the Lovense Remote App is complete.
Callback Parameters:
Name Type Description appDatas List<RemoteAppData> The search result
onGetAppsErrorEvent
Description:
Triggered when getting Lovense Remote App is on error.
Callback Parameters:
Name Type Description errorMsg string Error message
onGotToysEvent
Description:
Triggered when getting toy list is complete.
Callback Parameters:
Name Type Description toys List<LovenseRemoteToy> The toys of getting
onGetToysErrorEvent
Description:
Triggered when getting toy list is on error.
Callback Parameters:
Name Type Description errorMsg string Error message
onControlToysEvent
Description:
Triggered when sending commands is complete.
Callback Parameters:
Name Type Description result ControlToysResult The result
eventOfApi
Description:
Triggered when the events API status has changed.
Callback Parameters:
Name Type Description ip string The Lovense Remote App's IP eve EventApiType See EventApiType
eventOfGetToys
Description:
Triggered when the events API has been enabled and the toys under local network support Events API.
Callback Parameters:
Name Type Description ip string The Lovense Remote App's IP toys List<EventToy> the toys which support events api, See EventToy
eventOfToyStatus
Description:
Triggered when the connection status of the toy changes.
Callback Parameters:
Name Type Description ip string The Lovense Remote App's IP id string The toy's id connected bool The toy's connection status
eventOfButton
Description:
Triggered when the toy's button is pressed.
Callback Parameters:
Name Type Description ip string The Lovense Remote App's IP id string The toy's id index bool The index of the corresponding button. 0
represents button controls the vibration and1
represents button controls the inflation/rotation.type ButtonActionType See ButtonActionType
eventOfFunction
Description:
Triggered when the parameter
functionValue
of the toy changed.Callback Parameters:
Name Type Description ip string The Lovense Remote App's IP id string The toy's id value FunctionValue See FunctionValue
eventOfShakeFrequencyChanged
Description:
Triggered when the shake value of the toy changed.
Callback Parameters:
Name Type Description ip string The Lovense Remote App's IP id string The toy's id value float The value of shake
eventOfEveryShake
Description:
Trigger when user shakes the toy every time.
Callback Parameters:
Name Type Description ip string The Lovense Remote App's IP id string The toy's id
onPatternV2Event
Description:
Trigger when user PatternV2.
Callback Parameters:
Name Type Description type PatternV2_REQ_TYPE See PatternV2_REQ_TYPE result ControlToysResult See ControlToysResult
onPatternSyncTimeEvent
Description:
Trigger when get PatternV2 SyncTime.
Callback Parameters:
Name Type Description time float The SyncTime of PatternV2
RemoteAppData
Description:
The connection information and status of the Lovense Remote App.
Properties:
Name Type Description online bool The status of the Lovense Remote App, true
represents online,false
represents offlinedomain string The domain of the Lovense Remote App httpsPort int The https port of the Lovense Remote App wssPort int The wss port of the Lovense Remote App
LovenseRemoteToy
Description:
The information of the Lovense toy.
Properties:
Name Type Description domain string The domain of the Lovense Remote App that the toy is connected to port int The port of the Lovense Remote App that the toy is connected to isHttps bool Whether to use https or http to communicate with the Lovense Remote App id string The toy's id status string The toy's status, 1
represents connected,0
represents disconnectedname string The toy's name, such as "nora" nickName string The toy's nickname, such as "My Nora" battery int The toy's battery level, from 0
to100
LovenseCommand
Description:
The toy control command.
Properties:
Name Type Description type LovenseCommandType See below value int Function level
Function Level:
Type | Range |
---|---|
VIBRATE | 0 - 20 |
VIBRATE1 | 0 - 20 |
VIBRATE2 | 0 - 20 |
VIBRATE3 | 0 - 20 |
ROTATE | 0 - 20 |
PUMP | 0 - 3 |
SUCTION | 0 - 20 |
FINGERING | 0 - 20 |
THRUSTRING | 0 - 20 |
DEPTH | 0 - 3 |
LovenseCommandType
Description:
The enum of the toy function type.
Enum:
Value Description VIBRATE VIBRATE1 VIBRATE2 VIBRATE3 ROTATE PUMP THRUSTRING FINGERING SUCTION DEPTH POSITION Only SolacePro is available
The DEPTH command is a setting command that requires the THRUSTRING command to take effect.
ControlToysResult
Description:
The result of the toy control command.
Properties:
Name Type Description code int The result code type string The result type
Result Code:
Code | Description |
---|---|
0 | The request has an HTTP error or a network error |
200 | Success |
400 | Invalid Command |
401 | Toy Not Found |
402 | Toy Not Connected |
403 | Toy Doesn't Support This Command |
404 | Invalid Parameter |
500 | HTTP server not started or disabled |
506 | Server Error.Restart Lovense Connect |
EventApiType
Description:
The enum of the events API type.
Enum:
Value Description EVENT_OPEN the events api has opened EVENT_ERROR the events api is on error EVENT_GRANTED the events open and granted the app name EVENT_CLOSE the events api has closed
EventToy
Description:
The toys that support events API.
Properties:
Name type id string name string type string hVersion string fVersion int nickname string battery int connected bool
ButtonActionType
Description:
The enum of the button action type.
Enum:
Value BUTTON_DOWN BUTTON_UP BUTTON_PRESSED
FunctionValue
Description:
The events API's action values.
Properties:
Name type type See FunctionType index int value int
FunctionType
- Description:
The enum of the function type.
Enum:
Value VIBRATE ROTATE INFLATION THRUSTING DEPTH BATTERY
PatternV2_REQ_TYPE
Description:
The enum of the PatternV2 request type.
Enum:
Value SETUP SYNC_TIME Start Stop
PositionPatternValue
Description:
The position command.
Properties:
Name Type Description time int the time in milliseconds position int The position of the stroker(0-100)
LovenseSolaceProCommand
Description:
Extends from LovenseCommand,specially designed for use with SolacePro.
Properties:
Name Type Description strokeLow int the stroke Value at the low end strokeHigh int The stroke Value at the high end, strokeHigh - strokeLow must be greater than 20
Version Records
[Version1.8] - 2024-08-23
1.Support SolacePro,Update
2.Update the configuration file to version1.4.
3.Modify UI structure.
[Version1.74] - 2024-04-10
- 1.Fix error code 601.
[Version1.73] - 2023-12-15
- 1.Bug fixing for Android platform.
[Version1.72] - 2023-11-30
- 1.Adapting compatibility for the IL2CPP scripting backend.
[Version1.71] - 2023-11-24
- 1.Fixed MissingMethodException.
[Version1.7] - 2023-11-15
1.Add Depth command.
2.Update the configuration file to version1.3.
[Version1.6] - 2023-11-07
- 1.Add capability with WebGL.
[Version1.5] - 2023-11-01
- 1.Add Vibrate1 Vibrate2 Vibrate3 commands.
[Version1.4] - 2023-10-24
Added timeout parameter to the following functions using http/https:
SearchRemoteApp
GetToys
SendFunctions
SendPattern
SendPreset
SendStopFunction
The callback is triggered when the HTTP/HTTPS connection times out.
[Version1.3] - 2023-09-27
- 1.Add events API of Lovense Remote App.
[Version1.2] - 2023-09-12
1.Add a function that can query toy support instructions
2.Finding an empty Remote App or empty toy also triggers an event.
3.Change type of 'strengthValues' int[] to List<int> in pattern function
4.Change time type int to float.
5.Event [onControlToysEvent] add parames 'toyId'
[Version1.1] - 2023-08-25
1.Add onGetAppsErrorEvent and onGetAppsErrorEvent when the request has an HTTP error or a network error.
2.Add a error code when control toys has occus an HTTP error or a network error.
[Version1.0] - 2023-08-20
1.Functions
2.Pattern
3.Preset