Esempio n. 1
0
        public void SetAnimationVars(LetterSetup master_letter)
        {
            m_anim_state_vars = master_letter.AnimStateVars.Clone();

            m_current_letter_action = null;

            // clone the list of active loop cycles, so that the list reference is not shared between two letters
            m_anim_state_vars.m_active_loop_cycles = new List <ActionLoopCycle>();
            foreach (ActionLoopCycle loop_cycle in master_letter.AnimStateVars.m_active_loop_cycles)
            {
                m_anim_state_vars.m_active_loop_cycles.Add(loop_cycle.Clone());
            }
        }
Esempio n. 2
0
		public void PrepareData(ref LetterSetup[] letters, int num_letters, int num_words, int num_lines, LetterAction prev_action, AnimatePerOptions animate_per, bool prev_action_end_state = true)
		{
			m_duration_progression.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_duration_progression.AnimatePer, m_duration_progression.OverrideAnimatePerOption));
			
			
			if(m_audio_effects != null)
			{
				foreach(AudioEffectSetup effect_setup in m_audio_effects)
				{
					effect_setup.m_delay.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, effect_setup.m_delay.AnimatePer, effect_setup.m_delay.OverrideAnimatePerOption));
					effect_setup.m_offset_time.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, effect_setup.m_offset_time.AnimatePer, effect_setup.m_offset_time.OverrideAnimatePerOption));
					effect_setup.m_volume.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, effect_setup.m_volume.AnimatePer, effect_setup.m_volume.OverrideAnimatePerOption));
					effect_setup.m_pitch.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, effect_setup.m_pitch.AnimatePer, effect_setup.m_pitch.OverrideAnimatePerOption));
				}
			}

			if(m_particle_effects != null)
			{
				foreach(ParticleEffectSetup effect_setup in m_particle_effects)
				{
					effect_setup.m_position_offset.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, effect_setup.m_position_offset.AnimatePer, effect_setup.m_position_offset.OverrideAnimatePerOption), null);
					effect_setup.m_rotation_offset.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, effect_setup.m_rotation_offset.AnimatePer, effect_setup.m_rotation_offset.OverrideAnimatePerOption), null);
					effect_setup.m_delay.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, effect_setup.m_delay.AnimatePer, effect_setup.m_delay.OverrideAnimatePerOption));
					effect_setup.m_duration.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, effect_setup.m_duration.AnimatePer, effect_setup.m_duration.OverrideAnimatePerOption));
				}
			}
			
			if(m_action_type == ACTION_TYPE.BREAK)
			{
				return;
			}
			
			m_delay_progression.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_delay_progression.AnimatePer, m_delay_progression.OverrideAnimatePerOption));
			
			
			if(m_offset_from_last && prev_action != null)
			{
				m_use_gradient_start = prev_action.m_use_gradient_end;
				
				if(prev_action_end_state)
				{
					if(m_use_gradient_start)
					{
						m_start_vertex_colour.Values = prev_action.m_end_vertex_colour.Values;
					}
					else
					{
						m_start_colour.Values = prev_action.m_end_colour.Values;
					}
				}
				else
				{
					if(m_use_gradient_start)
					{
						m_start_vertex_colour.Values = prev_action.m_start_vertex_colour.Values;
					}
					else
					{
						m_start_colour.Values = prev_action.m_start_colour.Values;
					}
				}
			}
			else
			{
				if(m_use_gradient_start || (prev_action != null && (prev_action.m_use_gradient_end)))
				{
					if(!m_use_gradient_start)
					{
						// Need to convert flat colour into a vertex colour
						m_use_gradient_start = true;
						
						m_start_vertex_colour.ConvertFromFlatColourProg(m_start_colour);
					}
					
					// add this colour to previous state
					m_start_vertex_colour.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_start_vertex_colour.AnimatePer, m_start_vertex_colour.OverrideAnimatePerOption),
																prev_action != null && (prev_action.m_use_gradient_end) ? prev_action.m_end_vertex_colour.Values : null,
																prev_action != null && (!prev_action.m_use_gradient_end) ? prev_action.m_end_colour.Values : null);
				}
				else
				{
					m_start_colour.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_start_colour.AnimatePer, m_start_colour.OverrideAnimatePerOption), 
														prev_action != null ? prev_action.m_end_colour.Values : null);
				}
			}
			
			if(m_use_gradient_end || m_use_gradient_start)
			{
				if(!m_use_gradient_end)
				{
					// Need to convert flat colour into a vertex colour
					m_use_gradient_end = true;
					
					m_end_vertex_colour.ConvertFromFlatColourProg(m_end_colour);
				}
				
				m_end_vertex_colour.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_end_vertex_colour.AnimatePer, m_end_vertex_colour.OverrideAnimatePerOption),
															(m_use_gradient_start) ? m_start_vertex_colour.Values : null,
															(!m_use_gradient_start) ? m_start_colour.Values : null);
			}
			else
			{
				m_end_colour.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_end_colour.AnimatePer, m_end_colour.OverrideAnimatePerOption),
													m_start_colour.Values);
			}
			
			
			if(m_offset_from_last && prev_action != null)
			{
				m_start_pos.Values = prev_action_end_state ? prev_action.m_end_pos.Values : prev_action.m_start_pos.Values;
				m_start_euler_rotation.Values = prev_action_end_state ? prev_action.m_end_euler_rotation.Values : prev_action.m_start_euler_rotation.Values;
				m_start_scale.Values = prev_action_end_state ? prev_action.m_end_scale.Values : prev_action.m_start_scale.Values;
			}
			else
			{
				float[] start_pos_curve_letter_progressions = null;
				if(m_start_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX)
				{
					// Pre calculate letter progression values based on letter spacing
					start_pos_curve_letter_progressions = m_start_pos.BezierCurve.GetLetterProgressions(ref letters, m_letter_anchor_start);
				}
				
				m_start_pos.CalculatePositionProgressions(ref start_pos_curve_letter_progressions, GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_start_pos.AnimatePer, m_start_pos.OverrideAnimatePerOption),
													prev_action != null ? prev_action.m_end_pos.Values : new Vector3[]{Vector3.zero});
				m_start_euler_rotation.CalculateRotationProgressions(ref start_pos_curve_letter_progressions, GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_start_euler_rotation.AnimatePer, m_start_euler_rotation.OverrideAnimatePerOption),
													prev_action != null ? prev_action.m_end_euler_rotation.Values : new Vector3[]{Vector3.zero},
													m_start_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX ? m_start_pos.BezierCurve : null);
				m_start_scale.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_start_scale.AnimatePer, m_start_scale.OverrideAnimatePerOption),
													prev_action != null ? prev_action.m_end_scale.Values : new Vector3[]{Vector3.zero});
			}
			
			float[] end_pos_curve_letter_progressions = null;
			if(m_end_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX)
			{
				// Pre calculate letter progression values based on letter spacing
				end_pos_curve_letter_progressions = m_end_pos.BezierCurve.GetLetterProgressions(ref letters, m_letter_anchor_end);
			}
			
			m_end_pos.CalculatePositionProgressions(ref end_pos_curve_letter_progressions, GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_end_pos.AnimatePer, m_end_pos.OverrideAnimatePerOption), m_start_pos.Values);
			m_end_euler_rotation.CalculateRotationProgressions(ref end_pos_curve_letter_progressions, GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_end_euler_rotation.AnimatePer, m_end_euler_rotation.OverrideAnimatePerOption),
														m_start_euler_rotation.Values,
														m_end_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX ? m_end_pos.BezierCurve : null);
			m_end_scale.CalculateProgressions(GetProgressionTotal(num_letters, num_words, num_lines, animate_per, m_end_scale.AnimatePer, m_end_scale.OverrideAnimatePerOption), m_start_scale.Values);
			
			CalculateLetterAnchorOffset();
		}
