using GameDataEditor; using RogoDigital.Lipsync; using Spine; using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using UnityEngine; namespace Fie.Voice { public class FieVoiceController : MonoBehaviour { public delegate void FieVoiceControllerEventCallback(FieVoiceController controller); [SerializeField] private FieGameCharacter _actorCharacter; [SerializeField] private FieVoiceSpeaker _speaker; [SerializeField] public List phonemeAnimation; [SerializeField] public List emotionAnimation; private Dictionary phonemesAnimations; private Dictionary emotionsAnimations; public int phonemeTrackID; public int emotionTrackID = 1; public float restTime = 0.025f; private Dictionary _lipSyncData = new Dictionary(); private List _phonemeMarkers; private List _emotionMarkers; private AudioClip _currentAudioClip; private int _currentPhonemeMarker = -1; private int _currentEmotionMarker = -1; private int _currentFileID = -1; private float _masterTimer; private bool _isEndPreload; [CompilerGenerated] private static Comparison _003C_003Ef__mg_0024cache0; public bool isPlaying { get; private set; } public bool isPaused { get; private set; } public FieGameCharacter actorCharacter => _actorCharacter; public bool isEndPreload => _isEndPreload; public event FieVoiceControllerEventCallback startEvent; public event FieVoiceControllerEventCallback endEvent; private IEnumerator AsyncLoadVoiceDatas(GDEGameCharacterTypeData gameCharacterTypeData) { _003CAsyncLoadVoiceDatas_003Ec__Iterator0 _003CAsyncLoadVoiceDatas_003Ec__Iterator = (_003CAsyncLoadVoiceDatas_003Ec__Iterator0)/*Error near IL_0034: stateMachine*/; if (gameCharacterTypeData != null) { List voiceDataList = FieMasterData.FindMasterDataList(delegate(GDEWordScriptsListData data) { if (data.Actor.Key != gameCharacterTypeData.Key) { return false; } return true; }); if (voiceDataList.Count > 0) { foreach (GDEWordScriptsListData item in voiceDataList) { ResourceRequest loadRequest = Resources.LoadAsync(item.VoiceAssetPath); float time = 0f; if (time < 3f) { if (!loadRequest.isDone) { float num = time + Time.deltaTime; yield return (object)null; /*Error: Unable to find new state assignment for yield return*/; } LipSyncData lipSyncData = loadRequest.asset as LipSyncData; if (!(lipSyncData == null)) { _lipSyncData[item.Key] = lipSyncData; } } } _isEndPreload = true; } } yield break; IL_01c0: /*Error near IL_01c1: Unexpected return in MoveNext()*/; } private void Awake() { if (_actorCharacter == null) { Debug.LogError("FieVoiceController : An actor character not binded."); } else if (_speaker == null) { Debug.LogError("FieVoiceController : A speaker not binded."); } else { StartCoroutine(AsyncLoadVoiceDatas(_actorCharacter.getCharacterTypeData())); phonemesAnimations = new Dictionary(); emotionsAnimations = new Dictionary(); if (phonemeAnimation != null && phonemeAnimation.Count > 0) { foreach (FiePhonemeAnimationData item in phonemeAnimation) { phonemesAnimations[item.phoneme] = item.animationName; } } if (emotionAnimation != null && emotionAnimation.Count > 0) { foreach (FieEmotionAnimationData item2 in emotionAnimation) { emotionsAnimations[item2.emotion] = item2.animationName; } } } } private void Update() { if (isPlaying && !isPaused) { if (_phonemeMarkers == null) { Stop(stopAudio: false); } else { _masterTimer += Time.deltaTime; float time = _masterTimer / _currentAudioClip.length; UpdateAnimation(time); } } } private void OnDestroy() { Interrupt(); } public void Play(string voiceDataName, bool isForceSet = false) { if (_lipSyncData.ContainsKey(voiceDataName)) { PlayWithLipSyncData(_lipSyncData[voiceDataName], isForceSet); } } public void PlayWithLipSyncData(LipSyncData dataFile, bool isForceSet = false) { if (!isPlaying || isForceSet) { if (isPlaying && isForceSet) { Stop(stopAudio: true); } LoadData(dataFile); if (_actorCharacter != null && _actorCharacter.emotionController != null && dataFile.emotionData != null && dataFile.emotionData.Length > 0) { _actorCharacter.emotionController.StopAutoAnimation(); } isPlaying = true; isPaused = false; _masterTimer = 0f; SetCurrentPhoneme(0); SetCurrentEmotion(0); _speaker.audioSource.Play(); if (this.startEvent != null) { this.startEvent(this); this.startEvent = null; } } } public void Pause() { if (isPlaying && !isPaused) { isPaused = true; _speaker.audioSource.Pause(); } } public void Resume() { if (isPlaying && isPaused) { isPaused = false; _speaker.audioSource.UnPause(); } } public void Stop(bool stopAudio) { if (isPlaying) { isPlaying = false; isPaused = false; if (stopAudio) { _speaker.audioSource.Stop(); } } if (_actorCharacter != null && _actorCharacter.emotionController != null) { _actorCharacter.skeletonUtility.skeletonAnimation.state.ClearTrack(emotionTrackID); _actorCharacter.emotionController.RestoreEmotionFromDefaultData(); _actorCharacter.emotionController.RestartAutoAnimation(); } if (this.endEvent != null) { this.endEvent(this); this.endEvent = null; } } public void Interrupt() { Stop(stopAudio: true); } private void UpdateAnimation(float time) { if (_currentPhonemeMarker + 1 < _phonemeMarkers.Count) { if (time >= _phonemeMarkers[_currentPhonemeMarker + 1].time) { SetCurrentPhoneme(_currentPhonemeMarker + 1); } } else if (time >= _phonemeMarkers[_currentPhonemeMarker].time + restTime / _currentAudioClip.length) { Stop(stopAudio: false); } if (_currentEmotionMarker + 1 < _emotionMarkers.Count && time >= _emotionMarkers[_currentEmotionMarker + 1].startTime) { SetCurrentEmotion(_currentEmotionMarker + 1); } } private void UpdateEmotion(float time) { } private void SetCurrentPhoneme(int index) { if (_phonemeMarkers != null && _phonemeMarkers.Count > 0 && index < _phonemeMarkers.Count) { _currentPhonemeMarker = index; Phoneme phoneme = _phonemeMarkers[index].phoneme; if (phonemesAnimations.ContainsKey(phoneme)) { TrackEntry trackEntry = actorCharacter.skeletonUtility.skeletonAnimation.state.SetAnimation(phonemeTrackID, phonemesAnimations[phoneme], loop: false); if (trackEntry != null) { float mixDuration = 0f; if (_currentPhonemeMarker + 1 < _phonemeMarkers.Count) { mixDuration = _phonemeMarkers[_currentPhonemeMarker + 1].time - _phonemeMarkers[_currentPhonemeMarker].time; } trackEntry.mixDuration = mixDuration; } } } } private void SetCurrentEmotion(int index) { if (_emotionMarkers != null && _emotionMarkers.Count > 0 && index < _emotionMarkers.Count) { _currentEmotionMarker = index; string emotion = _emotionMarkers[index].emotion; if (emotionsAnimations.ContainsKey(emotion)) { TrackEntry trackEntry = actorCharacter.skeletonUtility.skeletonAnimation.state.SetAnimation(emotionTrackID, emotionsAnimations[emotion], loop: false); if (trackEntry != null) { trackEntry.mixDuration = 0.2f; } } } } private bool LoadData(LipSyncData dataFile) { if (dataFile.phonemeData.Length > 0 || dataFile.emotionData.Length > 0) { _currentAudioClip = dataFile.clip; _phonemeMarkers = new List(); _emotionMarkers = new List(); PhonemeMarker[] phonemeData = dataFile.phonemeData; foreach (PhonemeMarker item in phonemeData) { _phonemeMarkers.Add(item); } EmotionMarker[] emotionData = dataFile.emotionData; foreach (EmotionMarker item2 in emotionData) { _emotionMarkers.Add(item2); } _phonemeMarkers.Sort(SortTime); _speaker.audioSource.clip = _currentAudioClip; _currentFileID = dataFile.GetInstanceID(); return true; } Debug.Log("A LipSync Data dosen't exist : " + dataFile.ToString()); return false; } private static int SortTime(PhonemeMarker a, PhonemeMarker b) { float time = a.time; float time2 = b.time; return time.CompareTo(time2); } } }