167 lines
6.3 KiB
C#
167 lines
6.3 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Lofelt.NiceVibrations;
|
|
using UnityEngine;
|
|
|
|
namespace OCES.Haptic
|
|
{
|
|
public class HapticSystem : MonoBehaviour
|
|
{
|
|
public static HapticSystem Instance {get; private set;}
|
|
[NonSerialized]
|
|
public bool IsHapticSupported;
|
|
[NonSerialized]
|
|
public bool IsMeetsAdvanceRequirements;
|
|
[SerializeField]
|
|
HapticSettings hapticSettings;
|
|
|
|
|
|
internal ResourceLoader ResourceLoader;
|
|
|
|
HapticObjectConfig m_hapticObjects;
|
|
|
|
public void Play(uint hapticId, bool isDirectCall = true)
|
|
{
|
|
HapticObject hapticObject = this.m_hapticObjects.QueryById(hapticId);
|
|
if (hapticObject != null)
|
|
{
|
|
Play(hapticObject);
|
|
if (isDirectCall)
|
|
{
|
|
Debug.LogWarning($"[Haptic System] Playing haptic id {hapticId} without play audio." +
|
|
"This method should only be called during debugging.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("[Haptic System] Could not find Haptic Object with id: " + hapticId);
|
|
}
|
|
|
|
}
|
|
|
|
public void Play(HapticObject hapticObject)
|
|
{
|
|
switch (hapticObject.Type)
|
|
{
|
|
case HapticType.Preset:
|
|
if (Enum.TryParse(hapticObject.Payload, out HapticPatterns.PresetType hapticPattern))
|
|
{
|
|
HapticPatterns.PlayPreset(hapticPattern);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"[Haptic System] Could not parse haptic pattern: {hapticObject.Payload}]");
|
|
}
|
|
break;
|
|
case HapticType.Emphasis:
|
|
if (hapticObject.Amplitude < 0f || hapticObject.Frequency < 0f)
|
|
{
|
|
Debug.LogWarning($"[Haptic System] Haptic {hapticObject.Id} have no amplitude or frequency." +
|
|
"Please check the datatable.");
|
|
break;
|
|
}
|
|
HapticPatterns.PlayEmphasis(hapticObject.Amplitude, hapticObject.Frequency);
|
|
break;
|
|
case HapticType.Constant:
|
|
if (hapticObject.Amplitude < 0f || hapticObject.Frequency < 0f || hapticObject.Duration < 0f)
|
|
{
|
|
Debug.LogWarning($"[Haptic System] Haptic {hapticObject.Id} have no amplitude, frequency or duration." +
|
|
"Please check the datatable.");
|
|
break;
|
|
}
|
|
HapticController.Stop();
|
|
HapticPatterns.PlayConstant(hapticObject.Amplitude, hapticObject.Frequency, hapticObject.Duration);
|
|
break;
|
|
case HapticType.Advance:
|
|
if (Enum.TryParse(hapticObject.FallbackPreset, out HapticPatterns.PresetType fallbackPreset))
|
|
{
|
|
HapticController.fallbackPreset = fallbackPreset;
|
|
HapticClip hapticClip = GetHapticClip(hapticObject);
|
|
if (hapticClip)
|
|
{
|
|
HapticController.Stop();
|
|
HapticController.Play(hapticClip);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"[Haptic System] Could not parse haptic file: {hapticObject.Payload}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"[Haptic System] Could not parse fallback preset: {hapticObject.FallbackPreset}]");
|
|
}
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
|
|
}
|
|
|
|
public void Stop(uint? hapticId = null)
|
|
{
|
|
HapticController.Stop();
|
|
}
|
|
|
|
public void EnableHaptic(bool enable)
|
|
{
|
|
HapticController.hapticsEnabled = enable;
|
|
}
|
|
|
|
void Awake()
|
|
{
|
|
HapticSettings.Instance = this.hapticSettings;
|
|
|
|
if (Instance && Instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
Instance = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
|
|
this.ResourceLoader = gameObject.AddComponent<ResourceLoader>();
|
|
if (HapticSettings.Instance.useAssetBundle)
|
|
{
|
|
string bundlePath = Path.Combine(Application.streamingAssetsPath,
|
|
HapticSettings.Instance.hapticBundlePath);
|
|
this.ResourceLoader.SetProvider(new AssetBundleAssetProvider(bundlePath));
|
|
}
|
|
else
|
|
{
|
|
this.ResourceLoader.SetProvider(new ResourcesAssetProvider());
|
|
}
|
|
|
|
this.m_hapticObjects = HapticConfigLoader.Load<HapticObjectConfig>(HapticSettings.Instance.hapticConfigPath + "HapticObject");
|
|
this.IsHapticSupported = DeviceCapabilities.isVersionSupported;
|
|
this.IsMeetsAdvanceRequirements = DeviceCapabilities.meetsAdvancedRequirements;
|
|
}
|
|
|
|
static HapticClip GetHapticClip(HapticObject hapticObject)
|
|
{
|
|
return Instance.ResourceLoader.LoadSync<HapticClip>(HapticSettings.Instance.hapticResourcePath + hapticObject.Payload);
|
|
}
|
|
|
|
static class HapticConfigLoader
|
|
{
|
|
internal static T Load<T>(string tableName) where T : IBinarySerializable, new()
|
|
{
|
|
TextAsset bytes = Instance.ResourceLoader.LoadSync<TextAsset>(tableName);
|
|
if (!bytes)
|
|
{
|
|
Debug.LogError($"未找到表 {tableName}");
|
|
return default;
|
|
}
|
|
IBinarySerializable data = new T();
|
|
bool readOk = FileManager.ReadBinaryDataFromBytes(bytes.bytes, ref data);
|
|
if (readOk)
|
|
return (T)data;
|
|
Debug.LogError($"{tableName} 解析出错,类型 {typeof(T)}");
|
|
return default;
|
|
}
|
|
}
|
|
}
|
|
}
|