diff --git a/Assets/Scenes/UI_disabled.unity b/Assets/Scenes/UI_disabled.unity index 9c13b44..89c6bd7 100644 --- a/Assets/Scenes/UI_disabled.unity +++ b/Assets/Scenes/UI_disabled.unity @@ -807,6 +807,10 @@ Prefab: propertyPath: avatarCollider value: objectReference: {fileID: 1772849664} + - target: {fileID: 11427452, guid: cd81d95d2fa8dc448b18a415b9009d43, type: 2} + propertyPath: fadeLength + value: 0.5 + objectReference: {fileID: 0} m_RemovedComponents: [] m_ParentPrefab: {fileID: 100100000, guid: cd81d95d2fa8dc448b18a415b9009d43, type: 2} m_IsPrefabParent: 0 diff --git a/Assets/Scripts/GenericPlayerManager.txt b/Assets/Scripts/GenericPlayerManager.txt deleted file mode 100644 index 7f66bc2..0000000 --- a/Assets/Scripts/GenericPlayerManager.txt +++ /dev/null @@ -1,605 +0,0 @@ -//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 UnityEngine.UI; - -public abstract class GenericPlayerManager : MonoBehaviour { - - private class AnimationReference - { - public string name; - public string subtitle; - public AnimationState state; - public short type; - public bool playing; - - public AnimationReference(string name, string subtitle, AnimationState state, short type) - { - this.name = name; - this.subtitle = subtitle; - this.state = state; - this.type = type; - this.playing = false; - } - } - - protected class DefaultSignSpeed - { - public static float DEFAULT = 1.1F; - public static float DEFAULT_MAX = 2F; - - private float speed; - private float max; - // Relação entre a velocidade do tipo representado e a velocidade DEFAULT. - private float unit; - - public DefaultSignSpeed() - { - this.speed = DEFAULT; - this.max = DEFAULT_MAX; - this.unit = 1F; - } - - public DefaultSignSpeed(float defaultSpeed, float defaultMaxSpeed) - { - this.speed = defaultSpeed; - this.max = defaultMaxSpeed; - this.unit = (this.max - this.speed) / (DEFAULT_MAX - DEFAULT); - } - - public float Speed { - get { return this.speed; } - set { - this.speed = value; - this.unit = calculateUnit(); - } - } - public float Max { - get { return this.max; } - set { - this.speed = value; - this.unit = calculateUnit(); - } - } - public float Unit { - get { return this.unit; } - } - - private float calculateUnit() - { - return (this.max - this.speed) / (DEFAULT_MAX - DEFAULT); - } - - /* - * Retorna velocidade em relação ao estado do slider. - * @param slider - estado do slider (valor entre DefaultSignSpeed.DEFAULT e DefaultSignSpeed.DEFAULT_MAX) - */ - public float getProporcionalSpeed(float slider) - { - return this.speed + (slider - DEFAULT) * this.unit; - } - } - - private const string DEFAULT_ANIMATION = "_default"; - private const string NONE_ANIMATION = "_defaultWORD"; - - protected float fadeLength = 0.6F; - - protected DefaultSignSpeed defaultWordSpeed = new DefaultSignSpeed(); - protected DefaultSignSpeed defaultFirstLetterSpeed = new DefaultSignSpeed(2.1F, 2.8F); - protected DefaultSignSpeed defaultLetterSpeed = new DefaultSignSpeed(3F, 4.3F); - protected DefaultSignSpeed defaultNumberSpeed = new DefaultSignSpeed(1.5F, 2.9F); - - private const short TYPE_NONE = -1; - private const short TYPE_WORD = 0; - private const short TYPE_LETTER = 1; - private const short TYPE_NUMBER = 2; - - private float hSlidersecond = DefaultSignSpeed.DEFAULT; - private float wordSpeed = DefaultSignSpeed.DEFAULT; - private float letterSpeed = DefaultSignSpeed.DEFAULT; - private float numberSpeed = DefaultSignSpeed.DEFAULT; - - 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; - - public virtual void Start() - { - this.wordSpeed = this.defaultWordSpeed.Speed; - this.letterSpeed = this.defaultLetterSpeed.Speed; - this.numberSpeed = this.defaultNumberSpeed.Speed; - - this.AVATAR = GameObject.FindGameObjectWithTag("avatar");//referencia para o avatar - this.COMPONENT_ANIMATION = AVATAR.GetComponent();//referencia para o componente animador do avatar - this.AVATAR_COLLIDER = GameObject.FindGameObjectWithTag("avatar").GetComponent(); - } - - public bool isLoadingSingleAnimation() { return loadingSingleAnimation; } - public bool isLoading() { return loading; } - public bool isPlaying() { return playing; } - public bool isPaused() { return paused; } - - /* Ativar ou desativar o colisor do avatar */ - public void SetAvatarCollider(bool isActive) { - this.AVATAR_COLLIDER.enabled = isActive; - } - - /* Mudar legenda */ - protected virtual void setSubtitle(string text) { - this.SUBTITLES.text = text; - } - - /* Define a velocidade das animacões com base no slider da GUI */ - public void setSlider(float x) - { - this.hSlidersecond = x; - - this.wordSpeed = this.defaultWordSpeed.getProporcionalSpeed(x); - this.letterSpeed = this.defaultLetterSpeed.getProporcionalSpeed(x); - this.numberSpeed = this.defaultNumberSpeed.getProporcionalSpeed(x); - - if ( ! paused) - foreach (AnimationReference reference in this.animQueue) - if (reference.type != TYPE_NONE && reference.state != null) - reference.state.speed = getSpeedByType(reference.type); - } - - private float getSpeedByType(short type) - { - switch (type) - { - case TYPE_WORD: return this.wordSpeed; - case TYPE_LETTER: return this.letterSpeed; - case TYPE_NUMBER: return this.numberSpeed; - } - - return 2F; - } - - - public void stopAll() - { - StopCoroutine("loadAndPlay"); - - this.loading = false; - - stopAnimations(); - } - - void stopAnimations() - { - try { - StopCoroutine("handleStates"); - } catch (NullReferenceException nre) { Debug.Log("StopCoroutine handlestates nullreff::"+nre.ToString()); } - - setSubtitle(""); - - try { - animQueue.Clear(); - } catch (NullReferenceException nre) { Debug.Log("SetQueueList null reff::"+nre.ToString()); } - - COMPONENT_ANIMATION.Stop(); - COMPONENT_ANIMATION.CrossFade(DEFAULT_ANIMATION, fadeLength, PlayMode.StopAll); - - this.playing = false; - this.paused = false; - onPlayingStateChange(); - } - - /* - * Manda reproduzir animação e adiciona a file de animações a serem reproduzidas. - * - * Caso não haja SUBTITLE, name será utilizado como SUBTITLE. - * Caso não haja fadeLength, será atribuido fadeLength. - * Caso não haja velocidade, hSlidersecond será atribuída. - */ - 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) - { - 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) - { - Debug.Log("switch to: " + (paused ? "paused" : "playing")); - - 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( ! this.paused); - } - - public bool play() - { - if (playing) - switchPauseState(); - else - play(true, true, true); - - return true; - } - - public bool play(bool stopLoading, bool stopPlaying, bool forceLoading) - { - if (loading) - { - if (stopLoading) - stopAll(); - else - return false; - } - else if (playing) - { - if (stopPlaying) - stopAnimations(); - - else if ( ! forceLoading) - return false; - } - - StartCoroutine("loadAndPlay"); - return true; - } - - - /* - * Destaca caractere de uma string. - */ - private string highlight(string word, int index) - { - string subtitle = ""; - int last = 0; - - if (index == 0) - //subtitle += "" + word[0] + ""; - subtitle += "" + word[0] + ""; - else - subtitle += word[0]; - - for (int i = 1; i < word.Length; i++) - { - if ((word[i] >= 65 && word[i] <= 90) || (word[i] >= 48 && word[i] <= 57)) - subtitle += "-"; - - if (i == index || (last == index && word[i] == word[last])) - { - //subtitle += "" + word[i] + ""; - subtitle += "" + word[i] + ""; - if (i == index) last = i; - } - else - { - subtitle += word[i]; - last = i; - } - } - - return subtitle; - } - - /** - * 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 - letterSpeed = defaultLetterSpeed.getProporcionalSpeed(hSlidersecond); - - for (int i = 0; i < word.Length; i++) - { - char second = word[i]; - lastAnimationSubtitle = highlight(word, i); - - // Se for uma letra - if (second >= 65 && second <= 90) - playAnimation(TYPE_LETTER, second.ToString(), lastAnimationSubtitle, letterSpeed); - - // Se for um número - else if (second >= 48 && second <= 57) - playAnimation(TYPE_NUMBER, second.ToString(), lastAnimationSubtitle, numberSpeed); - - // Se for uma vírgula - else if (second == 44) - playAnimation(TYPE_WORD, second.ToString(), lastAnimationSubtitle); - - // Não há animação - else - { - // Reproduz animação default apenas uma vez - if ( ! defaultPlayed) - { - defaultPlayed = true; - playAnimation(TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle); - - // A reprodução da próxima letra deve ser longa para não ser cortada no fade - letterSpeed = defaultLetterSpeed.getProporcionalSpeed(hSlidersecond); - } - - Debug.Log("Animação \"" + second + "\" inexistente."); - continue; - } - - defaultPlayed = false; - letterSpeed = defaultLetterSpeed.getProporcionalSpeed(hSlidersecond); - } - - 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 Debug.Log ("Sinal \"" + name + "\" não carregado corretamente."); - } - } - - // Soletra palavra - nonexistentAssetBundles.Add(name); - - loadingSingleAnimation = false; - } - - - private IEnumerator loadAndPlay() - { - loading = true; - onPlayingStateChange(); - - string lastAnimationSubtitle = ""; - bool spelled = false; - - // Default - playAnimation(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) { - 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 Debug.Log ("Sinal \"" + aniName + "\" não carregado corretamente."); - } - } - } - - // Reproduz palavra - if (loaded) - { - if (spelled) - { - // Default - playAnimation(TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle); - spelled = false; - } - - bool isPunctuation = false; - - if (aniName[0] == '[') - { - if (aniName.Equals("[PONTO]") || aniName.Equals("[INTERROGACAO]") || aniName.Equals("[EXCLAMACAO]")) - { - isPunctuation = true; - lastAnimationSubtitle = ""; - } - else - { - lastAnimationSubtitle = aniName; - } - } - - if (isPunctuation) - playAnimation(TYPE_WORD, aniName, lastAnimationSubtitle); - else - playAnimation(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); - - Debug.Log("~~ To spell: " + aniName); - - if (aniName.Equals("[PONTO]") || aniName.Equals("[INTERROGACAO]") || aniName.Equals("[EXCLAMACAO]")) - { - playAnimation(TYPE_NONE, DEFAULT_ANIMATION, "", 1.6F); - continue; - } - - // Se já houve o soletramento de alguma palavra, reproduz animação default - if (spelled) - playAnimation(TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle, 1.6F); - else - spelled = true; - - lastAnimationSubtitle = spellWord(aniName); - } - } - - // Default - playAnimation(TYPE_NONE, DEFAULT_ANIMATION, ""); - - loading = false; - onPlayingStateChange(); - } - - //int _id = 0; - - /* - * Sincroniza as legendas com as animações. - */ - IEnumerator handleStates() - { - // 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(); - } - -} diff --git a/Assets/Scripts/GenericPlayerManager.txt.meta b/Assets/Scripts/GenericPlayerManager.txt.meta deleted file mode 100644 index 9661f46..0000000 --- a/Assets/Scripts/GenericPlayerManager.txt.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8eb75e5e1bed9744c97d6ee131d4ab3b -timeCreated: 1457721853 -licenseType: Pro -TextScriptImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/Player Manager/GenericPlayerManager.cs b/Assets/Scripts/Player Manager/GenericPlayerManager.cs index 558811e..c50bdcb 100644 --- a/Assets/Scripts/Player Manager/GenericPlayerManager.cs +++ b/Assets/Scripts/Player Manager/GenericPlayerManager.cs @@ -1,3 +1,25 @@ +/** Gerenciador genérico e principal dos players. + * + * Versão 2.1 + * - Acompanhamento da legenda + * Corrigido problema na soletração quando a velocidade ultrapassava ~1. + * + * Versão 2.2 + * - Acompanhamento da legenda + * Corrigido problema na soletração quando o estado muda para pausado. + * + * Versão 2.3 + * - Legenda + * A letras acentuadas reproduzem a mesma sem o acento. + * + * Versão 2.4 + * - Legenda + * "Ç" reproduz "C". + * - Reprodução + * Quando não há acesso aos bundles dos sinais de pontuação, eles são ignorados. + * Ç adicionado como TYPE_WORD. + */ + //Log Dir http://docs.unity3d.com/Manual/LogFiles.html using UnityEngine; using System.Collections; @@ -14,7 +36,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { private const string DEFAULT_ANIMATION = "_default"; private const string DEFAULT_ANIMATION_MIDDLE = "_default_middle"; - protected float fadeLength = 0.6F; + public float fadeLength = 0.6F; public string gloss = ""; // Referencia para o avatar @@ -22,7 +44,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { // Referencia para o componente animador do avatar private Animation COMPONENT_ANIMATION; public Text SUBTITLES; - + // Guarda os nomes das palavras já carregadas private HashSet loadedAssetBundles = new HashSet(); // Guarda os nomes das palavras que não tem assetbundle @@ -46,12 +68,16 @@ public abstract class GenericPlayerManager : MonoBehaviour { // Se diferente de null, não está reproduzindo animação de intervalo private AnimationState intervalAnimationState = null; + // Usado para pausar quando comandado + private AnimationReference animationPlaying = null; // Gerenciador de animações de intervalo public RandomAnimations randomAnimations; // Gerenciados de legendas private Subtitle subtitles = null; + private bool[] lastLetterAnimations = new bool[256]; + public virtual void Start() { // Configuração de velocidade das animações @@ -67,33 +93,33 @@ public abstract class GenericPlayerManager : MonoBehaviour { // Sinais ignorados na legenda string[] flags = new string[] { "[PONTO]", - "[INTERROGACAO]", - "[EXCLAMACAO]" + "[INTERROGAÇÃO]", + "[EXCLAMAÇÃO]" }; foreach (string flag in flags) this.flags.Add(flag); - // Duplica sinais para diferenciar quando há repetidos - string[] toDuplicate = new string[] { - "A", "B", "C", "D", "E", "F", "G", "H", "I", + string[] preloadedAnims = new string[] { + "A", "B", "C", "Ç", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", - "0", "1", "2", "3", "4", - "5", "6", "7", "8", "9", - "," + "0", "1", "2", "3", "4", + "5", "6", "7", "8", "9", + "," }; - foreach (string anim in toDuplicate) + + // Duplica sinais para diferenciar quando há repetidos + foreach (string anim in preloadedAnims) COMPONENT_ANIMATION.AddClip(COMPONENT_ANIMATION[anim].clip, "d_" + anim); - // Sinal default é tratado como animação de intervalo: não sinaliza reprodução na UI - //this.intervalAnimations.Add(DEFAULT_ANIMATION); + foreach (string anim in preloadedAnims) + this.loadedAssetBundles.Add(anim); // Cria novo _default chamado _default_middle para pausas dentro de uma glosa // Impede que a animação default seja confundida com não-reprodução na UI COMPONENT_ANIMATION.AddClip(COMPONENT_ANIMATION[DEFAULT_ANIMATION].clip, DEFAULT_ANIMATION_MIDDLE); } - /* Estados */ public bool isPlayingIntervalAnimation() { return intervalAnimationState != null; } public bool isLoading() { return loading; } public bool isPlaying() { return playing; } @@ -125,9 +151,9 @@ public abstract class GenericPlayerManager : MonoBehaviour { subtitles.updateNumberSpeed(); // Altera a velocidade de todas as animações em reprodução - if ( ! paused) lock (animQueue) + if ( ! paused) lock (this.animQueue) { - foreach (AnimationReference reference in animQueue) + foreach (AnimationReference reference in this.animQueue) if (reference.type != Subtitle.TYPE_NONE && reference.state != null) reference.state.speed = getSpeedByType(reference.type); } @@ -142,7 +168,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { case Subtitle.TYPE_LETTER: return subtitles.LetterSpeed; case Subtitle.TYPE_NUMBER: return subtitles.NumberSpeed; } - + return 2F; } @@ -163,12 +189,10 @@ public abstract class GenericPlayerManager : MonoBehaviour { this.randomAnimations.unlockFor("handleStates"); this.subtitles.setText(""); - lock (animQueue) { animQueue.Clear(); } + lock (this.animQueue) { this.animQueue.Clear(); } COMPONENT_ANIMATION.CrossFadeQueued(DEFAULT_ANIMATION, fadeLength, QueueMode.PlayNow); - - playing = false; - paused = false; - onPlayingStateChange(); + + resetStates(); } /* Repete animações */ @@ -192,7 +216,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { state.speed = speed; lock (this.animQueue) { - animQueue.Enqueue(new AnimationReference(name, subtitle, state, type)); + this.animQueue.Enqueue(new AnimationReference(name, subtitle, state, type)); } return state; @@ -229,12 +253,17 @@ public abstract class GenericPlayerManager : MonoBehaviour { */ public abstract WWW loadAssetBundle(string aniName); + /** + * Listen to changes in the playing status. + */ + public abstract void onConnectionError(string gloss, string word); /** * Listen to changes in the playing status. */ public abstract void onPlayingStateChange(); + /* Pause or continue animations */ public void setPauseState(bool paused) { @@ -242,15 +271,22 @@ public abstract class GenericPlayerManager : MonoBehaviour { { this.paused = paused; - lock (animQueue) + lock (this.animQueue) { - foreach (AnimationReference reference in animQueue) + if (this.animationPlaying != null && this.animationPlaying.state != null) + this.animationPlaying.state.speed = paused ? 0F : getSpeedByType(this.animationPlaying.type); + + foreach (AnimationReference reference in this.animQueue) if (reference.state != null) reference.state.speed = paused ? 0F : getSpeedByType(reference.type); } - - onPlayingStateChange(); } + + onPlayingStateChange(); + } + + public void setAnimationEnabled(bool enabled) { + COMPONENT_ANIMATION.enabled = enabled; } /* Pause or continue animations */ @@ -309,6 +345,32 @@ public abstract class GenericPlayerManager : MonoBehaviour { return true; } + private string nextLetterAnimation(char letter) + { + string animation = (this.lastLetterAnimations[letter] ? "" : "d_") + letter.ToString(); + this.lastLetterAnimations[letter] = ! this.lastLetterAnimations[letter]; + + return animation; + } + + private static short getType(char c) + { + // Se for uma letra + if (c >= 65 && c <= 90) + return Subtitle.TYPE_LETTER; + + // Se for um número + else if (c >= 48 && c <= 57) + return Subtitle.TYPE_NUMBER; + + // Se for uma vírgula + else if (c == 44 || c == 'Ç') + return Subtitle.TYPE_WORD; + + else + return Subtitle.TYPE_NONE; + } + /* Enfileira soletração de palavra */ private string spellWord(Queue toPlayQueue, string word) { @@ -318,50 +380,56 @@ public abstract class GenericPlayerManager : MonoBehaviour { // A reprodução da primeira letra deve ser longa para não ser cortada no fade this.subtitles.updateLetterSpeed(); - string lastAnim = ""; - for (int i = 0; i < word.Length; i++) { lastAnimationSubtitle = Subtitle.highlight(word, i); + char anim = word[i]; - string anim = word[i].ToString(); - lastAnim = anim.Equals(lastAnim) ? "d_" + anim : anim; - - short type; - - // Se for uma letra - if (word[i] >= 65 && word[i] <= 90) - type = Subtitle.TYPE_LETTER; - - // Se for um número - else if (word[i] >= 48 && word[i] <= 57) - type = Subtitle.TYPE_NUMBER; + switch (word[i]) + { + case 'Á': + case 'Â': + case 'À': + case 'Ã': anim = 'A'; + break; + case 'É': + case 'Ê': anim = 'E'; + break; + case 'Í': anim = 'I'; + break; + case 'Ó': + case 'Ô': + case 'Õ': anim = 'O'; + break; + case 'Ú': anim = 'U'; + break; + } - // Se for uma vírgula - else if (word[i] == 44) - type = Subtitle.TYPE_WORD; + short type = getType(anim); + string animName = nextLetterAnimation(anim); // Não há animação - else + if (type == Subtitle.TYPE_NONE) { // Reproduz animação default apenas uma vez if ( ! defaultPlayed) { defaultPlayed = true; - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, lastAnimationSubtitle, this)); + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_WORD, DEFAULT_ANIMATION_MIDDLE, lastAnimationSubtitle, this)); // A reprodução da próxima letra deve ser longa para não ser cortada no fade this.subtitles.updateLetterSpeed(); } - UnityEngine.Debug.Log("Animação \"" + word[i] + "\" inexistente."); - continue; + UnityEngine.Debug.Log("Animação \"" + animName + "\" inexistente."); } - - toPlayQueue.Enqueue(new ToPlay(type, lastAnim, lastAnimationSubtitle, this)); + else + { + toPlayQueue.Enqueue(new ToPlay(type, animName, lastAnimationSubtitle, this)); - defaultPlayed = false; - this.subtitles.updateLetterSpeed(); + defaultPlayed = false; + this.subtitles.updateLetterSpeed(); + } } return lastAnimationSubtitle; @@ -403,7 +471,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { { this.randomAnimations.lockFor("loadAndPlay"); this.loading = true; - onPlayingStateChange(); + // onPlayingStateChange(); string lastAnimationSubtitle = ""; bool spelled = false; @@ -437,23 +505,29 @@ public abstract class GenericPlayerManager : MonoBehaviour { 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); + bundle = www.assetBundle; - if (aniClip) + if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name)) { - COMPONENT_ANIMATION.AddClip(aniClip, aniName); + AnimationClip aniClip = bundle.mainAsset as AnimationClip; + bundle.Unload(false); - loadedAssetBundles.Add(aniName); - loaded = true; + if (aniClip) + { + COMPONENT_ANIMATION.AddClip(aniClip, aniName); + + loadedAssetBundles.Add(aniName); + loaded = true; + + Debug.Log("Bundle \"" + aniName + "\" loaded!"); + } + else UnityEngine.Debug.Log ("Sinal \"" + aniName + "\" foi não carregado corretamente."); } - else UnityEngine.Debug.Log ("Sinal \"" + aniName + "\" não carregado corretamente."); } + else onConnectionError(gloss, aniName); } + else onConnectionError(gloss, aniName); } // Reproduz palavra @@ -490,20 +564,21 @@ public abstract class GenericPlayerManager : MonoBehaviour { if (this.flags.Contains(aniName) || this.intervalAnimations.Contains(aniName)) { - //playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, "", 1.6F); toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F)); - continue; + spelled = false; } - - // Se já houve o soletramento de alguma palavra, reproduz animação default - if (spelled) - toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, lastAnimationSubtitle, 1.6F)); else - spelled = true; + { + // Se já houve o soletramento de alguma palavra, reproduz animação default + if (spelled) + toPlayQueue.Enqueue(new ToPlay(Subtitle.TYPE_NONE, DEFAULT_ANIMATION_MIDDLE, "", 1.6F)); + else + spelled = true; - lastAnimationSubtitle = spellWord(toPlayQueue, aniName); + lastAnimationSubtitle = spellWord(toPlayQueue, aniName); + } } - + if (toPlayQueue.Count > 4 || wordsCount == stringPos.Length) while (toPlayQueue.Count > 0) toPlayQueue.Dequeue().play(this); @@ -513,7 +588,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, ""); this.loading = false; - onPlayingStateChange(); + // onPlayingStateChange(); this.randomAnimations.unlockFor("loadAndPlay"); } } @@ -530,43 +605,93 @@ public abstract class GenericPlayerManager : MonoBehaviour { onPlayingStateChange(); bool isNotEmpty; - lock (animQueue) { isNotEmpty = animQueue.Count > 0; } + lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; } + + // Animação anterior a atual + AnimationReference endedAnimation = null; - // Enquanto estiver executando a rotina "loadAndPlay" + // Enquanto estiver executando a corotina "loadAndPlay" // ou existir animações na fila de reprodução while (loading || isNotEmpty) { + // Se não houver animações na fila, espera if (isNotEmpty) { + // Pega primeira animação AnimationReference reference; - lock (animQueue) { reference = animQueue.Peek(); } - - this.subtitles.setText(reference.subtitle); + lock (this.animQueue) { reference = this.animQueue.Peek(); } + // Se estiver sendo reproduzida if (COMPONENT_ANIMATION.IsPlaying(reference.name)) { - do { yield return null; } - while (COMPONENT_ANIMATION.IsPlaying(reference.name)); + this.subtitles.setText(reference.subtitle); + + // Animação seguinte + AnimationReference next = null; + lock (this.animQueue) + { + this.animationPlaying = this.animQueue.Dequeue(); + + if (this.animQueue.Count > 0) + next = this.animQueue.Peek(); + } + + while (true) + { + // Se a próxima animação estiver sendo reproduzida (no fade) + if (next != null && COMPONENT_ANIMATION.IsPlaying(next.name)) + { + // Se a animação anterior a atual não tiver acabado, + // espera acabar e só então conta o tempo + if (endedAnimation != null) + while (COMPONENT_ANIMATION.IsPlaying(endedAnimation.name)) + yield return null; + + // Tempo para pular para a legenda da próxima animação + yield return new WaitForSeconds(0.4F); + + // Deprecated + // yield return WaitForContinuousMillis.Wait(this, 300); + + endedAnimation = reference; + break; + } + + else if (COMPONENT_ANIMATION.IsPlaying(reference.name)) + yield return null; + + else break; + } + + reference = null; } - if (reference.state == null) - lock (animQueue) { animQueue.Dequeue(); } + // Se a animação não tiver sido liberada e seu AnimationState for nulo, + // a animação será liberada + if (reference != null && reference.state == null) + lock (this.animQueue) { this.animQueue.Dequeue(); } else yield return null; } else yield return null; - this.subtitles.setText(""); - - lock (animQueue) { isNotEmpty = animQueue.Count > 0; } + lock (this.animQueue) { isNotEmpty = this.animQueue.Count > 0; } } - this.playing = false; - this.paused = false; - onPlayingStateChange(); + this.subtitles.setText(""); + resetStates(); this.randomAnimations.unlockFor("handleStates"); } } + public void resetStates() + { + this.animationPlaying = null; + this.playing = false; + this.paused = false; + + onPlayingStateChange(); + } + } diff --git a/Assets/Scripts/Player Manager/RandomAnimations.cs b/Assets/Scripts/Player Manager/RandomAnimations.cs index 4578c4e..606811b 100644 --- a/Assets/Scripts/Player Manager/RandomAnimations.cs +++ b/Assets/Scripts/Player Manager/RandomAnimations.cs @@ -60,36 +60,37 @@ public class RandomAnimations : MonoBehaviour { { while (true) { - while (this.playerManager.isPlayingIntervalAnimation()) - yield return new WaitForSeconds(1); + // Espera enquanto estiver reproduzindo animações de intervalo + do { yield return null; } + while (this.playerManager.isPlayingIntervalAnimation()); - bool isNotBlocked; - lock (this.blockingObjects) { - isNotBlocked = this.blockingObjects.Count == 0; - } - - if (isNotBlocked) + // Se houver bloqueio, espera acabar + while (true) { - yield return new WaitForSeconds(this.time); - lock (this.blockingObjects) { - if (this.blockingObjects.Count > 0) - continue; + if (this.blockingObjects.Count == 0) + break; } - int index = sortIndex(); + yield return null; + } - if (index != -1) - { - if (index == this.lastIndex) - index = sortIndex(); + // Espera time + yield return new WaitForSeconds(this.time); - //this.playerManager.play(this.names[index], true, false, true); - this.playerManager.playIntervalAnimation(this.names[index]); - } + // Se houver bloqueio, volta a esperar + lock (this.blockingObjects) { + if (this.blockingObjects.Count > 0) + continue; } - - yield return null; + + int index = sortIndex(); + + if (index != -1 && index == this.lastIndex) + index = sortIndex(); + + if (index != -1) + this.playerManager.playIntervalAnimation(this.names[index]); } } diff --git a/Assets/Scripts/Player Manager/Subtitle.cs b/Assets/Scripts/Player Manager/Subtitle.cs index 4942a78..9c9efb1 100644 --- a/Assets/Scripts/Player Manager/Subtitle.cs +++ b/Assets/Scripts/Player Manager/Subtitle.cs @@ -2,6 +2,12 @@ using UnityEngine.UI; /** * Gerenciador de legendas + * + * Versão 1.1 + * - Caracteres de letras acentuadas e % são separados com "-". + * + * Versão 1.1.1 + * - "Ç" é separada por "-" na legenda. */ public class Subtitle { @@ -32,7 +38,7 @@ public class Subtitle { private float numberSpeed = DefaultSignSpeed.DEFAULT; public static string highlightedColor = "white"; - + // Referência para a legenda public Text subtitle; @@ -116,6 +122,28 @@ public class Subtitle { this.NumberSpeed = this.DefaultNumberSpeed.getProportional(this.SliderPosition); } + public static bool isSeparable(char c) + { + switch (c) + { + case '%': + case 'Á': + case 'Â': + case 'À': + case 'Ã': + case 'É': + case 'Ê': + case 'Í': + case 'Ó': + case 'Ô': + case 'Õ': + case 'Ú': + case 'Ç': return true; + } + + return (c >= 65 && c <= 90) || (c >= 48 && c <= 57); + } + /* Destaca caractere de uma string. */ public static string highlight(string word, int index) { @@ -123,7 +151,7 @@ public class Subtitle { for (int i = 0; i < word.Length; i++) { - if (i > 0 && ((word[i] >= 65 && word[i] <= 90) || (word[i] >= 48 && word[i] <= 57))) + if (i > 0 && isSeparable(word[i])) subtitle += "-"; if (i == index) diff --git a/Assets/Scripts/PlayerManager.cs b/Assets/Scripts/PlayerManager.cs index e873afb..bb06739 100644 --- a/Assets/Scripts/PlayerManager.cs +++ b/Assets/Scripts/PlayerManager.cs @@ -22,15 +22,11 @@ public class PlayerManager : GenericPlayerManager { public override void Start() { - //base.defaultFirstLetterSpeed = new DefaultSignSpeed(2.3F, 3.2F); - //base.defaultLetterSpeed = new DefaultSignSpeed(3.1F, 4.6F); - base.Start(); Application.ExternalCall("onLoadPlayer"); } // SendMessage("PlayerManager", "catchGlosa", "LAVID"); - // SendMessage("PlayerManager", "switchSubtitleStatus"); public override WWW loadAssetBundle(string aniName) { return WWW.LoadFromCacheOrDownload(BASE_URL + aniName, 1); @@ -46,6 +42,8 @@ public class PlayerManager : GenericPlayerManager { base.isRepeatable()); } + public override void onConnectionError(string gloss, string word) { } + private static bool itb(int value) { return value == 0 ? false : true; } diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index cababbe..7f31e3b 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -477,7 +477,7 @@ PlayerSettings: - WebGL::useEmbeddedResources - XboxOne::enus WebGL::analyzeBuildSize: 0 - WebGL::dataCaching: 1 + WebGL::dataCaching: 0 WebGL::useEmbeddedResources: 0 XboxOne::enus: 1 stringPropertyNames: -- libgit2 0.21.2