230 lines
5.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Android;
#region Enums
public enum EViaggioAIState
{
StartingUp = 0,
Idle = 10,
IntentRecognition = 20,
Conversation = 30,
}
#endregion
public class ViaggioAIManager : MonoBehaviour
{
#region Inspector Properties
[Header("Config Values")]
[SerializeField]
private bool debugModeIsActive;
[SerializeField]
public bool soundEffectsEnabled;
[Header("Scene Objects")]
[SerializeField]
private AudioSource audioSource;
[SerializeField]
private GameObject servicesContainer;
[SerializeField]
private GameObject debugContent;
[Header("Services")]
[SerializeField]
public IntentRecognitionService IntentRecognitionService;
[SerializeField]
public ConversationService ConversationService;
[SerializeField]
public SpeechRecognitionService SpeechRecognitionService;
[SerializeField]
public SpeechSynthesizerService SpeechSynthesizerService;
[SerializeField]
public APIService APIService;
#endregion
#region Public Properties
#region Singleton
public static ViaggioAIManager Instance { get; private set; }
#endregion
public string SessionUID { get; private set; }
#region ViaggioAIState
private EViaggioAIState _viaggioAIState = EViaggioAIState.Idle;
public EViaggioAIState ViaggioAIState
{
get { return this._viaggioAIState; }
private set
{
if (value != this._viaggioAIState)
{
this.LogIfInDebugMode("ViaggioAIState changed, new value= " + value);
this._viaggioAIState = value;
if (this.OnViaggioAIStateChangedEvent != null)
{
this.OnViaggioAIStateChangedEvent.Invoke(this, value);
}
}
}
}
public event EventHandler<EViaggioAIState> OnViaggioAIStateChangedEvent;
#endregion
#endregion
#region Private Properties
private float initDelay = 0.5f;
#endregion
#region Framework Functions
void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
return;
}
Instance = this;
// Check if SessionGUID is already set, if not generate a new one
if (string.IsNullOrEmpty(SessionGUID.identifier))
{
SessionGUID.identifier = System.Guid.NewGuid().ToString();
this.LogIfInDebugMode($"Session UID generated: {SessionGUID.identifier}");
}
else
{
this.LogIfInDebugMode($"Session UID already exists: {SessionGUID.identifier}");
}
this.SessionUID = SessionGUID.identifier;
}
void OnEnable()
{
this.initWithDelay();
}
#endregion
#region Private Events
#endregion
#region Public Events
public event EventHandler<string> OnViaggioAIErrorEvent;
public void RaiseViaggioAIError(string error)
{
this.OnViaggioAIErrorEvent?.Invoke(this, error);
}
#endregion
#region Public Functions
public void StartIntentRecognition(Dictionary<string, string> possibleIntents)
{
this.ViaggioAIState = EViaggioAIState.IntentRecognition;
this.IntentRecognitionService.StartIntentRecognition(possibleIntents);
}
public void SetSpeechRecognitionLanguage(string languageCode)
{
this.LogIfInDebugMode($"ViaggioAIManager: Set speech language to {languageCode}");
this.SpeechRecognitionService.SetRecognitionLanguage(languageCode);
}
public void StopIntentRecognition()
{
this.IntentRecognitionService.StopIntentRecognition();
this.ViaggioAIState = EViaggioAIState.Idle;
}
public void SynthesizeText(string text, string languageCode, string voiceNameOverride = null)
{
this.SpeechSynthesizerService.Synthesize(text, languageCode, voiceNameOverride);
}
public void StartConversation(string languageCode, string instructions, string context, int maxRoundtrips, float maxSilenceBeforeTimeOut, string outroText)
{
this.ViaggioAIState = EViaggioAIState.Conversation;
this.ConversationService.StartConversation(languageCode, instructions, context, maxRoundtrips, maxSilenceBeforeTimeOut, outroText);
}
public void StopConversation()
{
this.ConversationService.StopConversation();
this.ViaggioAIState = EViaggioAIState.Idle;
}
public void PlayAudioIfEnabled(AudioClip clip)
{
if (!this.soundEffectsEnabled)
{
return;
}
this.audioSource.PlayOneShot(clip);
}
public void LogIfInDebugMode(string message)
{
if (!this.debugModeIsActive)
{
return;
}
Debug.Log($"(ViaggioAI) => {message}");
}
#endregion
#region Private Functions
private async void initWithDelay()
{
this.ViaggioAIState = EViaggioAIState.StartingUp;
this.debugContent.SetActive(this.debugModeIsActive);
await Task.Delay(TimeSpan.FromSeconds(this.initDelay));
this.servicesContainer.SetActive(true);
this.ViaggioAIState = EViaggioAIState.Idle;
}
#endregion
}