├── .gitignore ├── Android Bluetooth Unity3D Package ├── V1 │ └── UnityAndroidBluetooth V1.unitypackage ├── V2 │ └── UnityAndroidBluetooth V2.unitypackage └── V3 │ └── UnityAndroidBluetoothV3.unitypackage ├── Android source code ├── V1 │ └── Android Studio src ├── V2 │ └── BluetoothConnector.java └── V3 │ ├── BluetoothConnector.java │ └── DeviceListAdapter.java ├── LICENSE ├── README.md └── Use this build to test ├── V1 └── AndroidTestAppV1.apk ├── V2 └── AndroidTestAppV2.apk └── V3 └── AndroidTestAppV3.apk /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | Assets/AssetStoreTools* 7 | 8 | # Visual Studio cache directory 9 | .vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | *.opendb 26 | 27 | # Unity3D generated meta files 28 | *.pidb.meta 29 | *.pdb.meta 30 | 31 | # Unity3D Generated File On Crash Reports 32 | sysinfo.txt 33 | 34 | # Builds 35 | # *.apk 36 | # *.unitypackage 37 | -------------------------------------------------------------------------------- /Android Bluetooth Unity3D Package/V1/UnityAndroidBluetooth V1.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentalebahmed/BlueUnity/aede232e8ba57e64f408e02ecd2bc9c22d72defb/Android Bluetooth Unity3D Package/V1/UnityAndroidBluetooth V1.unitypackage -------------------------------------------------------------------------------- /Android Bluetooth Unity3D Package/V2/UnityAndroidBluetooth V2.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentalebahmed/BlueUnity/aede232e8ba57e64f408e02ecd2bc9c22d72defb/Android Bluetooth Unity3D Package/V2/UnityAndroidBluetooth V2.unitypackage -------------------------------------------------------------------------------- /Android Bluetooth Unity3D Package/V3/UnityAndroidBluetoothV3.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentalebahmed/BlueUnity/aede232e8ba57e64f408e02ecd2bc9c22d72defb/Android Bluetooth Unity3D Package/V3/UnityAndroidBluetoothV3.unitypackage -------------------------------------------------------------------------------- /Android source code/V1/Android Studio src: -------------------------------------------------------------------------------- 1 | 2 | package com.example.unity3dbluetoothplugin; 3 | 4 | import android.bluetooth.BluetoothAdapter; 5 | import android.bluetooth.BluetoothDevice; 6 | import android.bluetooth.BluetoothSocket; 7 | import android.content.Context; 8 | //import android.util.Log; 9 | import android.widget.Toast; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.InputStreamReader; 15 | import java.io.OutputStream; 16 | import java.util.ArrayList; 17 | import java.util.Set; 18 | import java.util.UUID; 19 | 20 | public class BluetoothConnector { 21 | 22 | 23 | private static final BluetoothConnector ourInstance = new BluetoothConnector(); 24 | public static BluetoothConnector getInstance() { 25 | return ourInstance; 26 | } 27 | public final String TAG = "MAIN"; 28 | public ArrayList devices_true = new ArrayList<>(); 29 | public ArrayListdevice_names = new ArrayList<>(); 30 | public final UUID mUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 31 | 32 | public BluetoothAdapter adapter; 33 | public BluetoothSocket skt; 34 | public BluetoothDevice cur_device; 35 | public BluetoothDevice con_device; 36 | public Set devices; 37 | public InputStream inputStream; 38 | public OutputStream outputStream; 39 | 40 | 41 | private BluetoothConnector() {} 42 | 43 | public String[] GetBluetoothDevices(){ 44 | try{ 45 | devices_true.clear(); 46 | device_names.clear(); 47 | adapter = BluetoothAdapter.getDefaultAdapter(); 48 | devices = adapter.getBondedDevices(); 49 | for(BluetoothDevice device:devices) 50 | { 51 | devices_true.add(device); 52 | device_names.add(device.getName()); 53 | } 54 | return device_names.toArray(new String[0]); 55 | } 56 | catch (Exception ex){ 57 | return null; 58 | } 59 | } 60 | 61 | public String StartBluetoothConnection(String DeviceName){ 62 | try{ 63 | devices_true.clear(); 64 | device_names.clear(); 65 | adapter = BluetoothAdapter.getDefaultAdapter(); 66 | devices = adapter.getBondedDevices(); 67 | for(BluetoothDevice device:devices) 68 | { 69 | devices_true.add(device); 70 | device_names.add(device.getName()); 71 | } 72 | 73 | cur_device = devices_true.get(device_names.indexOf(DeviceName)); 74 | 75 | if(cur_device == null) 76 | { 77 | return "Device not found"; 78 | } 79 | 80 | con_device = adapter.getRemoteDevice(cur_device.getAddress()); 81 | 82 | skt = con_device.createInsecureRfcommSocketToServiceRecord(mUUID); 83 | adapter.cancelDiscovery(); 84 | skt.connect(); 85 | 86 | inputStream = skt.getInputStream(); 87 | outputStream = skt.getOutputStream(); 88 | 89 | return "Connected"; 90 | } 91 | catch (Exception ex) 92 | { 93 | return "Error"; 94 | } 95 | } 96 | public String ReadData(){ 97 | 98 | try { 99 | if(inputStream.available() > 0){ 100 | 101 | BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 102 | return reader.readLine(); 103 | } 104 | else return ""; 105 | } catch (IOException e) { 106 | return ""; 107 | } 108 | } 109 | 110 | public void WriteData(String data){ 111 | try { 112 | outputStream.write(data.getBytes()); 113 | } catch (IOException e) { 114 | // e.printStackTrace(); 115 | } 116 | } 117 | 118 | public void StopBluetoothConnection(){ 119 | try { 120 | if(inputStream != null) inputStream.close(); 121 | if(outputStream != null) outputStream.close(); 122 | if(skt != null) skt.close(); 123 | } catch (IOException e) { 124 | // e.printStackTrace(); 125 | } 126 | } 127 | 128 | public void PrintOnScreen(Context context, String info){ 129 | Toast.makeText(context, info,Toast.LENGTH_SHORT).show(); 130 | } 131 | } 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Android source code/V2/BluetoothConnector.java: -------------------------------------------------------------------------------- 1 | 2 | package com.example.unity3dbluetoothplugin; 3 | 4 | import android.bluetooth.BluetoothAdapter; 5 | import android.bluetooth.BluetoothDevice; 6 | import android.bluetooth.BluetoothSocket; 7 | import android.content.Context; 8 | //import android.util.Log; 9 | import android.widget.Toast; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.InputStreamReader; 15 | import java.io.OutputStream; 16 | import java.util.ArrayList; 17 | import java.util.Set; 18 | import java.util.UUID; 19 | 20 | public class BluetoothConnector { 21 | 22 | 23 | private static final BluetoothConnector ourInstance = new BluetoothConnector(); 24 | public static BluetoothConnector getInstance() { 25 | return ourInstance; 26 | } 27 | public final String TAG = "MAIN"; 28 | public ArrayList devices_true = new ArrayList<>(); 29 | public ArrayListdevice_names = new ArrayList<>(); 30 | public final UUID mUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 31 | 32 | public BluetoothAdapter adapter; 33 | public BluetoothSocket skt; 34 | public BluetoothDevice cur_device; 35 | public BluetoothDevice con_device; 36 | public Set devices; 37 | public InputStream inputStream; 38 | public OutputStream outputStream; 39 | 40 | 41 | private BluetoothConnector() {} 42 | 43 | public String[] GetBluetoothDevices(){ 44 | try{ 45 | devices_true.clear(); 46 | device_names.clear(); 47 | adapter = BluetoothAdapter.getDefaultAdapter(); 48 | devices = adapter.getBondedDevices(); 49 | for(BluetoothDevice device:devices) 50 | { 51 | devices_true.add(device); 52 | device_names.add(device.getName()); 53 | } 54 | return device_names.toArray(new String[0]); 55 | } 56 | catch (Exception ex){ 57 | return null; 58 | } 59 | } 60 | 61 | public String StartBluetoothConnection(String DeviceName){ 62 | try{ 63 | devices_true.clear(); 64 | device_names.clear(); 65 | adapter = BluetoothAdapter.getDefaultAdapter(); 66 | devices = adapter.getBondedDevices(); 67 | for(BluetoothDevice device:devices) 68 | { 69 | devices_true.add(device); 70 | device_names.add(device.getName()); 71 | } 72 | 73 | cur_device = devices_true.get(device_names.indexOf(DeviceName)); 74 | 75 | if(cur_device == null) 76 | { 77 | return "Device not found"; 78 | } 79 | 80 | con_device = adapter.getRemoteDevice(cur_device.getAddress()); 81 | 82 | skt = con_device.createInsecureRfcommSocketToServiceRecord(mUUID); 83 | adapter.cancelDiscovery(); 84 | skt.connect(); 85 | 86 | inputStream = skt.getInputStream(); 87 | outputStream = skt.getOutputStream(); 88 | 89 | return "Connected"; 90 | } 91 | catch (Exception ex) 92 | { 93 | return "Error"; 94 | } 95 | } 96 | public String ReadData(){ 97 | 98 | try { 99 | if(inputStream.available() > 0){ 100 | 101 | BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 102 | return reader.readLine(); 103 | } 104 | else return ""; 105 | } catch (IOException e) { 106 | return ""; 107 | } 108 | } 109 | 110 | public void WriteData(String data){ 111 | try { 112 | outputStream.write(data.getBytes()); 113 | } catch (IOException e) { 114 | // e.printStackTrace(); 115 | } 116 | } 117 | 118 | public void StopBluetoothConnection(){ 119 | try { 120 | if(inputStream != null) inputStream.close(); 121 | if(outputStream != null) outputStream.close(); 122 | if(skt != null) skt.close(); 123 | } catch (IOException e) { 124 | // e.printStackTrace(); 125 | } 126 | } 127 | 128 | public void PrintOnScreen(Context context, String info){ 129 | Toast.makeText(context, info,Toast.LENGTH_SHORT).show(); 130 | } 131 | } 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Android source code/V3/BluetoothConnector.java: -------------------------------------------------------------------------------- 1 | // aar file to import into unity after build 2 | // C:\Users\ user\AndroidStudioProjects\ unity3dbluetoothplugin\build\outputs\aar 3 | 4 | package com.example.unity3dbluetoothplugin; 5 | 6 | 7 | import android.annotation.SuppressLint; 8 | import android.bluetooth.BluetoothAdapter; 9 | import android.bluetooth.BluetoothDevice; 10 | import android.bluetooth.BluetoothManager; 11 | import android.bluetooth.BluetoothSocket; 12 | import android.bluetooth.le.BluetoothLeScanner; 13 | import android.content.BroadcastReceiver; 14 | import android.content.Context; 15 | import android.content.Intent; 16 | import android.content.IntentFilter; 17 | import android.os.Handler; 18 | import android.widget.Toast; 19 | 20 | 21 | import com.unity3d.player.UnityPlayer; 22 | import java.io.BufferedReader; 23 | import java.io.IOException; 24 | import java.io.InputStream; 25 | import java.io.InputStreamReader; 26 | import java.io.OutputStream; 27 | import java.util.ArrayList; 28 | import java.util.Set; 29 | import java.util.UUID; 30 | 31 | public class BluetoothConnector { 32 | 33 | private static BluetoothConnector mInstance = null; 34 | 35 | private static final UUID mUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 36 | private static BluetoothManager mBluetoothManager = null; 37 | private static BluetoothAdapter mBluetoothAdapter = null; 38 | private static BluetoothLeScanner mBluetoothLeScanner = null; 39 | private static DeviceListAdapter mDeviceListAdapter; 40 | private static boolean scanning = false; 41 | private static final Handler handler = new Handler(); 42 | private static final long SCAN_PERIOD = 10000; 43 | private static BluetoothSocket skt; 44 | private static InputStream inputStream; 45 | private static OutputStream outputStream; 46 | private static BufferedReader reader; 47 | 48 | @SuppressLint("MissingPermission") 49 | public static BluetoothConnector getInstance() { 50 | if (mInstance == null) 51 | mInstance = new BluetoothConnector(); 52 | return mInstance; 53 | } 54 | 55 | @SuppressLint("MissingPermission") 56 | public BluetoothConnector() { 57 | // checkPermissions(UnityPlayer.currentActivity.getApplicationContext(), UnityPlayer.currentActivity); 58 | mBluetoothManager = UnityPlayer.currentActivity.getApplication().getApplicationContext().getSystemService(BluetoothManager.class); 59 | mBluetoothAdapter = mBluetoothManager.getAdapter(); 60 | 61 | if(!mBluetoothAdapter.isEnabled()) 62 | { 63 | Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 64 | UnityPlayer.currentActivity.startActivityForResult(enableBtIntent, 1); 65 | } 66 | 67 | if (!mBluetoothAdapter.isEnabled()) 68 | mBluetoothAdapter.enable(); 69 | 70 | mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); 71 | 72 | mDeviceListAdapter = new DeviceListAdapter(); 73 | 74 | IntentFilter filter = new IntentFilter(); 75 | filter.addAction(BluetoothDevice.ACTION_FOUND); 76 | filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); 77 | filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 78 | 79 | BroadcastReceiver receiver = new BroadcastReceiver() { 80 | @Override 81 | public void onReceive(Context context, Intent intent) { 82 | String action = intent.getAction(); 83 | if (BluetoothDevice.ACTION_FOUND.equals(action)) { 84 | BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 85 | if (mDeviceListAdapter.AddDevice(device)){ 86 | String deviceName = device.getName()==null? "null": device.getName(); 87 | String deviceAddress = device.getAddress(); 88 | UnityPlayer.UnitySendMessage("BluetoothManager", "NewDeviceFound", deviceAddress + "+" + deviceName); 89 | } 90 | } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) { 91 | UnityPlayer.UnitySendMessage("BluetoothManager", "ScanStatus", "started"); 92 | } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { 93 | UnityPlayer.UnitySendMessage("BluetoothManager", "ScanStatus", "stopped"); 94 | } 95 | } 96 | }; 97 | UnityPlayer.currentActivity.getApplication().getApplicationContext().registerReceiver(receiver, filter); 98 | } 99 | 100 | @SuppressLint("MissingPermission") 101 | private static void StartScanDevices() { 102 | // Check if discovery is already in progress, and cancel if so 103 | if (mBluetoothAdapter.isDiscovering()) { 104 | mBluetoothAdapter.cancelDiscovery(); 105 | } 106 | mDeviceListAdapter.clearAll(); 107 | mBluetoothAdapter.startDiscovery(); 108 | } 109 | 110 | @SuppressLint("MissingPermission") 111 | private static void StopScanDevices() { 112 | // Check if discovery is already in progress, and cancel if so 113 | if (mBluetoothAdapter.isDiscovering()) { 114 | mBluetoothAdapter.cancelDiscovery(); 115 | UnityPlayer.UnitySendMessage("BluetoothManager", "ScanStatus", "stopped"); 116 | } 117 | } 118 | 119 | @SuppressLint("MissingPermission") 120 | public static String[] GetPairedDevices() { 121 | try { 122 | ArrayList paired_devices = new ArrayList<>(); 123 | 124 | Set devices = mBluetoothAdapter.getBondedDevices(); 125 | for(BluetoothDevice device:devices) 126 | { 127 | paired_devices.add(device.getAddress()+"+"+device.getName()); 128 | } 129 | return paired_devices.toArray(new String[0]); 130 | } 131 | catch (Exception ex){ 132 | UnityPlayer.UnitySendMessage("BluetoothManager", "ReadLog", ex.toString()); 133 | return null; 134 | } 135 | } 136 | 137 | @SuppressLint("MissingPermission") 138 | public static void StartConnection(String DeviceAdd){ 139 | UnityPlayer.UnitySendMessage("BluetoothManager", "ConnectionStatus", "connecting"); 140 | try{ 141 | if(!BluetoothAdapter.checkBluetoothAddress(DeviceAdd)) 142 | UnityPlayer.UnitySendMessage("BluetoothManager", "ConnectionStatus", "Device not found"); 143 | 144 | BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(DeviceAdd); 145 | // skt = device.createInsecureRfcommSocketToServiceRecord(mUUID); 146 | skt = device.createRfcommSocketToServiceRecord(mUUID); 147 | mBluetoothAdapter.cancelDiscovery(); 148 | skt.connect(); 149 | inputStream = skt.getInputStream(); 150 | outputStream = skt.getOutputStream(); 151 | 152 | reader = new BufferedReader(new InputStreamReader(inputStream)); 153 | 154 | ReadDatathread = new Thread(ReadData); 155 | ReadDatathread.start(); 156 | 157 | UnityPlayer.UnitySendMessage("BluetoothManager", "ConnectionStatus", "connected"); 158 | } 159 | catch (Exception ex) 160 | { 161 | UnityPlayer.UnitySendMessage("BluetoothManager", "ConnectionStatus", "unable to connect"); 162 | UnityPlayer.UnitySendMessage("BluetoothManager", "ReadLog", "StartConnection Error: "+ex); 163 | } 164 | } 165 | public static void StopConnection(){ 166 | try { 167 | ReadDatathread.interrupt(); 168 | if(inputStream != null) inputStream.close(); 169 | if(outputStream != null) outputStream.close(); 170 | if(skt != null) skt.close(); 171 | } catch (IOException e) { 172 | UnityPlayer.UnitySendMessage("BluetoothManager", "ReadLog", "StopConnection Error: "+e); 173 | } 174 | } 175 | 176 | private static final Runnable ReadData = new Runnable() { 177 | public void run() { 178 | while (skt.isConnected() && !ReadDatathread.isInterrupted()) { 179 | try { 180 | if (inputStream.available() > 0) { 181 | 182 | UnityPlayer.UnitySendMessage("BluetoothManager", "ReadData", reader.readLine()); 183 | } 184 | } catch (IOException e) { 185 | UnityPlayer.UnitySendMessage("BluetoothManager", "ReadLog", "inputStream Error: " + e); 186 | } 187 | } 188 | UnityPlayer.UnitySendMessage("BluetoothManager", "ConnectionStatus", "disconnected"); 189 | } 190 | }; 191 | 192 | private static Thread ReadDatathread = null; 193 | 194 | public static void WriteData(String data) { 195 | try { 196 | if (skt.isConnected()) { 197 | outputStream.write(data.getBytes()); 198 | } 199 | } catch (IOException e) { 200 | UnityPlayer.UnitySendMessage("BluetoothManager", "ReadLog", "WriteData Error: "+e); 201 | } 202 | } 203 | 204 | public static void Toast(String info){ 205 | Toast.makeText(UnityPlayer.currentActivity.getApplicationContext(), info,Toast.LENGTH_SHORT).show(); 206 | } 207 | 208 | } 209 | 210 | 211 | 212 | 213 | -------------------------------------------------------------------------------- /Android source code/V3/DeviceListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.unity3dbluetoothplugin; 2 | 3 | import android.bluetooth.BluetoothDevice; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class DeviceListAdapter { 9 | public Map mDevicesMap = new HashMap(); 10 | 11 | public boolean AddDevice(BluetoothDevice device) { 12 | if (this.mDevicesMap.get(device.getAddress()) != null) { 13 | return false; 14 | } 15 | 16 | this.mDevicesMap.put(device.getAddress(), device); 17 | return true; 18 | } 19 | 20 | public int getCount() { 21 | return this.mDevicesMap.size(); 22 | } 23 | 24 | public BluetoothDevice getItem(String i) { 25 | return this.mDevicesMap.get(i); 26 | } 27 | 28 | public void clearAll(){ 29 | this.mDevicesMap.clear(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 BENTALEB Ahmed 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlueUnity 2 | BlueUnity is a plugin for using Bluetooth Serial with Unity3d on Android. 3 | 4 | ## Installation 5 | 6 | 1) Create new Unity project. 7 | 8 | 2) Switch to Android build profile 9 | 10 | 3) In Player Settings -> Publishing Settings -> Build : enable Custom Main Manifest. 11 | 12 | 4) Also in Player Settings -> Other Settings -> Minimum API Level : set it to API level 27 13 | 14 | 5) Check in Player Settings -> Other Settings, if you have the option `Application Entry Point`, make sure to set it to Activity and not GameActivity as the plugin uses custom Android Manifest (Found that in Unity 6). 15 | 16 | 6) Import the latest [`UnityAndroidBluetooth Unitypackage`](https://github.com/bentalebahmed/BlueUnity/releases/tag/v3.0.0) . In the Scenes folder, you will find a scene "SampleScene" to test the Bluetooth plugin. 17 | 18 | > Note: Pluging was tested on `Unity 2020.3.28f1` and `Unity 6000.0.38f1` on a Samsung A53 that runs Android 14 (API 34) with a HC-05 bluetooth module. 19 | 20 | ## Usage 21 | 22 | 1) Build the game using SampleScene or use the one I already built (see in 'Use this build to test/ V3'). 23 | 24 | 2) Enable bluetooth and location. 25 | 26 | 3) Open the app and approve all permissions 27 | 28 | 5) Click Search button to start scanning for bluetooth devices or Paired Devices button to list all paired devices. Enter the MAC address of the bluetooth device, and click Start button to connect. 29 | 30 | 6) Enter data in the input field named "Enter Data to send" and click Send. 31 | 32 | 7) The incoming data is displayed directly on the screen, using ReadData(string data) which is called from Java class using UnityPlayer.UnitySendMessage(). 33 | > **Note:** The plugin parses incoming data with `inputBuffer.readLine()`, which reads until it reaches a new line character ('\n'). 34 | 35 | 8) To see Log messages, draw a circle in the screen with your finger to see the Log Viewer (Unity-Logs-Viewer from assets store). 36 | 37 | 9) Do not forget to enalbe bluetooth and location access. 38 | 39 | ## Supported functionality 40 | - Check and Request BT and location permissions (for Search Devices). 41 | - Search Devices. 42 | - Search Status. 43 | - Get Paired Devices. 44 | - Connect BT with MAC address. 45 | - Disconnect BT. 46 | - Connection Status. 47 | - Read Stream. 48 | - Write Stream. 49 | 50 | I have Enhanced the code by using Unity3D UnityPlayer java class, this is done by adding the following line in build.gradle.kts of the Module, Here I'm using Unity 2020.3.28f1, change that to your version: 51 | 52 | ``` 53 | dependencies { 54 | ... 55 | compileOnly(files("C:/Program Files/Unity/Hub/Editor/2020.3.28f1/Editor/Data/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Classes/classes.jar")) 56 | } 57 | 58 | ``` 59 | In the Java class you can import UnityPlayer java class: 60 | ``` 61 | import com.unity3d.player.UnityPlayer; 62 | ``` 63 | and use UnitySendMessage that searches for a GameObject by Name and calls a Function inside that GameObject and passes Arguments as String to it: 64 | ``` 65 | UnityPlayer.UnitySendMessage("GameObjectName", "FunctionToBeCalled", "ArgumentAsString"); 66 | ``` 67 | 68 | This function is used for Search status, Connection status, New Device Found, and Read Data callbacks. 69 | 70 | 71 | Demo and code explanation are coming soon, for now, I hope the code is self-explained. 72 | 73 | 74 | ## Bluetooth Compatibility 75 | 76 | BlueUnity was tested on HC-05, HC-06, BM78 Bluetooth modules, and ESP32 using the standard Bluetooth library (BluetoothSerial.h). 77 | 78 | > **Note:** Use println(data) or write(data+"\n"). As the plug-in expects new line ('\n') each time data is received. 79 | 80 | ## Adapting to Your Project 81 | 82 | If you want to edit the plugin and adapt it to your needs, check the "Android source code" folder, which contains the code of the plugin. 83 | 84 | To create you own plug-in (the arr file), in Android studio go to File -> New -> New Module, and select Android Library. 85 | 86 | To use UnitySendMessage don't forget to add the required dependency (check above) in 'build.gradle.kts' of your library 87 | 88 | ## Contributing or Questions 89 | 90 | Contact: ben.studio33@gmail.com 91 | 92 | ## License 93 | [MIT](https://choosealicense.com/licenses/mit/) 94 | -------------------------------------------------------------------------------- /Use this build to test/V1/AndroidTestAppV1.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentalebahmed/BlueUnity/aede232e8ba57e64f408e02ecd2bc9c22d72defb/Use this build to test/V1/AndroidTestAppV1.apk -------------------------------------------------------------------------------- /Use this build to test/V2/AndroidTestAppV2.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentalebahmed/BlueUnity/aede232e8ba57e64f408e02ecd2bc9c22d72defb/Use this build to test/V2/AndroidTestAppV2.apk -------------------------------------------------------------------------------- /Use this build to test/V3/AndroidTestAppV3.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentalebahmed/BlueUnity/aede232e8ba57e64f408e02ecd2bc9c22d72defb/Use this build to test/V3/AndroidTestAppV3.apk --------------------------------------------------------------------------------