Esempio n. 3
0
 float GetLetterAnchorOffset(LetterSetup letter, int letter_anchor)
 {
     return(letter_anchor == (int)TextfxTextAnchor.LowerCenter || letter_anchor == (int)TextfxTextAnchor.MiddleCenter || letter_anchor == (int)TextfxTextAnchor.UpperCenter || letter_anchor == (int)TextfxTextAnchor.BaselineCenter ? (letter.m_offset_width + (letter.m_width - letter.m_offset_width)) / 2
                                 : ((letter_anchor == (int)TextfxTextAnchor.LowerRight || letter_anchor == (int)TextfxTextAnchor.MiddleRight || letter_anchor == (int)TextfxTextAnchor.UpperRight || letter_anchor == (int)TextfxTextAnchor.BaselineRight) ? (letter.m_offset_width + (letter.m_width - letter.m_offset_width)) : 0));
 }
		float GetLetterAnchorOffset(LetterSetup letter, int letter_anchor)
		{
			return (letter_anchor == (int) TextfxTextAnchor.LowerCenter || letter_anchor == (int) TextfxTextAnchor.MiddleCenter || letter_anchor == (int) TextfxTextAnchor.UpperCenter || letter_anchor == (int) TextfxTextAnchor.BaselineCenter ? (letter.m_offset_width + (letter.m_width - letter.m_offset_width))/2
					: ((letter_anchor == (int) TextfxTextAnchor.LowerRight || letter_anchor == (int) TextfxTextAnchor.MiddleRight || letter_anchor == (int) TextfxTextAnchor.UpperRight || letter_anchor == (int) TextfxTextAnchor.BaselineRight) ? (letter.m_offset_width + (letter.m_width - letter.m_offset_width)) : 0));
		}
		public float[] GetLetterProgressions(ref LetterSetup[] letters, int letter_anchor)
		{
			float[] letter_progressions = new float[letters.Length];
			
			if(m_anchor_points == null || m_anchor_points.Count < 2)
			{
				for(int idx=0; idx < letters.Length; idx++)
				{
					letter_progressions[idx] = 0;
				}
				return letter_progressions;
			}
			
			float progress_inc = 1f / NUM_CURVE_SAMPLE_SUBSECTIONS;
			float progress;
			Vector3 new_point = new Vector3();
			Vector3 last_point = new Vector3();
			int letter_idx = 0, line_number=0;
			float base_letters_offset = 0, letters_offset = 0;
			LetterSetup letter;
			EffectManager effect_manager_ref;
			float last_line_length = 0, line_length = 0;
			float curve_length = 0;
			float length_val;

			// Grab reference to first letter setup
			letter = letters[letter_idx];
			
			// grab a reference to the EffectManager instance
			effect_manager_ref = letter.m_effect_manager_handle;
			
			// Calculate the total length of the belzier curve if the text alignment is set to center or right.
			if(effect_manager_ref.m_text_alignment == TextAlignment.Center || effect_manager_ref.m_text_alignment == TextAlignment.Right)
			{
				for(int curve_idx=0; curve_idx < m_anchor_points.Count - 1; curve_idx++)
				{
					length_val = GetCurveLength(curve_idx);
		
					curve_length += length_val;
				}
			}
			
			// Assign base letter offset value using first letters offset value
			base_letters_offset = letter.m_base_offset.x;
			
			// Setup letter offset value
			letters_offset = 	(letter.m_base_offset.x - base_letters_offset)
								+ GetLetterAnchorOffset(letter, letter_anchor);
			
			// Handle alignment-specific offset values
			if(effect_manager_ref.m_text_alignment == TextAlignment.Center)
			{
				letters_offset += ((curve_length/2) - (letter.m_effect_manager_handle.TextDimensions[letter.m_progression_variables.m_line_value].m_text_line_width/2));
			}
			else if(effect_manager_ref.m_text_alignment == TextAlignment.Right)
			{
				letters_offset += (curve_length - letter.m_effect_manager_handle.TextDimensions[letter.m_progression_variables.m_line_value].m_text_line_width);
			}
			

			for(int curve_idx=0; curve_idx < m_anchor_points.Count - 1; curve_idx++)
			{
				for(int idx=0; idx <= NUM_CURVE_SAMPLE_SUBSECTIONS; idx++)
				{
					progress = idx * progress_inc;
					
					new_point = GetCurvePoint(progress, curve_idx : curve_idx);
					
					if(idx > 0)
					{
						line_length += (new_point - last_point).magnitude;
						
						while(letter_idx < letters.Length && line_length > letters_offset)
						{
							// calculate relative progress between the last two points which would represent the next letters offset distance
							progress = curve_idx + ((idx-1) * progress_inc) + (((letters_offset - last_line_length) / (line_length - last_line_length)) * progress_inc);
							
							letter_progressions[letter_idx] = progress;
							
							letter_idx++;
							
							if(letter_idx < letters.Length)
							{
								letter = letters[letter_idx];
								
								if(letter.m_progression_variables.m_line_value > line_number)
								{
									line_number = letter.m_progression_variables.m_line_value;
									
									// Set a new base offset value to that of the first letter of this new line
									base_letters_offset = letter.m_base_offset.x;
									
									curve_idx = 0;
									idx=-1;
									line_length = 0;
								}
								
								// Setup letter offset value
								letters_offset = 	(letter.m_base_offset.x - base_letters_offset)
													+ GetLetterAnchorOffset(letter, letter_anchor);

								// Handle alignment-specific offset values
								if(effect_manager_ref.m_text_alignment == TextAlignment.Center)
								{
									letters_offset += ((curve_length/2) - (letter.m_effect_manager_handle.TextDimensions[letter.m_progression_variables.m_line_value].m_text_line_width/2));
								}
								else if(effect_manager_ref.m_text_alignment == TextAlignment.Right)
								{
									letters_offset += (curve_length - letter.m_effect_manager_handle.TextDimensions[letter.m_progression_variables.m_line_value].m_text_line_width);
								}
							}
						}
						
						if(letter_idx == letters.Length)
							break;
					}
					
					last_point = new_point;
					last_line_length = line_length;
				}
			}
			
			// Handle any letters which didn't have room to fit on the line
			// Currently forces them to all position at the end of the line
			for(int idx=letter_idx; idx < letters.Length; idx++)
			{
				letter_progressions[idx] = m_anchor_points.Count - 1;
			}
			
			return letter_progressions;
		}
		public void PrepareData(LetterSetup[] letters, int num_words, int num_lines, AnimatePerOptions animate_per)
		{
			if(letters == null || letters.Length == 0)
			{
				return;
			}
			
			int num_letters = letters.Length;
			
			// Populate list of letters to animate by index, and set Letter indexes accordingly
			if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.ALL_LETTERS)
			{
				m_letters_to_animate = new List<int>();
				for(int letter_idx=0; letter_idx < num_letters; letter_idx++)
				{
					m_letters_to_animate.Add(letter_idx);
					
					letters[letter_idx].m_progression_variables.m_letter_value = letter_idx;
				}
			}
			else if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.FIRST_LETTER || m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LETTER)
			{
				m_letters_to_animate = new List<int>();
				m_letters_to_animate.Add(m_letters_to_animate_option == LETTERS_TO_ANIMATE.FIRST_LETTER ? 0 : letters.Length -1);
				
				letters[m_letters_to_animate_option == LETTERS_TO_ANIMATE.FIRST_LETTER ? 0 : letters.Length - 1].m_progression_variables.m_letter_value = 0;
			}
			else if(m_letters_to_animate_option != LETTERS_TO_ANIMATE.CUSTOM)
			{
				m_letters_to_animate = new List<int>();
				
				int line_idx = m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LETTER_LINES ? 0 : -1;
				int word_idx = m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LETTER_WORDS ? 0 : -1;
				int target_idx = 0;
				
				if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_WORD)
					target_idx = letters[letters.Length-1].m_progression_variables.m_word_value;
				else if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LINE)
					target_idx = letters[letters.Length-1].m_progression_variables.m_line_value;
				else if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.NTH_WORD || m_letters_to_animate_option == LETTERS_TO_ANIMATE.NTH_LINE)
					target_idx = m_letters_to_animate_custom_idx - 1;
				
				int letter_idx = 0;
				int progression_idx = 0;
				foreach(LetterSetup letter in letters)
				{
					if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.FIRST_LINE || m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LINE || m_letters_to_animate_option == LETTERS_TO_ANIMATE.NTH_LINE)
					{
						if(letter.m_progression_variables.m_line_value == target_idx)
						{
							letter.m_progression_variables.m_letter_value = progression_idx;
							m_letters_to_animate.Add(letter_idx);
							progression_idx ++;
						}
					}
					else if(letter.m_progression_variables.m_line_value > line_idx)
					{
						if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.FIRST_LETTER_LINES)
						{
							letter.m_progression_variables.m_letter_value = progression_idx;
							m_letters_to_animate.Add(letter_idx);
							progression_idx ++;
							
						}
						else if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LETTER_LINES)
						{
							letter.m_progression_variables.m_letter_value = progression_idx - 1;
							m_letters_to_animate.Add(letter_idx - 1);
							progression_idx ++;
						}
						line_idx = letter.m_progression_variables.m_line_value;
					}
					
					if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.FIRST_WORD || m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_WORD || m_letters_to_animate_option == LETTERS_TO_ANIMATE.NTH_WORD)
					{
						if(letter.m_progression_variables.m_word_value == target_idx)
						{
							letter.m_progression_variables.m_letter_value = progression_idx;
							m_letters_to_animate.Add(letter_idx);
							progression_idx ++;
						}
					}
					else if(letter.m_progression_variables.m_word_value > word_idx)
					{
						if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.FIRST_LETTER_WORDS)
						{
							letter.m_progression_variables.m_letter_value = progression_idx;
							m_letters_to_animate.Add(letter_idx);
							progression_idx ++;
						}
						else if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LETTER_WORDS)
						{
							letter.m_progression_variables.m_letter_value = progression_idx;
							m_letters_to_animate.Add(letter_idx - 1);
							progression_idx ++;
						}
						word_idx = letter.m_progression_variables.m_word_value;
					}
					
					letter_idx++;
				}
				
				if(m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LETTER_WORDS || m_letters_to_animate_option == LETTERS_TO_ANIMATE.LAST_LETTER_LINES)
				{
					letters[num_letters - 1].m_progression_variables.m_letter_value = letter_idx - 1;
					m_letters_to_animate.Add(letter_idx - 1);
				}
			}
			else
			{
				int progression_idx = 0;
				for(int letter_idx=0; letter_idx < num_letters; letter_idx++)
				{	
					if(m_letters_to_animate.Contains(letter_idx))
					{
						letters[letter_idx].m_progression_variables.m_letter_value = progression_idx;
						
						progression_idx ++;
					}
				}
			}
			
			// Prepare data progression data in all actions
			LetterAction letter_action;
			LetterAction prev_action = null;
			bool prev_action_end_state = true;
			for(int action_idx = 0; action_idx < m_letter_actions.Count; action_idx ++)
			{
				letter_action = m_letter_actions[action_idx];
				
				letter_action.PrepareData(ref letters, m_letters_to_animate.Count, num_words, num_lines, prev_action, animate_per, prev_action_end_state);
				
				
				if(letter_action.m_action_type == ACTION_TYPE.ANIM_SEQUENCE)
				{
					// Set default previous action settings
					prev_action_end_state = true;
					prev_action = letter_action;
				}
				
				// Check for reverse loops, and how the animation should progress from there
				foreach(ActionLoopCycle loop_cycle in m_loop_cycles)
				{
					if(loop_cycle.m_end_action_idx == action_idx && loop_cycle.m_loop_type == LOOP_TYPE.LOOP_REVERSE)
					{
						prev_action = m_letter_actions[loop_cycle.m_start_action_idx];
						prev_action_end_state = false;
					}
				}
			}
		}
