void SetupMesh(LetterAction letter_action, LetterAction prev_action, float action_progress, AnimationProgressionVariables progression_variables, AnimatePerOptions animate_per, float linear_progress, EffectManager effect_manager) { // construct current anchor offset vector m_anchor_offset = letter_action.AnchorOffsetStart; m_anchor_offset = new Vector3(m_anchor_offset.x * m_width, letter_action.m_letter_anchor_start == (int)TextfxTextAnchor.BaselineLeft || letter_action.m_letter_anchor_start == (int)TextfxTextAnchor.BaselineCenter || letter_action.m_letter_anchor_start == (int)TextfxTextAnchor.BaselineRight ? 0 // zero because letters are based around the baseline already. : (effect_manager.IsFontBaseLineSet ? (effect_manager.FontBaseLine + m_y_offset) - (m_anchor_offset.y * -m_height) : (m_anchor_offset.y * m_height)), // Legacy effect support when baseline isn't already set. 0); if (letter_action.m_letter_anchor_2_way) { m_anchor_offset = letter_action.AnchorOffsetEnd; m_anchor_offset = Vector3.Lerp(m_anchor_offset, new Vector3( m_anchor_offset.x * m_width, letter_action.m_letter_anchor_end == (int)TextfxTextAnchor.BaselineLeft || letter_action.m_letter_anchor_end == (int)TextfxTextAnchor.BaselineCenter || letter_action.m_letter_anchor_end == (int)TextfxTextAnchor.BaselineRight ? 0 // zero because letters are based around the baseline already. : (effect_manager.IsFontBaseLineSet ? (effect_manager.FontBaseLine + m_y_offset) - (m_anchor_offset.y * -m_height) : (m_anchor_offset.y * m_height)), // Legacy effect support when baseline isn't already set. 0), action_progress); } // Calculate Scale Vector from_vec = letter_action.m_start_scale.GetValue(progression_variables, animate_per); to_vec = letter_action.m_end_scale.GetValue(progression_variables, animate_per); if (letter_action.m_scale_axis_ease_data.m_override_default) { m_letter_scale = new Vector3(EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_x_ease, linear_progress)), EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_y_ease, linear_progress)), EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_z_ease, linear_progress))); } else { m_letter_scale = EffectManager.Vector3Lerp( from_vec, to_vec, action_progress); } // Calculate Rotation from_vec = letter_action.m_start_euler_rotation.GetValue(progression_variables, animate_per); to_vec = letter_action.m_end_euler_rotation.GetValue(progression_variables, animate_per); if (letter_action.m_rotation_axis_ease_data.m_override_default) { m_letter_rotation = Quaternion.Euler ( EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_x_ease, linear_progress)), EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_y_ease, linear_progress)), EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_z_ease, linear_progress)) ); } else { m_letter_rotation = Quaternion.Euler( EffectManager.Vector3Lerp( from_vec, to_vec, action_progress) ); } // Calculate Position if (letter_action.m_start_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX || (letter_action.m_offset_from_last && prev_action != null && prev_action.m_end_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX)) { from_vec = new Vector3(-m_anchor_offset.x, m_base_offset.y, 0); } else if (letter_action.m_start_pos.ForcePositionOverride) { from_vec = new Vector3(-m_anchor_offset.x, 0, 0); } else { from_vec = BaseOffset; } from_vec += letter_action.m_start_pos.GetValue(progression_variables, animate_per); if (letter_action.m_end_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX || (letter_action.m_end_pos.IsOffsetFromLast && letter_action.m_start_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX)) { to_vec = new Vector3(-m_anchor_offset.x, m_base_offset.y, 0); } else if (letter_action.m_end_pos.ForcePositionOverride) { to_vec = new Vector3(-m_anchor_offset.x, 0, 0); } else { to_vec = BaseOffset; } to_vec += letter_action.m_end_pos.GetValue(progression_variables, animate_per); if (letter_action.m_position_axis_ease_data.m_override_default) { m_letter_position = new Vector3(EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_x_ease, linear_progress)), EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_y_ease, linear_progress)), EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_z_ease, linear_progress))); } else { m_letter_position = EffectManager.Vector3Lerp( from_vec, to_vec, action_progress); } // Calculate letter center position m_letter_center = new Vector3(m_width / 2, m_height / 2, 0); m_letter_center -= m_anchor_offset; m_letter_center = Vector3.Scale(m_letter_center, m_letter_scale); m_letter_center = m_letter_rotation * m_letter_center; m_letter_center += m_anchor_offset + m_letter_position; if (mesh_verts == null || mesh_verts.Length == 0) { mesh_verts = new Vector3[4]; } for (int idx = 0; idx < 4; idx++) { mesh_verts[idx] = m_base_vertices[idx]; // normalise vert position to the anchor point before scaling and rotating. mesh_verts[idx] -= m_anchor_offset; // Scale verts mesh_verts[idx] = Vector3.Scale(mesh_verts[idx], m_letter_scale); // Rotate vert mesh_verts[idx] = m_letter_rotation * mesh_verts[idx]; mesh_verts[idx] += m_anchor_offset; // translate vert mesh_verts[idx] += m_letter_position; } m_mesh.vertices = mesh_verts; // Sort out letters colour if (letter_action.m_use_gradient_start) { start_colour = letter_action.m_start_vertex_colour.GetValue(progression_variables, animate_per); } else { start_colour = new VertexColour(letter_action.m_start_colour.GetValue(progression_variables, animate_per)); } if (letter_action.m_use_gradient_end) { end_colour = letter_action.m_end_vertex_colour.GetValue(progression_variables, animate_per); } else { end_colour = new VertexColour(letter_action.m_end_colour.GetValue(progression_variables, animate_per)); } if (!m_flipped) { m_mesh.colors = new Color[] { Color.Lerp(start_colour.top_right, end_colour.top_right, action_progress), Color.Lerp(start_colour.top_left, end_colour.top_left, action_progress), Color.Lerp(start_colour.bottom_left, end_colour.bottom_left, action_progress), Color.Lerp(start_colour.bottom_right, end_colour.bottom_right, action_progress) }; } else { m_mesh.colors = new Color[] { Color.Lerp(start_colour.top_left, end_colour.top_left, action_progress), Color.Lerp(start_colour.bottom_left, end_colour.bottom_left, action_progress), Color.Lerp(start_colour.bottom_right, end_colour.bottom_right, action_progress), Color.Lerp(start_colour.top_right, end_colour.top_right, action_progress) }; } }
public static float GetEaseProgress(EasingEquation ease_type, float linear_progress) { switch (ease_type) { case EasingEquation.Linear: return(linear_progress); case EasingEquation.BackEaseIn: return(EasingManager.BackEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.BackEaseInOut: return(EasingManager.BackEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.BackEaseOut: return(EasingManager.BackEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.BackEaseOutIn: return(EasingManager.BackEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.BounceEaseIn: return(EasingManager.BounceEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.BounceEaseInOut: return(EasingManager.BounceEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.BounceEaseOut: return(EasingManager.BounceEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.BounceEaseOutIn: return(EasingManager.BounceEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.CircEaseIn: return(EasingManager.CircEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.CircEaseInOut: return(EasingManager.CircEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.CircEaseOut: return(EasingManager.CircEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.CircEaseOutIn: return(EasingManager.CircEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.CubicEaseIn: return(EasingManager.CubicEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.CubicEaseInOut: return(EasingManager.CubicEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.CubicEaseOut: return(EasingManager.CubicEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.CubicEaseOutIn: return(EasingManager.CubicEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.ElasticEaseIn: return(EasingManager.ElasticEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.ElasticEaseInOut: return(EasingManager.ElasticEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.ElasticEaseOut: return(EasingManager.ElasticEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.ElasticEaseOutIn: return(EasingManager.ElasticEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.ExpoEaseIn: return(EasingManager.ExpoEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.ExpoEaseInOut: return(EasingManager.ExpoEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.ExpoEaseOut: return(EasingManager.ExpoEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.ExpoEaseOutIn: return(EasingManager.ExpoEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.QuadEaseIn: return(EasingManager.QuadEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.QuadEaseInOut: return(EasingManager.QuadEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.QuadEaseOut: return(EasingManager.QuadEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.QuadEaseOutIn: return(EasingManager.QuadEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.QuartEaseIn: return(EasingManager.QuartEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.QuartEaseInOut: return(EasingManager.QuartEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.QuartEaseOut: return(EasingManager.QuartEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.QuartEaseOutIn: return(EasingManager.QuartEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.QuintEaseIn: return(EasingManager.QuintEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.QuintEaseInOut: return(EasingManager.QuintEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.QuintEaseOut: return(EasingManager.QuintEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.QuintEaseOutIn: return(EasingManager.QuintEaseOutIn(linear_progress, 0, 1, 1)); case EasingEquation.SineEaseIn: return(EasingManager.SineEaseIn(linear_progress, 0, 1, 1)); case EasingEquation.SineEaseInOut: return(EasingManager.SineEaseInOut(linear_progress, 0, 1, 1)); case EasingEquation.SineEaseOut: return(EasingManager.SineEaseOut(linear_progress, 0, 1, 1)); case EasingEquation.SineEaseOutIn: return(EasingManager.SineEaseOutIn(linear_progress, 0, 1, 1)); default: return(linear_progress); } }
// Animates the letter mesh and return the current action index in use public LETTER_ANIMATION_STATE AnimateMesh(bool force_render, float timer, TextAnchor text_anchor, int lowest_action_progress, LetterAnimation animation, AnimatePerOptions animate_per, float delta_time, EffectManager effect_manager) { m_last_animate_per = animate_per; m_effect_manager_handle = effect_manager; if (animation.NumActions > 0 && m_anim_state_vars.m_action_index < animation.NumActions) { if (!m_anim_state_vars.m_active && !force_render) { return(LETTER_ANIMATION_STATE.STOPPED); } if (m_anim_state_vars.m_action_index != m_anim_state_vars.m_prev_action_index) { SetCurrentLetterAction(animation.GetAction(m_anim_state_vars.m_action_index), animate_per); m_anim_state_vars.m_started_action = false; } else if (m_current_letter_action == null) { SetCurrentLetterAction(animation.GetAction(m_anim_state_vars.m_action_index), animate_per); } m_anim_state_vars.m_prev_action_index = m_anim_state_vars.m_action_index; if (force_render) { SetupMesh(m_current_letter_action, m_anim_state_vars.m_action_index > 0 ? animation.GetAction(m_anim_state_vars.m_action_index - 1) : null, m_anim_state_vars.m_action_progress, m_progression_variables, animate_per, m_anim_state_vars.m_linear_progress, m_effect_manager_handle); } if (m_anim_state_vars.m_waiting_to_sync) { if (m_current_letter_action.m_action_type == ACTION_TYPE.BREAK) { if (!force_render && m_anim_state_vars.m_break_delay > 0) { m_anim_state_vars.m_break_delay -= delta_time; if (m_anim_state_vars.m_break_delay <= 0) { ContinueAction(timer, animation, animate_per); return(LETTER_ANIMATION_STATE.PLAYING); } } return(LETTER_ANIMATION_STATE.WAITING); } else if (lowest_action_progress < m_anim_state_vars.m_action_index_progress) { return(LETTER_ANIMATION_STATE.PLAYING); } else if (!force_render) { m_anim_state_vars.m_waiting_to_sync = false; // reset timer offset to compensate for the sync-up wait time m_anim_state_vars.m_timer_offset = timer; } } else if (!force_render && (m_current_letter_action.m_action_type == ACTION_TYPE.BREAK || (!m_anim_state_vars.m_reverse && m_current_letter_action.m_force_same_start_time && lowest_action_progress < m_anim_state_vars.m_action_index_progress))) { // Force letter to wait for rest of letters to be in sync m_anim_state_vars.m_waiting_to_sync = true; m_anim_state_vars.m_break_delay = Mathf.Max(m_current_letter_action.m_duration_progression.GetValue(m_progression_variables, animate_per), 0); return(LETTER_ANIMATION_STATE.PLAYING); } if (force_render) { return(m_anim_state_vars.m_active ? LETTER_ANIMATION_STATE.PLAYING : LETTER_ANIMATION_STATE.STOPPED); } m_anim_state_vars.m_action_progress = 0; m_anim_state_vars.m_linear_progress = 0; m_action_timer = timer - m_anim_state_vars.m_timer_offset; if ((m_anim_state_vars.m_reverse || m_action_timer > m_action_delay)) { m_anim_state_vars.m_linear_progress = (m_action_timer - (m_anim_state_vars.m_reverse ? 0 : m_action_delay)) / m_action_duration; if (m_anim_state_vars.m_reverse) { if (m_action_timer >= m_action_duration) { m_anim_state_vars.m_linear_progress = 0; } else { m_anim_state_vars.m_linear_progress = 1 - m_anim_state_vars.m_linear_progress; } } if (!m_anim_state_vars.m_started_action) { // Trigger any action onStart audio or particle effects TriggerAudioEffect(animate_per, PLAY_ITEM_EVENTS.ON_START); TriggerParticleEffects(animate_per, PLAY_ITEM_EVENTS.ON_START); m_anim_state_vars.m_started_action = true; } m_anim_state_vars.m_action_progress = EasingManager.GetEaseProgress(m_current_letter_action.m_ease_type, m_anim_state_vars.m_linear_progress); if ((!m_anim_state_vars.m_reverse && m_anim_state_vars.m_linear_progress >= 1) || (m_anim_state_vars.m_reverse && m_action_timer >= m_action_duration + m_action_delay)) { m_anim_state_vars.m_action_progress = m_anim_state_vars.m_reverse ? 0 : 1; m_anim_state_vars.m_linear_progress = m_anim_state_vars.m_reverse ? 0 : 1; if (!m_anim_state_vars.m_reverse && m_anim_state_vars.m_action_index != -1) { TriggerParticleEffects(animate_per, PLAY_ITEM_EVENTS.ON_FINISH); TriggerAudioEffect(animate_per, PLAY_ITEM_EVENTS.ON_FINISH); } int prev_action_idx = m_anim_state_vars.m_action_index; float prev_delay = m_action_delay; // Set next action index SetNextActionIndex(animation); if (m_anim_state_vars.m_active) { if (!m_anim_state_vars.m_reverse) { m_anim_state_vars.m_started_action = false; } if (!m_anim_state_vars.m_reverse && m_anim_state_vars.m_action_index_progress > m_anim_state_vars.m_action_index) { // Repeating the action again; check for unqiue random variable requests. animation.GetAction(m_anim_state_vars.m_action_index).SoftReset(animation.GetAction(prev_action_idx), m_progression_variables, animate_per, m_anim_state_vars.m_action_index == 0); } else if (m_anim_state_vars.m_reverse) { animation.GetAction(m_anim_state_vars.m_action_index).SoftResetStarts(animation.GetAction(prev_action_idx), m_progression_variables, animate_per); } // Add to the timer offset m_anim_state_vars.m_timer_offset += prev_delay + m_action_duration; if (prev_action_idx != m_anim_state_vars.m_action_index) { UpdateLoopList(animation); } else { SetCurrentLetterAction(animation.GetAction(m_anim_state_vars.m_action_index), animate_per); } } } } SetupMesh(m_current_letter_action, m_anim_state_vars.m_action_index > 0 ? animation.GetAction(m_anim_state_vars.m_action_index - 1) : null, m_anim_state_vars.m_action_progress, m_progression_variables, animate_per, m_anim_state_vars.m_linear_progress, m_effect_manager_handle); } else { // no actions found for this letter. Position letter in its default position if (mesh_verts == null || mesh_verts.Length == 0) { mesh_verts = new Vector3[4]; } for (int idx = 0; idx < 4; idx++) { mesh_verts[idx] = m_base_vertices[idx] + m_base_offset; } m_mesh.vertices = mesh_verts; m_anim_state_vars.m_active = false; } return(m_anim_state_vars.m_active ? LETTER_ANIMATION_STATE.PLAYING : LETTER_ANIMATION_STATE.STOPPED); }