diff --git a/Assets/Scripts/Player Manager/AnimationReference.cs b/Assets/Scripts/Player Manager/AnimationReference.cs index d6be4ba..7ae7faa 100644 --- a/Assets/Scripts/Player Manager/AnimationReference.cs +++ b/Assets/Scripts/Player Manager/AnimationReference.cs @@ -1,19 +1,33 @@ using UnityEngine; -public class AnimationReference -{ +public class AnimationReference { + + private GenericPlayerManager context = GenericPlayerManager.context; + public string name; public string subtitle; - public AnimationState state; public short type; - public bool playing; + public float speed; + + public AnimationState state = null; - public AnimationReference(string name, string subtitle, AnimationState state, short type) + public AnimationReference(string name, string subtitle, short type, float speed) { this.name = name; this.subtitle = subtitle; - this.state = state; this.type = type; - this.playing = false; + this.speed = speed; + } + + public AnimationReference(string name, string subtitle, short type) + : this(name, subtitle, type, 0F) { + this.speed = context.getSpeedByType(Subtitle.TYPE_WORD); } + + public void play() + { + this.state = context.COMPONENT_ANIMATION.CrossFadeQueued(this.name, context.fadeLength, QueueMode.CompleteOthers); + this.state.speed = this.speed; + } + } \ No newline at end of file diff --git a/Assets/Scripts/Player Manager/GenericPlayerManager.cs b/Assets/Scripts/Player Manager/GenericPlayerManager.cs index bac707b..ab2f6ae 100644 --- a/Assets/Scripts/Player Manager/GenericPlayerManager.cs +++ b/Assets/Scripts/Player Manager/GenericPlayerManager.cs @@ -10,9 +10,11 @@ using UnityEngine.UI; public abstract class GenericPlayerManager : MonoBehaviour { + public static GenericPlayerManager context; + private const string DEFAULT_ANIMATION = "_default"; - protected float fadeLength = 0.6F; + public float fadeLength = 0.6F; public string gloss = ""; // Vetor usado para quebrar a glosa @@ -21,17 +23,15 @@ public abstract class GenericPlayerManager : MonoBehaviour { // Referencia para o avatar private GameObject AVATAR; // Referencia para o componente animador do avatar - private Animation COMPONENT_ANIMATION; + public Animation COMPONENT_ANIMATION; public Text SUBTITLES; // Guarda os nomes das palavras já carregadas - private HashSet loadedAssetBundles = new HashSet(); + public HashSet loadedAssetBundles = new HashSet(); // Guarda os nomes das palavras que não tem assetbundle - private HashSet nonexistentAssetBundles = new HashSet(); + public HashSet nonexistentAssetBundles = new HashSet(); - // Fila de animações para reprodução - // Utilizada para alterar velocidade e apresentar a legenda - private Queue animQueue = new Queue(); + private Queue glossQueue = new Queue(); // Sinais de intervalo de animações: não sinaliza reprodução na UI private HashSet intervalAnimations = new HashSet(); @@ -56,6 +56,8 @@ public abstract class GenericPlayerManager : MonoBehaviour { public virtual void Start() { + context = this; + // Configuração de velocidade das animações subtitles = new Subtitle(SUBTITLES); subtitles.DefaultWordSpeed = new DefaultSignSpeed(); @@ -113,7 +115,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { } } - private float getSpeedByType(short type) + public float getSpeedByType(short type) { switch (type) { @@ -128,7 +130,10 @@ public abstract class GenericPlayerManager : MonoBehaviour { public void stopAll() { - StopCoroutine("loadAndPlay"); + foreach (Gloss gloss in this.glossQueue) gloss.destroy(); + gloss.Clear(); + + //StopCoroutine("loadAndPlay"); this.randomAnimations.unlockFor("loadAndPlay"); loading = false; @@ -160,36 +165,6 @@ public abstract class GenericPlayerManager : MonoBehaviour { play(this.gloss, true, true, true); } - /* - * 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; - - lock (this.animQueue) { - 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. @@ -197,7 +172,7 @@ public abstract class GenericPlayerManager : MonoBehaviour { * @return AssetBundle - se for encontrado. * null - se ocorrer num erro. */ - protected abstract WWW loadAssetBundle(string aniName); + public abstract WWW loadAssetBundle(string aniName); /** @@ -270,70 +245,30 @@ public abstract class GenericPlayerManager : MonoBehaviour { } } - StartCoroutine("loadAndPlay", gloss); + StartCoroutine("loadAndPlay", gloss) 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 - this.subtitles.updateLetterSpeed(); + private System.Object loadingLocker = new System.Object(); - for (int i = 0; i < word.Length; i++) + private IEnumerator loadAndPlay(string glossText) + { + lock (this.loadingLocker) { - 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, subtitles.LetterSpeed); + Gloss gloss = new Gloss(glossText); + this.glossQueue.Add(gloss); - // Se for um número - else if (second >= 48 && second <= 57) - playAnimation(Subtitle.TYPE_NUMBER, second.ToString(), lastAnimationSubtitle, subtitles.NumberSpeed); - - // Se for uma vírgula - else if (second == 44) - playAnimation(Subtitle.TYPE_WORD, second.ToString(), lastAnimationSubtitle); + if ( ! gloss.loaded) + yield return gloss.load(); - // Não há animação - else - { - // Reproduz animação default apenas uma vez - if ( ! defaultPlayed) - { - defaultPlayed = true; - playAnimation(Subtitle.TYPE_NONE, DEFAULT_ANIMATION, lastAnimationSubtitle); + yield return gloss.handle(); + - // A reprodução da próxima letra deve ser longa para não ser cortada no fade - subtitles.updateLetterSpeed(); - } - UnityEngine.Debug.Log("Animação \"" + second + "\" inexistente."); - continue; - } - defaultPlayed = false; - subtitles.updateLetterSpeed(); - } - return lastAnimationSubtitle; - } - private System.Object loadingLocker = new System.Object(); - private IEnumerator loadAndPlay(string gloss) - { - lock (this.loadingLocker) - { this.randomAnimations.lockFor("loadAndPlay"); this.loading = true; // onPlayingStateChange(); diff --git a/Assets/Scripts/Player Manager/Gloss.cs b/Assets/Scripts/Player Manager/Gloss.cs new file mode 100644 index 0000000..577deed --- /dev/null +++ b/Assets/Scripts/Player Manager/Gloss.cs @@ -0,0 +1,181 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System; +using System.Threading; + +public class Gloss { + + private GenericPlayerManager context = GenericPlayerManager.context; + + private string gloss; + private string[] tokens; + + private Queue animations = new Queue(); + + public bool loaded = false; + + public Gloss(string gloss) + { + this.gloss = gloss; + this.tokens = gloss.Split(' '); + } + + private void addDefault() { + this.animations.Add(new AnimationReference(context.DEFAULT_ANIMATION, "", Subtitle.TYPE_NONE, 2F)); + } + + public IEnumerator load() + { + loaded = true; + addDefault(); + + bool spelled = false; + + foreach (string token in this.tokens) + { + if (String.IsNullOrEmpty(token) + || context.nonexistentAssetBundles.Contains(token) + || context.loadedAssetBundles.Contains(token)) + continue; + + bool success = false; + string error = null; + + WWW www = context.loadAssetBundle(token); + if (www != null) + { + yield return www; + + if (www.error == null) + { + AssetBundle bundle = www.assetBundle; + + if (bundle != null && ! String.IsNullOrEmpty(bundle.mainAsset.name)) + { + AnimationClip clip = bundle.mainAsset as AnimationClip; + bundle.Unload(false); + + if (clip) + { + success = true; + context.COMPONENT_ANIMATION.AddClip(clip, token); + context.loadedAssetBundles.Add(token); + + if (spelled) + { + addDefault(); + spelled = false; + } + + string subtitle = context.flags.Contains(token) ? token : ""; + + this.animations.Add(new AnimationReference(token, subtitle, Subtitle.TYPE_WORD)); + } + else error = "Error at Gloss.load(): clip from AssetBundle of " + token + " wasn't found"; + } + else error = "Error at Gloss.load(): could not get AssetBundle from WWW"; + } + else error = "Error at Gloss.load(): WWW: " + www.error; + } + else error = "Error at Gloss.load(): WWW is null"; + + if ( ! success) + { + Debug.Log(error); + context.nonexistentAssetBundles.Add(token); + + if (this.flags.Contains(aniName)) + { + addDefault(); + continue; + } + + // Se já houve o soletramento de alguma palavra, reproduz animação default + if (spelled) + addDefault(); + else + spelled = true; + + spellWord(token); + } + } + + addDefault(); + } + + private void spellWord(string word) + { + // A reprodução da primeira letra deve ser longa para não ser cortada no fade + context.subtitles.updateLetterSpeed(); + + char last = ' '; + + for (int i = 0; i < word.Length; i++) + { + char letter = word[i]; + string subtitle = Subtitle.highlight(word, i); + + string animationName = letter.ToString(); + if (letter == last) animationName += "_2"; + + last = letter; + + // Se for uma letra + if (letter >= 65 && letter <= 90) + this.animations.Add(new AnimationReference( + animationName, + subtitle, + Subtitle.TYPE_LETTER + )); + + // Se for um número + else if (letter >= 48 && letter <= 57) + this.animations.Add(new AnimationReference( + animationName, + subtitle, + Subtitle.TYPE_NUMBER + )); + + // Se for uma vírgula + else if (letter == 44) + this.animations.Add(new AnimationReference( + animationName, + subtitle, + Subtitle.TYPE_WORD + )); + + context.subtitles.updateLetterSpeed(); + } + } + + private IEnumerator play() + { + foreach (AnimationReference animation in this.animations) + animation.play(); + + while (this.animations.Count > 0) + { + AnimationReference reference = this.animations.Peek(); + + this.subtitles.setText(reference.subtitle); + + while (COMPONENT_ANIMATION.IsPlaying(reference.name)) + yield return null; + + if (reference.state == null) + this.animations.Dequeue(); + else + yield return null; + } + + this.subtitles.setText(""); + } + + public void destroy() + { + context.StopCoroutine("load"); + context.StopCoroutine("handle"); + } + +} diff --git a/Assets/Scripts/Player Manager/Gloss.cs.meta b/Assets/Scripts/Player Manager/Gloss.cs.meta new file mode 100644 index 0000000..6110edf --- /dev/null +++ b/Assets/Scripts/Player Manager/Gloss.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ff84f8e2340949a419032a7d7f7bc160 +timeCreated: 1456775969 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Player Manager/Subtitle.cs b/Assets/Scripts/Player Manager/Subtitle.cs index 75db5bc..81b6773 100644 --- a/Assets/Scripts/Player Manager/Subtitle.cs +++ b/Assets/Scripts/Player Manager/Subtitle.cs @@ -119,28 +119,16 @@ public class Subtitle { public static string highlight(string word, int index) { string subtitle = ""; - int last = 0; - if (index == 0) - subtitle += "" + word[0] + ""; - else - subtitle += word[0]; - - for (int i = 1; i < word.Length; i++) + for (int i = 0; i < word.Length; i++) { - if ((word[i] >= 65 && word[i] <= 90) || (word[i] >= 48 && word[i] <= 57)) + if (i > 0 && ((word[i] >= 65 && word[i] <= 90) || (word[i] >= 48 && word[i] <= 57))) subtitle += "-"; - if (i == index || (last == index && word[i] == word[last])) - { + if (i == index) subtitle += "" + word[i] + ""; - if (i == index) last = i; - } else - { subtitle += word[i]; - last = i; - } } return subtitle; diff --git a/Assets/Scripts/PlayerManager.cs b/Assets/Scripts/PlayerManager.cs index 898576f..cd7e216 100644 --- a/Assets/Scripts/PlayerManager.cs +++ b/Assets/Scripts/PlayerManager.cs @@ -98,7 +98,7 @@ public class PlayerManager : GenericPlayerManager { public Text debugText; - protected override WWW loadAssetBundle(string aniName) { + public override WWW loadAssetBundle(string aniName) { return WWW.LoadFromCacheOrDownload(BASE_URL + aniName, version); } -- libgit2 0.21.2