Esempio n. 7
0
		public void SetAnimationVars(LetterSetup master_letter)
		{
			m_anim_state_vars = master_letter.AnimStateVars.Clone();
			
			m_current_letter_action = null;
			
			// clone the list of active loop cycles, so that the list reference is not shared between two letters
			m_anim_state_vars.m_active_loop_cycles = new List<ActionLoopCycle>();
			foreach(ActionLoopCycle loop_cycle in master_letter.AnimStateVars.m_active_loop_cycles)
			{
				m_anim_state_vars.m_active_loop_cycles.Add(loop_cycle.Clone());
			}
		}
Esempio n. 8
0
		public void SetText(string new_text, bool force_all_new = false)
		{
			if(m_renderer == null)
			{
				m_renderer = this.GetComponent<Renderer>();
			}
			
			bool setup_correctly = false;
			
			// Automatically assign the font material to the renderer if its not already set
			if((m_renderer.sharedMaterial == null || m_renderer.sharedMaterial != m_font_material) && m_font_material != null)
			{
				m_renderer.sharedMaterial = m_font_material;
			}
			else if(m_font != null)
			{	
				if(m_renderer.sharedMaterial == null || m_renderer.sharedMaterial != m_font_material)
				{
					m_font_material = m_font.material;
					m_renderer.sharedMaterial = m_font_material;
				}
				
				if(m_renderer.sharedMaterial != null)
				{
					setup_correctly = true;
				}
			}
			
			
			if(!setup_correctly && (m_renderer.sharedMaterial == null || m_font_data_file == null))
			{
				// Incorrectly setup font information
				m_font = Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
				m_font_material = m_font.material;
				m_renderer.sharedMaterial = m_font_material;
				m_font_data_file = null;
			}
			
			m_text = new_text;
			
			// Remove all carriage return char's from new_text
			new_text = new_text.Replace("\r", "");
			
			string raw_chars = m_text.Replace(" ", "");
			raw_chars = raw_chars.Replace("\n", "");
			raw_chars = raw_chars.Replace("\r", "");
			raw_chars = raw_chars.Replace("\t", "");
			
			int text_length = new_text.Length;
			
			LetterSetup[] prev_letters = m_letters;
			
			m_letters= new LetterSetup[raw_chars.Length];
		
			CustomCharacterInfo char_info = new CustomCharacterInfo();
			CustomCharacterInfo last_char_info = null;
			
			m_text_datas = new List<TextSizeData>();
			
			if(m_font != null)
			{
				// Make sure font contains all characters required
				m_font.RequestCharactersInTexture(m_text);
				
				if(m_font_material.mainTexture.width != m_font_texture_width || m_font_material.mainTexture.height != m_font_texture_height)
				{
					// Font texture size has changed
					m_font_texture_width = m_font_material.mainTexture.width;
					m_font_texture_height = m_font_material.mainTexture.height;
					SetText(m_text, true);
					return;
				}
			}
			
			// Calculate bounds of text mesh
			char character;
			float y_max=0, y_min=0, x_max=0, x_min=0;
			float text_width = 0, text_height = 0;
			int line_letter_idx = 0;
			float line_height_offset = 0;
			float total_text_width = 0, total_text_height = 0;
			float line_width_at_last_space = 0;
			float space_char_offset = 0;
			int last_letter_setup_idx = -1;
			float last_space_y_max = 0;
			float last_space_y_min = 0;
			Rect uv_data;
			LetterSetup last_letter = null;
			
			float letter_offset = 0;
			int letter_count = 0;
			int line_idx = 0;
			int word_idx = 0;

			m_line_height = 0;
			
			Action AddNewLineData = new Action( () =>
			{
				if(m_display_axis == TextDisplayAxis.HORIZONTAL)
				{
					float height = Mathf.Abs(y_max - y_min ) * LineHeightFactor;

					// Check if line is the tallest so far
					if(height > m_line_height)
						m_line_height = height;

					if(last_char_info != null)
					{
						// Re-adjust width of last letter since its the end of the text line
						text_width += - last_char_info.width + last_char_info.vert.width + last_char_info.vert.x;
					}
					
					m_text_datas.Add( new TextSizeData(text_width, height, line_height_offset, y_max));
					line_height_offset += height;
					
					if(text_width > total_text_width)
					{
						total_text_width = text_width;
					}
					total_text_height += height;
				}
				else
				{
					float width = Mathf.Abs( x_max - x_min ) * LineHeightFactor;

					// Check if line is the tallest so far
					if(width > m_line_height)
						m_line_height = width;

					m_text_datas.Add( new TextSizeData( width, text_height * -1, line_height_offset, 0));
					line_height_offset += width;
					
					total_text_width += width;
					if(text_height < total_text_height)
					{
						total_text_height = text_height;
					}
				}
				
				line_letter_idx = 0;
				text_width = 0;
				line_width_at_last_space = 0;
				space_char_offset = 0;
				last_space_y_max = 0;
				last_space_y_min = 0;
				last_letter_setup_idx = -1;
				text_height = 0;
				last_char_info = null;
			});
			
			for(int letter_idx=0; letter_idx < text_length; letter_idx++)
			{
				character = new_text[letter_idx];
				
				if(GetCharacterInfo(character, ref char_info))
				{
					if(character.Equals('\t'))
					{
						continue;
					}
					else if(character.Equals(' '))
					{
						if(m_display_axis == TextDisplayAxis.HORIZONTAL)
						{
							// Record the state of the line dims at this point incase the next word is forced onto next line by bound box
							line_width_at_last_space = text_width;
							space_char_offset = char_info.width;
							last_space_y_max = y_max;
							last_space_y_min = y_min;
							
							last_letter_setup_idx = letter_count;
							text_width += char_info.width;
						}
						else
						{
							char_info.vert.height = -char_info.width;
						}
						
						// Add space width to offset value
						letter_offset += m_display_axis == TextDisplayAxis.HORIZONTAL ? char_info.width : -char_info.width;
						
						//Increment word count
						word_idx++;
					}
					else if(character.Equals('\n'))
					{
						AddNewLineData.Invoke();
						
						letter_offset = 0;
						line_idx++;
						
						//Increment word count
						word_idx++;
					}
					else
					{
						if(m_display_axis == TextDisplayAxis.HORIZONTAL)
						{
							if(line_letter_idx == 0 || char_info.vert.y > y_max)
							{
								y_max = char_info.vert.y;
							}
							if(line_letter_idx == 0 || char_info.vert.y + char_info.vert.height < y_min)
							{
								y_min = char_info.vert.y + char_info.vert.height;
							}
							
							// increment the text width by the letter progress width, and then full mesh width for last letter or end of line.
							text_width += (letter_idx == text_length - 1)
												? char_info.vert.width + char_info.vert.x :
													char_info.width;
							
							// Handle bounding box if setup
							if(m_max_width > 0 && last_letter_setup_idx >= 0)
							{
								float actual_line_width = (letter_idx == text_length - 1) ? text_width : text_width - char_info.width + char_info.vert.width + char_info.vert.x;
								
								if(actual_line_width > m_max_width)
								{
									// Line exceeds bounding box width
									float new_line_text_width = text_width - line_width_at_last_space - space_char_offset;
									float new_line_y_min = last_space_y_min;
									float new_line_y_max = last_space_y_max;									
										
									// Set line width to what it was at the last space (which is now the end of this line)
									text_width = line_width_at_last_space;
									y_max = last_space_y_max;
									y_min = last_space_y_min;
									
									
									letter_offset = 0;
									line_idx++;
									
									// Need to change the associated line number and positional offset of the letters now on a new line
									for(int past_letter_idx=last_letter_setup_idx; past_letter_idx < letter_count; past_letter_idx++)
									{
										m_letters[past_letter_idx].m_progression_variables.m_line_value = line_idx;
										
										m_letters[past_letter_idx].m_base_offset = m_display_axis == TextDisplayAxis.HORIZONTAL ? new Vector3(letter_offset, 0, 0) : new Vector3(0, letter_offset, 0);
										
										letter_offset += m_display_axis == TextDisplayAxis.HORIZONTAL ? 
											m_letters[past_letter_idx].m_offset_width + (m_px_offset.x / FontScale) : 
												m_letters[past_letter_idx].m_height + (-m_px_offset.y / FontScale);
									}
									
									AddNewLineData.Invoke();
									
									// Setup current values
									text_width = new_line_text_width;
									y_min = new_line_y_min;
									y_max = new_line_y_max;
								}
							}
						}
						else
						{
							if(line_letter_idx == 0 || char_info.vert.x + char_info.vert.width > x_max)
							{
								x_max = char_info.vert.x + char_info.vert.width;
							}
							if(line_letter_idx == 0 || char_info.vert.x < x_min)
							{
								x_min = char_info.vert.x;
							}
							
							text_height += char_info.vert.height;
						}
						
						
						// Get letterSetup reference
						if(letter_count < prev_letters.Length && !force_all_new)
						{
							last_letter = prev_letters[letter_count];
						}
						
						// Either reuse the same previous instance of LetterSetup or create a new one for this character.
						
						if(	!force_all_new
							&& prev_letters != null
							&& letter_count < prev_letters.Length
							&& last_letter.m_character.Equals(new_text[letter_idx].ToString())
							&& last_letter.m_progression_variables.m_letter_value == letter_idx
							&& last_letter.m_mesh != null)
						{
							// Use same LetterSetup from previous configuration
							m_letters[letter_count] = last_letter;
							
							// Remove instance from previous letters list
							prev_letters[letter_count] = null;
							
							// position the letter offset again, incase it has changed from previous letters changing.
							last_letter.m_base_offset = m_display_axis == TextDisplayAxis.HORIZONTAL ? new Vector3(letter_offset, 0, 0) : new Vector3(0, letter_offset, 0);
							last_letter.SetupLetterMesh(ref char_info);
							last_letter.m_progression_variables.m_line_value = line_idx;
							last_letter.m_progression_variables.m_word_value = word_idx;
							last_letter.m_base_offsets_setup = false;
						}
						else
						{
							uv_data = char_info.uv;
							
							if(letter_count < prev_letters.Length && !force_all_new)
							{
								// Recycle last letter instance.
								m_letters[letter_count] = last_letter;
								
								// Setup Mesh UV co-ords and triangles (and fill in placeholder vertices)
								last_letter.m_mesh.vertices = new Vector3[]{Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero};
								last_letter.m_mesh.uv = new Vector2[]{ new Vector2(uv_data.x + uv_data.width, uv_data.y + uv_data.height), new Vector2(uv_data.x, uv_data.y + uv_data.height), new Vector2(uv_data.x, uv_data.y), new Vector2(uv_data.x + uv_data.width, uv_data.y)};
								last_letter.m_mesh.triangles = new int[]{2,1,0, 3,2,0};
								last_letter.m_mesh.normals = new Vector3[]{ Vector3.back, Vector3.back, Vector3.back, Vector3.back};
								
								last_letter.Recycle(
									"" + character,
									letter_count,
									last_letter.m_mesh,
									m_display_axis == TextDisplayAxis.HORIZONTAL ? new Vector3(letter_offset, 0, 0) : new Vector3(0, letter_offset, 0),		// base_offset
									ref char_info,
									line_idx,
									word_idx,
									this);
								
								last_letter.m_base_offsets_setup = false;
								
								// Remove instance from previous letters list
								prev_letters[letter_count] = null;
							}
							else
							{	
								Mesh mesh = new Mesh();
								// Setup Mesh UV co-ords and triangles (and fill in placeholder vertices)
								mesh.vertices = new Vector3[]{Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero};
								mesh.uv = new Vector2[]{ new Vector2(uv_data.x + uv_data.width, uv_data.y + uv_data.height), new Vector2(uv_data.x, uv_data.y + uv_data.height), new Vector2(uv_data.x, uv_data.y), new Vector2(uv_data.x + uv_data.width, uv_data.y)};
								mesh.triangles = new int[]{2,1,0, 3,2,0};
								mesh.normals = new Vector3[]{ Vector3.back, Vector3.back, Vector3.back, Vector3.back};
								
								m_letters[letter_count] = new LetterSetup(
									"" + character,
									letter_count,
									mesh,
									m_display_axis == TextDisplayAxis.HORIZONTAL ? new Vector3(letter_offset, 0, 0) : new Vector3(0, letter_offset, 0),		// base_offset
									ref char_info,
									line_idx,
									word_idx,
									this);
								
								if(last_letter != null)
								{
									m_letters[letter_count].SetAnimationVars(last_letter);
								}
							}
							
						}
						
						letter_count ++;
						
						letter_offset += m_display_axis == TextDisplayAxis.HORIZONTAL ? 
												char_info.width + (m_px_offset.x / FontScale) : 
												char_info.vert.height + (-m_px_offset.y / FontScale);
						
						
						last_char_info = char_info;
						
					}
				}
				
				line_letter_idx++;
			}
			
			// Save line and word info for later
			m_number_of_words = word_idx + 1;
			m_number_of_lines = line_idx + 1;
			
			if(m_display_axis == TextDisplayAxis.HORIZONTAL)
			{
				float height = Mathf.Abs(y_max - y_min );
				m_text_datas.Add( new TextSizeData(text_width, height, line_height_offset, y_max));
				
				if(text_width > total_text_width)
				{
					total_text_width = text_width;
				}
				total_text_height += height;
			}
			else
			{
				float width = Mathf.Abs( x_max - x_min );
				m_text_datas.Add( new TextSizeData( width, text_height * -1, line_height_offset, 0));
				
				total_text_width += width;
				
				if(text_height < total_text_height)
				{
					total_text_height = text_height;
				}
			}

#if UNITY_EDITOR
			m_total_text_width = total_text_width;
			m_total_text_height = total_text_height;
#endif
			
			for(int idx=0; idx < m_text_datas.Count; idx++)
			{
				m_text_datas[idx].m_total_text_height = total_text_height * (m_display_axis == TextDisplayAxis.HORIZONTAL ? 1 : -1);
				
				if(m_max_width > 0)
				{
					m_text_datas[idx].m_total_text_width = m_max_width;
				}
				else
				{
					m_text_datas[idx].m_total_text_width = total_text_width;
				}
			}
			
			// Destroy any left over unused meshes
			if(prev_letters != null)
			{
				foreach(LetterSetup old_letter in prev_letters)
				{
					if(old_letter != null)
					{
						// Letter wasn't used in new text setup; delete it's mesh instance.
						if(Application.isPlaying)
						{
							Destroy(old_letter.m_mesh);
						}
						else
						{
							DestroyImmediate(old_letter.m_mesh);
						}
					}
				}
			}
			
			
			// Set letter base offsets where needed
			bool all_offsets_set = true;
			do
			{
				all_offsets_set = true;
				
				foreach(LetterSetup letter in m_letters)
				{
					if(!letter.m_base_offsets_setup)
					{
						if(m_text_datas.Count == 0)
						{
							all_offsets_set = false;
							break;
						}
						letter.SetBaseOffset(m_text_anchor, m_display_axis, m_text_alignment, m_text_datas);
					}
				}
				
				if(!all_offsets_set)
				{
					// If text_datas has been lost or if legacy effect and hasn't been created, re-set text to recalculate it.
					Debug.LogError("If text_datas has been lost or if legacy effect and hasn't been created, reset text.");
					SetText(m_text);
				}
			}
			while(!all_offsets_set);
			
			// Calculate action progression values
			PrepareAnimationData();
			
			// Render state of newly set text
			UpdateMesh(true, true, 0, 0);
		}