//Log Dir http://docs.unity3d.com/Manual/LogFiles.html using UnityEngine; using System.Collections; using System.Collections.Generic; using System; using System.IO; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using UnityEngine.UI; public abstract class GenericPlayerManager : MonoBehaviour { private const string DEFAULT_ANIMATION = "_default"; private const string NONE_ANIMATION = "_defaultWORD"; protected float fadeLength = 0.6F; protected string glosa = ""; private static String[] stringPos = { DEFAULT_ANIMATION };//vetor que sera usado para quebrar a glosa private GameObject AVATAR; private Animation COMPONENT_ANIMATION; private BoxCollider AVATAR_COLLIDER; public Text SUBTITLES; // Guarda os nomes das palavras ja carregadas. private HashSet loadedAssetBundles = new HashSet(); // Guarda os nomes das palavras que nao tem assetbundle. private HashSet nonexistentAssetBundles = new HashSet(); // Lista de animações sendo reproduzidas. // Utilizada para alterar velocidade e apresentar a legenda. private volatile Queue animQueue = new Queue(); private volatile bool loadingSingleAnimation = false; private volatile bool loading = false; private volatile bool playing = false; private volatile bool paused = false; private Stopwatch watch = new Stopwatch(); private string lastRandom = ""; private int repeated = 0; private Subtitle subtitle; public virtual void Start() { subtitle = new Subtitle(SUBTITLES); subtitle.DefaultWordSpeed = new DefaultSignSpeed(); subtitle.DefaultFirstLetterSpeed = new DefaultSignSpeed(2.1F, 2.8F); subtitle.DefaultLetterSpeed = new DefaultSignSpeed(3F, 4.3F); subtitle.DefaultNumberSpeed = new DefaultSignSpeed(1.5F, 2.9F); AVATAR = GameObject.FindGameObjectWithTag("avatar");//referencia para o avatar COMPONENT_ANIMATION = AVATAR.GetComponent();//referencia para o componente animador do avatar AVATAR_COLLIDER = GameObject.FindGameObjectWithTag("avatar").GetComponent(); watch.Start(); Invoke("playRandomAnimation", 5); } public bool isLoadingSingleAnimation() { return loadingSingleAnimation; } public bool isLoading() { return loading; } public bool isPlaying() { return playing; } public bool isPaused() { return paused; } private void stopWatch() { watch.Stop(); watch.Reset(); } private void continueWatch() { watch.Start(); } private void playRandomAnimation(string glosa) { stopWatch(); this.glosa = glosa; this.play(); } private void playRandomAnimation() { if (watch.Elapsed.Seconds >= 1) { int rand = new System.Random().Next(3); switch (rand) { case 0: playRandomAnimation("[OLA]"); break; case 1: playRandomAnimation("[OI]"); break; case 2: playRandomAnimation("[IAE]"); break; } } Invoke("playRandomAnimation", 1); } public void SetAvatarCollider(bool isActive) { AVATAR_COLLIDER.enabled = isActive; } protected virtual void setSubtitle(string text) { SUBTITLES.text = text; } // Define a velocidade das animacões com base no slider da GUI public void setSlider(float sliderPosition) { subtitle.SliderPosition = sliderPosition; subtitle.updateWordSpeed(); subtitle.updateLetterSpeed(); subtitle.updateNumberSpeed(); if ( ! paused) foreach (AnimationReference reference in animQueue) if (reference.type != Subtitle.TYPE_NONE && reference.state != null) reference.state.speed = getSpeedByType(reference.type); } private float getSpeedByType(short type) { switch (type) { case Subtitle.TYPE_WORD: return subtitle.WordSpeed; case Subtitle.TYPE_LETTER: return subtitle.LetterSpeed; case Subtitle.TYPE_NUMBER: return subtitle.NumberSpeed; } return 2F; } public void stop_animations() { StopCoroutine("loadAndPlay"); loading = false; playing = false; paused = false; onPlayingStateChange(); stopAnimations(); } public void stopAnimations() { try { StopCoroutine("handleStates"); } catch (NullReferenceException nre) { UnityEngine.Debug.Log("StopCoroutine handlestates nullreff::"+nre.ToString()); } setSubtitle(""); try { animQueue.Clear(); } catch (NullReferenceException nre) { UnityEngine.Debug.Log("SetQueueList null reff::"+nre.ToString()); } COMPONENT_ANIMATION.Stop(); COMPONENT_ANIMATION.CrossFade(DEFAULT_ANIMATION, fadeLength, PlayMode.StopAll); } /* * Manda reproduzir animação e adiciona a file de animações a serem reproduzidas. */ private AnimationState playAnimation(short type, string name, string subtitle, float speed) { try { AnimationState state = COMPONENT_ANIMATION.CrossFadeQueued(name, fadeLength, QueueMode.CompleteOthers); state.speed = speed; animQueue.Enqueue(new AnimationReference(name, subtitle, state, type)); return state; } catch (NullReferenceException nre) { UnityEngine.Debug.Log("'" + name + "' não foi encontrado!\n" + nre.ToString()); } return null; } private AnimationState playAnimation(short type, string name, string subtitle) { return playAnimation(type, name, subtitle, getSpeedByType(type)); } private AnimationState playAnimation(short type, string name) { return playAnimation(type, name, name); } /** * Returns the asset bundle named aniName. * * @return AssetBundle - se for encontrado. * null - se ocorrer num erro. */ protected abstract WWW loadAssetBundle(string aniName); /** * Listen to changes in the playing status. */ protected abstract void onPlayingStateChange(); public void switchPauseState(bool paused) { if (this.paused != paused) { this.paused = paused; foreach (AnimationReference reference in animQueue) if (reference.state != null) reference.state.speed = paused ? 0F : getSpeedByType(reference.type); onPlayingStateChange(); } } public void switchPauseState() { switchPauseState( ! paused); } public bool play() { if (playing) switchPauseState(); else play(true, true, true); return true; } public bool play(bool stopLoading, bool stopPlaying, bool forceLoading) { try { if (loading) { if (stopLoading) stop_animations(); else return false; } else if (playing) { if (stopPlaying) stopAnimations(); else if ( ! forceLoading) return false; } } catch (NullReferenceException nre) { nre.ToString(); } StartCoroutine("loadAndPlay"); return true; } /** * Spells word. * * @return last animation's subtitle. */ private string spellWord(string word) { string lastAnimationSubtitle = ""; bool defaultPlayed = false; // A reprodução da primeira letra deve ser longa para não ser cortada no fade subtitle.updateLetterSpeed(); for (int i = 0; i < word.Length; i++) { char second = word[i]; lastAnimationSubtitle = Subtitle.highlight(word, i); // Se for uma letra if (second >= 65 && second <= 90) playAnimation(Subtitle.TYPE_LETTER, second.ToString(), lastAnimationSubtitle, subtitle.LetterSpeed); // Se for um número else if (second >= 48 && second <= 57) playAnimation(Subtitle.TYPE_NUMBER, second.ToString(), lastAnimationSubtitle, subtitle.NumberSpeed); // Se for uma vírgula else if (second == 44) playAnimation(Subtitle.TYPE_WORD, second.ToString(), lastAnimationSubtitle); // Não há animação else { // Reproduz animação default apenas uma vez if ( ! defaultPlayed) { defaultPlayed = true; playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle); // A reprodução da próxima letra deve ser longa para não ser cortada no fade subtitle.updateLetterSpeed(); } UnityEngine.Debug.Log("Animação \"" + second + "\" inexistente."); continue; } defaultPlayed = false; subtitle.updateLetterSpeed(); } return lastAnimationSubtitle; } protected IEnumerator loadAnimation(string name) { loadingSingleAnimation = true; // Função loadAssetBundle é definida pela classe filha WWW www = loadAssetBundle(name); if (www != null) { yield return www; AssetBundle bundle = null; if (www.error == null) bundle = www.assetBundle; if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name)) { AnimationClip aniClip = bundle.mainAsset as AnimationClip; bundle.Unload(false); if (aniClip) { COMPONENT_ANIMATION.AddClip(aniClip, name); // Reproduz palavra loadedAssetBundles.Add(name); yield break; } else UnityEngine.Debug.Log ("Sinal \"" + name + "\" não carregado corretamente."); } } // Soletra palavra nonexistentAssetBundles.Add(name); loadingSingleAnimation = false; } private bool isFlag(string animationName) { return animationName.Equals("[PONTO]") || animationName.Equals("[INTERROGACAO]") || animationName.Equals("[EXCLAMACAO]") || animationName.Equals("[OLA]") || animationName.Equals("[OI]") || animationName.Equals("[IAE]"); } private IEnumerator loadAndPlay() { loading = true; onPlayingStateChange(); string lastAnimationSubtitle = ""; bool spelled = false; // Default playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", 2F); if ( ! playing) { playing = true; StartCoroutine("handleStates"); } stringPos = glosa.Split(' '); foreach (string aniName in stringPos) { try { if (String.IsNullOrEmpty(aniName)) continue; } catch (Exception e) { UnityEngine.Debug.Log(e + " :: NotNullNotEmpty"); } bool nonexistent = nonexistentAssetBundles.Contains(aniName); bool loaded = loadedAssetBundles.Contains(aniName); if ( ! nonexistent && ! loaded) { // Função loadAssetBundle é definida pela classe filha WWW www = loadAssetBundle(aniName); if (www != null) { yield return www; AssetBundle bundle = null; if (www.error == null) bundle = www.assetBundle; if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name)) { AnimationClip aniClip = bundle.mainAsset as AnimationClip; bundle.Unload(false); if (aniClip) { COMPONENT_ANIMATION.AddClip(aniClip, aniName); loadedAssetBundles.Add(aniName); loaded = true; } else UnityEngine.Debug.Log ("Sinal \"" + aniName + "\" não carregado corretamente."); } } } // Reproduz palavra if (loaded) { if (spelled) { // Default playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle); spelled = false; } //bool isFlag = false; //if (aniName[0] == '[') //{ if (isFlag(aniName)) { //isFlag = true; lastAnimationSubtitle = ""; playAnimation(Subtitle.TYPE_WORD, aniName, ""); } else { lastAnimationSubtitle = aniName; playAnimation(Subtitle.TYPE_WORD, aniName); } //} /*if (isFlag) playAnimation(Subtitle.TYPE_WORD, aniName, ""); else playAnimation(Subtitle.TYPE_WORD, aniName);*/ } // Soletra palavra else { // Se a animação não foi carregada e nem está marcada como não existente, // adiciona ao set de animações não existentes if ( ! nonexistent) nonexistentAssetBundles.Add(aniName); UnityEngine.Debug.Log("~~ To spell: " + aniName); if (isFlag(aniName)) { playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", 1.6F); continue; } // Se já houve o soletramento de alguma palavra, reproduz animação default if (spelled) playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle, 1.6F); else spelled = true; lastAnimationSubtitle = spellWord(aniName); } } // Default playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, ""); loading = false; onPlayingStateChange(); } //int _id = 0; /* * Sincroniza as legendas com as animações. */ IEnumerator handleStates() { stopWatch(); // Enquanto estiver executando a rotina "loadAndPlay" // ou existir animações na fila de reprodução while (loading || animQueue.Count > 0) { if (animQueue.Count > 0) { AnimationReference reference = animQueue.Peek(); setSubtitle(reference.subtitle); while (COMPONENT_ANIMATION.IsPlaying(reference.name)) { reference.playing = true; yield return null; } if (reference.state == null) animQueue.Dequeue(); else yield return null; } else yield return null; setSubtitle(""); } playing = false; paused = false; onPlayingStateChange(); continueWatch(); } }