438 lines
13 KiB
C#
438 lines
13 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using BehaviorDesigner.Runtime.Tasks;
|
||
using TruegearSdk;
|
||
using UnityEngine;
|
||
|
||
public class TrueGearEffectManager : MonoBehaviour
|
||
{
|
||
|
||
public static TrueGearEffectManager Ins;
|
||
|
||
// 马甲功能开关(在Unity编辑器中配置)
|
||
[SerializeField] private bool enableTrueGear = true;
|
||
|
||
/// <summary>
|
||
/// 是否启用TrueGear马甲功能
|
||
/// </summary>
|
||
public bool EnableTrueGear => enableTrueGear;
|
||
|
||
private void Awake()
|
||
{
|
||
// 场景切换时保留此对象,防止切换场景后单例丢失
|
||
DontDestroyOnLoad(gameObject);
|
||
|
||
// 设置单例(带保护,防止重复创建)
|
||
if (Ins == null)
|
||
{
|
||
Ins = this;
|
||
}
|
||
else if (Ins != this)
|
||
{
|
||
Destroy(gameObject); // 防止重复创建
|
||
return;
|
||
}
|
||
|
||
isAvailableIndex = 20;
|
||
GetConnectIndex = 20;
|
||
AddHitPart();
|
||
// 不再自动连接,等待用户选择设备后再连接
|
||
}
|
||
|
||
|
||
private void Start()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化TrueGear蓝牙(仅初始化,不连接)
|
||
/// </summary>
|
||
public void InitTrueGear()
|
||
{
|
||
TruegearAndroidConnector androidConnector = new TruegearAndroidConnector();
|
||
androidConnector.InitShellJavaObject();
|
||
androidConnector.RequestPermission();
|
||
Debug.Log("TrueGear蓝牙初始化完成");
|
||
|
||
// 初始化完成后自动开始搜索设备
|
||
StartScanTrueGear();
|
||
}
|
||
|
||
public void StartRequestTrueGear()
|
||
{
|
||
TruegearAndroidConnector androidConnector = new TruegearAndroidConnector();
|
||
androidConnector.InitShellJavaObject();
|
||
androidConnector.RequestPermission();
|
||
Debug.Log("开始连接");
|
||
StartCoroutine(TrueGearAndroidConnector());
|
||
}
|
||
|
||
public bool isGetConnect;
|
||
|
||
private int isAvailableIndex = 0;
|
||
private int GetConnectIndex;
|
||
|
||
// 用于停止扫描和连接的标志
|
||
private bool shouldStopScan = false;
|
||
private Coroutine scanCoroutine;
|
||
|
||
/// <summary>
|
||
/// 停止扫描和连接
|
||
/// </summary>
|
||
public void StopScan()
|
||
{
|
||
shouldStopScan = true;
|
||
if (scanCoroutine != null)
|
||
{
|
||
StopCoroutine(scanCoroutine);
|
||
scanCoroutine = null;
|
||
}
|
||
Debug.Log("已停止TrueGear扫描和连接");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置扫描状态(当用户选择设备时调用)
|
||
/// </summary>
|
||
public void ResetScanState()
|
||
{
|
||
shouldStopScan = false;
|
||
isAvailableIndex = 20;
|
||
GetConnectIndex = 20;
|
||
}
|
||
|
||
// 设备选择相关
|
||
public int SelectedDeviceIndex { get; set; }
|
||
private List<DeviceData> scannedDevices = new List<DeviceData>();
|
||
|
||
/// <summary>
|
||
/// 获取扫描到的设备列表
|
||
/// </summary>
|
||
public List<DeviceData> GetDeviceList()
|
||
{
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
if (androidConnector == null || !androidConnector.IsAvailable())
|
||
{
|
||
return new List<DeviceData>();
|
||
}
|
||
scannedDevices = androidConnector.GetScanedDevices();
|
||
return scannedDevices;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取选中设备的地址
|
||
/// </summary>
|
||
public string GetSelectedDeviceAddress()
|
||
{
|
||
if (scannedDevices != null && SelectedDeviceIndex >= 0 && SelectedDeviceIndex < scannedDevices.Count)
|
||
{
|
||
return scannedDevices[SelectedDeviceIndex].address;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据索引连接指定设备
|
||
/// </summary>
|
||
public void ConnectToDeviceByIndex(int index)
|
||
{
|
||
if (scannedDevices == null || index < 0 || index >= scannedDevices.Count)
|
||
{
|
||
Debug.LogWarning("无效的设备索引");
|
||
return;
|
||
}
|
||
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
if (androidConnector == null || !androidConnector.IsAvailable())
|
||
{
|
||
Debug.LogWarning("TrueGear 蓝牙不可用");
|
||
return;
|
||
}
|
||
|
||
DeviceData device = scannedDevices[index];
|
||
bool connected = androidConnector.ConnectToDevice(device.address);
|
||
if (connected)
|
||
{
|
||
Debug.Log($"成功连接设备: {device.name} - {device.address}");
|
||
isGetConnect = true;
|
||
SelectedDeviceIndex = index;
|
||
ChangeElectricalLevel();
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning($"设备连接失败: {device.name} - {device.address}");
|
||
}
|
||
}
|
||
IEnumerator TrueGearAndroidConnector()
|
||
{
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
bool res = androidConnector.IsAvailable();
|
||
Debug.Log("蓝牙是否授权成功:"+res);
|
||
while (!res&& isAvailableIndex>0)
|
||
{
|
||
yield return new WaitForSeconds(1f);
|
||
Debug.Log("蓝牙尝试连接中....");
|
||
androidConnector.InitShellJavaObject();
|
||
androidConnector.RequestPermission();
|
||
res = androidConnector.IsAvailable();
|
||
isAvailableIndex--;
|
||
}
|
||
|
||
if (isAvailableIndex <= 0)
|
||
{
|
||
Debug.Log("蓝牙授权失败");
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("蓝牙授权成功");
|
||
StartScanTrueGear();
|
||
while (!isGetConnect&& GetConnectIndex>0)
|
||
{
|
||
GetScanedDevices();
|
||
StartConnect();
|
||
yield return new WaitForSeconds(1);
|
||
Debug.Log("正在重新连接...");
|
||
GetConnectIndex--;
|
||
}
|
||
}
|
||
}
|
||
|
||
//搜索设备
|
||
public void StartScanTrueGear()
|
||
{
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
bool res = androidConnector.IsAvailable();
|
||
if (res)
|
||
androidConnector.StartScan();
|
||
Debug.Log("OnStartScanClick" + res);
|
||
}
|
||
|
||
//获取设备列表
|
||
public void GetScanedDevices()
|
||
{
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
bool res = androidConnector.IsAvailable();
|
||
Debug.Log("OnGetScanedDevicesClick" + res);
|
||
if (!res)
|
||
return;
|
||
List<DeviceData> res1 = androidConnector.GetScanedDevices();
|
||
string str = "";
|
||
foreach (var item in res1)
|
||
{
|
||
str += (string.Format("{0}, {1} ", item.name, item.address));
|
||
}
|
||
Debug.Log("OnGetScanedDevicesClick " + str);
|
||
}
|
||
|
||
//开始连接设备
|
||
public void StartConnect()
|
||
{
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
bool res = androidConnector.IsAvailable();
|
||
Debug.Log("OnStartConnectClick" + res);
|
||
if (!res)
|
||
return;
|
||
|
||
List<DeviceData> devices = androidConnector.GetScanedDevices();
|
||
if (devices == null || devices.Count == 0)
|
||
{
|
||
Debug.Log("未扫描到任何设备");
|
||
return;
|
||
}
|
||
|
||
foreach (var device in devices)
|
||
{
|
||
bool connected = androidConnector.ConnectToDevice(device.address);
|
||
if (connected)
|
||
{
|
||
Debug.Log($"成功连接设备: {device.name} - {device.address}");
|
||
isGetConnect = true;
|
||
ChangeElectricalLevel();
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning($"设备被占用或连接失败: {device.name} - {device.address}");
|
||
}
|
||
}
|
||
Debug.Log("No device found");
|
||
}
|
||
|
||
public void ChangeElectricalLevel()
|
||
{
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
bool isZD= androidConnector.ModifyElectricalPercent(80);
|
||
Debug.LogError("是否震动:"+isZD);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 断开连接
|
||
/// </summary>
|
||
public void CloseConnect()
|
||
{
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
androidConnector.DisconnectFromDevice();
|
||
}
|
||
|
||
private void OnApplicationQuit()
|
||
{
|
||
//断开连接
|
||
Debug.Log("断开连接");
|
||
#if !UNITY_EDITOR
|
||
CloseConnect();
|
||
#endif
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 触发TrueGear震动
|
||
/// </summary>
|
||
/// <param name="effectName">效果名,可自定义</param>
|
||
/// <param name="motorIndex">作用的电机ID列表</param>
|
||
/// <param name="startTime">起始时间,单位ms</param>
|
||
/// <param name="endTime">结束时间,单位ms</param>
|
||
/// <param name="startIntensity">起始强度(0-100)</param>
|
||
/// <param name="endIntensity">结束强度(0-100)</param>
|
||
/// <param name="intensityMode">强度模式:Const/Fade/FadeInAndOut</param>
|
||
/// <param name="actionType">震动位置</param>
|
||
public void PlayVibrationEffect(
|
||
string effectName,
|
||
List<int> motorIndex,
|
||
int startTime = 0,
|
||
int endTime = 300,
|
||
int startIntensity = 30,
|
||
int endIntensity = 30,
|
||
string intensityMode = "Const",
|
||
string actionType="Shake"
|
||
)
|
||
{
|
||
string indexStr = string.Join(",", motorIndex);
|
||
Debug.Log(indexStr);
|
||
string json = $@"
|
||
{{
|
||
""name"":""{effectName}"",
|
||
""uuid"":""{effectName}"",
|
||
""keep"":""False"",
|
||
""priority"": 0,
|
||
""tracks"":[{{
|
||
""start_time"":{startTime},
|
||
""end_time"":{endTime},
|
||
""stop_name"":"""",
|
||
""start_intensity"":{startIntensity},
|
||
""end_intensity"":{endIntensity},
|
||
""intensity_mode"":""{intensityMode}"",
|
||
""action_type"":""{actionType}"",
|
||
""once"":""True"",
|
||
""interval"":1,
|
||
""index"":[{indexStr}]
|
||
}}
|
||
]
|
||
}}
|
||
";
|
||
|
||
SendPlayEffectByContent(json);
|
||
}
|
||
|
||
public void SendPlayEffectByContent(string jsonStr)
|
||
{
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
bool res = androidConnector.IsAvailable();
|
||
Debug.Log("OnTestClick" + res);
|
||
if (!res)
|
||
return;
|
||
try
|
||
{
|
||
androidConnector.SendPlayEffectByContent(jsonStr);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.LogError("调用 TrueGear 崩溃保护: " + ex);
|
||
ReconnectTrueGear();
|
||
}
|
||
|
||
}
|
||
|
||
// 当检测蓝牙断开或异常时调用
|
||
void ReconnectTrueGear()
|
||
{
|
||
try
|
||
{
|
||
var conn = TruegearAndroidConnector.Instance;
|
||
conn.InitShellJavaObject();
|
||
conn.RequestPermission();
|
||
conn.StartScan();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError("重新初始化 TrueGear 失败:" + e);
|
||
}
|
||
}
|
||
|
||
public List<string> hitParts=new List<string>();
|
||
|
||
public void AddHitPart()
|
||
{
|
||
hitParts.Add("leftUp");
|
||
hitParts.Add("leftDown");
|
||
hitParts.Add("rightUp");
|
||
hitParts.Add("rightDown");
|
||
hitParts.Add("rightAim");
|
||
}
|
||
public void OnHit(bool isUp, int index,bool isArm)
|
||
{
|
||
// 如果未启用马甲功能,则跳过
|
||
if (!enableTrueGear)
|
||
{
|
||
return;
|
||
}
|
||
|
||
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
|
||
if (androidConnector == null)
|
||
{
|
||
Debug.LogWarning("TrueGear connector 为空,跳过调用");
|
||
isGetConnect = false;
|
||
return;
|
||
}
|
||
|
||
if (!androidConnector.IsAvailable())
|
||
{
|
||
Debug.LogWarning("TrueGear 蓝牙不可用或断开,跳过调用");
|
||
isGetConnect = false;
|
||
return;
|
||
}
|
||
|
||
if (!isGetConnect)
|
||
{
|
||
// 不再自动连接,只记录状态
|
||
Debug.LogWarning("TrueGear 未连接,跳过震动");
|
||
return;
|
||
}
|
||
List<int> motorIDs = new List<int>();
|
||
string hitPart= hitParts[index];
|
||
switch (hitPart)
|
||
{
|
||
case "leftUp":
|
||
motorIDs.AddRange( isUp?new int[] { 0, 1, 4,5 }: new int[] { 100, 101, 104,105 }); break;
|
||
case "leftDown":
|
||
motorIDs.AddRange(isUp?new int[] { 8, 9, 12,13 }: new int[] { 108, 109, 112,113 }); break;
|
||
case "rightUp":
|
||
motorIDs.AddRange(isUp?new int[] { 2,3,6,7}: new int[] { 102, 103, 106,107 }); break;
|
||
case "rightDown":
|
||
motorIDs.AddRange(isUp?new int[] { 10,11,14,15}: new int[] { 114, 115, 118,119 }); break;
|
||
case "rightAim":
|
||
motorIDs.AddRange(new int[] { 0,100}); break;
|
||
default:
|
||
motorIDs.Add(0); break;
|
||
}
|
||
|
||
PlayVibrationEffect(
|
||
effectName: $"Hit_{hitPart}",
|
||
motorIndex: motorIDs,
|
||
startIntensity: isArm?20:50,
|
||
endIntensity: isArm?20:50,
|
||
endTime: 400,
|
||
actionType: isArm? "Electrical" :"Shake"
|
||
);
|
||
}
|
||
} |