Files
HapticSystem/Assets/Scripts/OCES/Haptic/Handwritten/HapticSystem.cs
T

151 lines
5.8 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
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();
}
void Awake()
{
HapticSettings.Instance = this.hapticSettings;
if (Instance && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
this.ResourceLoader = gameObject.AddComponent<ResourceLoader>();
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;
}
}
}
}