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;
///
/// 是否启用TrueGear马甲功能
///
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()
{
}
///
/// 初始化TrueGear蓝牙(仅初始化,不连接)
///
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;
///
/// 停止扫描和连接
///
public void StopScan()
{
shouldStopScan = true;
if (scanCoroutine != null)
{
StopCoroutine(scanCoroutine);
scanCoroutine = null;
}
Debug.Log("已停止TrueGear扫描和连接");
}
///
/// 重置扫描状态(当用户选择设备时调用)
///
public void ResetScanState()
{
shouldStopScan = false;
isAvailableIndex = 20;
GetConnectIndex = 20;
}
// 设备选择相关
public int SelectedDeviceIndex { get; set; }
private List scannedDevices = new List();
///
/// 获取扫描到的设备列表
///
public List GetDeviceList()
{
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
if (androidConnector == null || !androidConnector.IsAvailable())
{
return new List();
}
scannedDevices = androidConnector.GetScanedDevices();
return scannedDevices;
}
///
/// 获取选中设备的地址
///
public string GetSelectedDeviceAddress()
{
if (scannedDevices != null && SelectedDeviceIndex >= 0 && SelectedDeviceIndex < scannedDevices.Count)
{
return scannedDevices[SelectedDeviceIndex].address;
}
return null;
}
///
/// 根据索引连接指定设备
///
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 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 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);
}
///
/// 断开连接
///
public void CloseConnect()
{
TruegearAndroidConnector androidConnector = TruegearAndroidConnector.Instance;
androidConnector.DisconnectFromDevice();
}
private void OnApplicationQuit()
{
//断开连接
Debug.Log("断开连接");
#if !UNITY_EDITOR
CloseConnect();
#endif
}
///
/// 触发TrueGear震动
///
/// 效果名,可自定义
/// 作用的电机ID列表
/// 起始时间,单位ms
/// 结束时间,单位ms
/// 起始强度(0-100)
/// 结束强度(0-100)
/// 强度模式:Const/Fade/FadeInAndOut
/// 震动位置
public void PlayVibrationEffect(
string effectName,
List 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 hitParts=new List();
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 motorIDs = new List();
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"
);
}
}