您现在的位置是:网站首页> C#技术
Unity3D 框架技术收集
- C#技术
- 2024-09-06
- 1023人已阅读
Unity3D 框架技术收集
Unity实现Android源生平台蓝牙BLE4.0数据传输(一)
Unity实现Android源生平台蓝牙BLE4.0数据传输(二)
Unity实现Android源生平台蓝牙BLE4.0数据传输(三)
Unity3D UI框架
直接使用NGUI或UGUI
1.Unity-UI-Framework的设计与实现 By:王选易 Github
2.简单、强大的TTUIFramework By:chiuan 游戏蛮牛 (这位的设计思路是参考上面那位作者的)
3.【设计和开发一套自动化UI框架】 By:NPC燕 游戏蛮牛
Unity实现Android源生平台蓝牙BLE4.0数据传输(一)
Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。虽然是游戏引擎,不过现在目前还有很多用来做AR、VR、MR等内容.这样就少不了要与智能硬件配合交互,智能硬件由于便利性都大多数采用无线连接,无线连接主流一般是WIFI、Bluetooth蓝牙等方式.其中蓝牙BLE4.0以更省电、成本低、3毫秒低延迟、超长有效连接距离、AES-128加密等优势,取得大家的青睐,今天就来说说用Unity实现BLE4.0的数据传输.
Unity想要使用Android源生控件或者功能首先我们要来了AndroidJavaClass、AndroidJavaObject、AndroidJavaProxy三个类.
其中 AndroidJavaClass 一般调用静态函数跟获取静态字段使用这个,如果做过unity 跟android交互的朋友们应该见过这句
unityActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
这里先new了一个 AndroidJavaClass对象然后调用GetStatic获取静态字段currentActivity
AndroidJavaObject 一般是Java实例对象用来调用Java的实例函数跟获取实例字段.
比如 我要建立一个Java的String对象
AndroidJavaObject javaString = new AndroidJavaObject("java.lang.String", text);
我再获取这个String对象的字符长度
var sLenth = javaString.Call<int>("length");
AndroidJavaProxy 是用来实现Java的接口interface. 这里引用Unity官方文档样例
private static DateTime selectedDate = DateTime.Now;
public class DateCallback : AndroidJavaProxy
{
public DateCallback() :base("android.app.DatePickerDialog$OnDateSetListener") { }
void onDateSet(AndroidJavaObject view, int year, int monthOfYear, int dayOfMonth)
{
selectedDate = new DateTime(year, monthOfYear + 1, dayOfMonth);
}
}
实现接口以后Android 调用接口函数的时候会调用Unity端的接口实现.但函数名应该保持与Java接口函数一致.
其实能使用AndroidJavaClass、AndroidJavaObject 类已经能使用Android 大部分功能.
Unity实现Android源生平台蓝牙BLE4.0数据传输(二)
这篇我们来利用这些知识来实现蓝牙设备的打开系统功能,扫描,以及连接.
首先想要Android平台使用蓝牙的功能那么权限是不能少的
我们把AndroidManifest.xml文件放在Unity工程的Plugins->Android 文件夹下
AndroidManifest文件中加入如下代码
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
保存之后就可以开始了
首先判断系统的蓝牙是否打开
var bluetooth = new AndroidJavaClass("android.bluetooth.BluetoothAdapter");//获得Android BluetoothAdapter类
bluetoothAdapter = bluetooth.CallStatic<AndroidJavaObject>("getDefaultAdapter");//获取本地蓝牙设备也就是手机的蓝牙
//判断系统蓝牙是否打开
if (!bluetoothAdapter.Call<bool>("isEnabled"))
{
var isOpen = bluetoothAdapter.Call<bool>("enable"); //打开蓝牙,需要BLUETOOTH_ADMIN权限
}
执行之后手机上面会出现android源生的蓝牙打开请求界面 我们选择"是"打开
打开设备后就开始扫描蓝牙设备了
var mBluetoothLeScanner = bluetoothAdapter.Call<AndroidJavaObject>("getBluetoothLeScanner");
ScanCallback scanCallback = new ScanCallback();//unity继承的扫描对象接口实现类
AndroidJavaObject wfzScanCallback = new AndroidJavaObject("com.wfz.bletounity.WFZScanCallback");//蓝牙扫描回调对象
//扫描结果的事件委托实现
scanCallback.onScanResultDelegate = (t, r) =>
{
if (r == null)
{
return;
}
var bluetoothDevice = r.Call<AndroidJavaObject>("getDevice");//从结果中获取到设备对象
var deviceName = bluetoothDevice.Call<string>("getName");//获取设备的名字
var deviceAddress = bluetoothDevice.Call<string>("getAddress");//获取设备的MAC地址
Debug.Log("扫描到设备:" + deviceName + "地址:" + deviceAddress);
if (deviceName =="CAD")//判断是否想要的连接的设备名字
{
if (buetoothGatt == null)
{
ConnectGatt(bluetoothDevice);//连接想要的设备
mBluetoothLeScanner.Call("stopScan", wfzScanCallback);//停止扫描
}
}
};
wfzScanCallback.Call("AddUnityCallback", scanCallback);//添加unity对android蓝牙的监听事件
mBluetoothLeScanner.Call("startScan", wfzScanCallback);//开始扫描
这样我们就连接到我们想要的设备了 下一篇我们来说说数据的获取.
Unity实现Android源生平台蓝牙BLE4.0数据传输(三)
AndroidJavaObject wfzBluetoothGattCallback = new AndroidJavaObject("com.wfz.bletounity.WFZBluetoothGattCallback”);//连接的事件回调对象
BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback();//unity事件回调接口的实现类
//特征值数据变化的事件委托
bluetoothGattCallback.onCharacteristicChangedDelegate = (g, c) =>
{
var data = c.Call<byte[]>("getValue");
string d = "";
for (int i = 0; i < data.Length; i++)
{
d += data[i];
}
Debug.Log(d);
};
//设备连接状态变化的事件委托
bluetoothGattCallback.onConnectionStateChangeDelegate = (g, s, n) =>
{
switch (n)
{
case 0:
Debug.Log("断开连接");
break;
case 1:
Debug.Log("连接中");
break;
case 2:
Debug.Log("连接成功");
Debug.Log("获取到gatt对象"+g.Call<AndroidJavaObject>("getDevice").Call<string>("getName"));
var isFind= g.Call<bool>("discoverServices");
break;
case 3:
Debug.Log("断开中");
break;
default:
break;
}
};
//发现设备服务事件委托
bluetoothGattCallback.onServicesDiscoveredDelegate = (g, c) =>
{
var gattServices = g.Call<AndroidJavaObject>("getServices");
Debug.Log("发现新服务..." + gattServices.Get<int>("size"));
if (gattCharacteristic==null)
{
gattCharacteristic = GetCharacteristic(GetService(g, serviceID), characteristicID);
NotificationData(g, gattCharacteristic, descriptorID);
}
};
回调对象写好了我们就可以连接设备了
wfzBluetoothGattCallback.Call("AddUnityCallback", bluetoothGattCallback);//把实现的接口添加到回调对象
buetoothGatt = device.Call<AndroidJavaObject>("connectGatt", AndroidCall.unityActivity, true, wfzBluetoothGattCallback);//开始连接
下面是获取服务 特征值的函数实现
/// <summary>
/// Gets the service.
/// </summary>
/// <returns>The service.</returns>
/// <param name="gatt">Gatt.</param>
/// <param name="uuid">UUID.</param>
public AndroidJavaObject GetService(AndroidJavaObject gatt, string uuid)
{
return gatt.Call<AndroidJavaObject>("getService", ToAndroidUUID(uuid));
}
/// <summary>
/// Gets the characteristic.
/// </summary>
/// <returns>The characteristic.</returns>
/// <param name="Service">Service.</param>
/// <param name="uuid">UUID.</param>
public AndroidJavaObject GetCharacteristic(AndroidJavaObject Service,string uuid)
{
return Service.Call<AndroidJavaObject>("getCharacteristic", ToAndroidUUID(uuid));
}
打开特征值的通知
/// <summary>
/// Notifications the data.
/// </summary>
/// <param name="gatt">Gatt.</param>
/// <param name="characteristic">Characteristic.</param>
/// <param name="uuid">UUID.</param>
public void NotificationData(AndroidJavaObject gatt,AndroidJavaObject characteristic,string uuid)
{
var b = gatt.Call<bool>("setCharacteristicNotification", characteristic, true);
if (b)
{
var bluetoothGattDescriptor = new AndroidJavaClass("android.bluetooth.BluetoothGattDescriptor");
var descriptor= characteristic.Call<AndroidJavaObject>("getDescriptor",ToAndroidUUID(uuid));
var isSet= descriptor.Call<bool>("setValue", bluetoothGattDescriptor.GetStatic<byte[]>("ENABLE_NOTIFICATION_VALUE"));
if (isSet)
{
var iSwrite= gatt.Call<bool>("writeDescriptor", descriptor);
if (iSwrite)
{
Debug.Log("打开特性通知");
}
}
}
}
打开通知之后 就可以在onCharacteristicChanged 事件里面获取到发送过来的数据了