Files
Zombie/Assets/_Zombie/Scripts/TrueGearEffectManager.cs
2026-04-07 17:33:45 +08:00

423 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 = false;
/// <summary>
/// 是否启用TrueGear马甲功能
/// </summary>
public bool EnableTrueGear => enableTrueGear;
private void Awake()
{
Ins = this;
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蓝牙初始化完成");
}
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"
);
}
}