public void SetValueReference(ActionVector3Progression progression)
		{
			m_value_state = PROGRESSION_VALUE_STATE.REFERENCE;
			m_offset_progression = progression.ReferenceData;
		}
		public virtual void CalculateProgressions(int num_progressions,
		                                          ActionVector3Progression offset_prog,
		                                          bool variableActive = true)
		{
			if(!variableActive)
			{
				SetValueReference(offset_prog);
				return;
			}
			else if(m_is_offset_from_last && offset_prog != null)
			{
				m_value_state = PROGRESSION_VALUE_STATE.OFFSET_FROM_REFERENCE;
				m_offset_progression = offset_prog.GetOffsetReference();
			}
			else
				m_value_state = PROGRESSION_VALUE_STATE.UNIQUE;

			// Initialise the array of values. Array of only one if all progressions share the same constant value.
			m_values = new Vector3[Progression == (int) ValueProgression.Eased || Progression == (int) ValueProgression.EasedCustom || Progression == (int) ValueProgression.Random ? num_progressions : 1];

			// Calculate progression values
			if(Progression == (int) ValueProgression.Random)
			{
				for(int idx=0; idx < num_progressions; idx++)
				{
					m_values[idx] = new Vector3(m_from.x + (m_to.x - m_from.x) * UnityEngine.Random.value, m_from.y + (m_to.y - m_from.y) * UnityEngine.Random.value, m_from.z + (m_to.z - m_from.z) * UnityEngine.Random.value);
				}
			}
			else if(Progression == (int) ValueProgression.Eased)
			{
				float progression;
				
				for(int idx=0; idx < num_progressions; idx++)
				{
					progression = num_progressions == 1 ? 0 : (float)idx / ((float)num_progressions - 1f);
					
					if(m_to_to_bool)
					{
						if(progression <= 0.5f)
						{
							m_values[idx] = m_from + (m_to - m_from) * EasingManager.GetEaseProgress(m_ease_type, progression/0.5f);
						}
						else
						{
							progression -= 0.5f;
							m_values[idx] = m_to + (m_to_to - m_to) * EasingManager.GetEaseProgress(EasingManager.GetEaseTypeOpposite(m_ease_type), progression/0.5f);
						}
					}
					else
					{
						m_values[idx] = m_from + (m_to - m_from) * EasingManager.GetEaseProgress(m_ease_type, progression);
					}
				}
				
			}
			else if(Progression == (int) ValueProgression.EasedCustom)
			{
				float progression;
				
				for(int idx=0; idx < num_progressions; idx++)
				{
					progression = num_progressions == 1 ? 0 : (float)idx / ((float)num_progressions - 1f);
					
					if(m_ease_curve_per_axis)
					{
						m_values[idx].x = m_from.x + (m_to.x - m_from.x) * m_custom_ease_curve.Evaluate(progression);
						m_values[idx].y = m_from.y + (m_to.y - m_from.y) * m_custom_ease_curve_y.Evaluate(progression);
						m_values[idx].z = m_from.z + (m_to.z - m_from.z) * m_custom_ease_curve_z.Evaluate(progression);
					}
					else
						m_values[idx] = m_from + (m_to - m_from) * m_custom_ease_curve.Evaluate(progression);
				}
			}
			else if(Progression == (int) ValueProgression.Constant)
			{
				for(int idx=0; idx < m_values.Length; idx++)
				{
					m_values[idx] = m_from;
				}
			}
		}
		public ActionVector3Progression Clone()
		{
			ActionVector3Progression vector3_progression = new ActionVector3Progression(Vector3.zero);
			
			vector3_progression.m_progression_idx = Progression;
			vector3_progression.m_ease_type = m_ease_type;
			vector3_progression.m_from = m_from;
			vector3_progression.m_to = m_to;
			vector3_progression.m_to_to = m_to_to;
			vector3_progression.m_to_to_bool = m_to_to_bool;
			vector3_progression.m_is_offset_from_last = m_is_offset_from_last;
			vector3_progression.m_unique_randoms = m_unique_randoms;
			vector3_progression.m_override_animate_per_option = m_override_animate_per_option;
			vector3_progression.m_animate_per = m_animate_per;
			vector3_progression.m_ease_curve_per_axis = m_ease_curve_per_axis;
			vector3_progression.m_custom_ease_curve = new AnimationCurve(m_custom_ease_curve.keys);
			vector3_progression.m_custom_ease_curve_y = new AnimationCurve(m_custom_ease_curve_y.keys);
			vector3_progression.m_custom_ease_curve_z = new AnimationCurve(m_custom_ease_curve_z.keys);
			
			return vector3_progression;
		}
		public void CalculateRotationProgressions (ref float[] letter_progressions,
		                                           int num_progressions,
		                                           ActionVector3Progression offset_prog,
		                                           TextFxBezierCurve curve_override = null,
		                                           bool variableActive = true)
		{
			if(curve_override != null)
			{
				// Work out letter rotations based on the provided bezier curve setup
				
//				bool constant_offset = offset_vecs != null && offset_vecs.Length == 1;
				m_values = new Vector3[num_progressions];
				
				for(int idx=0; idx < num_progressions; idx++)
				{
//					m_values[idx] = m_is_offset_from_last ? offset_vecs[constant_offset ? 0 : idx] : Vector3.zero;
					m_values[idx] = Vector3.zero;
				}
				
				for(int idx=0; idx < num_progressions; idx++)
				{
					m_values[idx] += curve_override.GetCurvePointRotation(letter_progressions[idx]);
				}
			}
			else
//				CalculateProgressions(num_progressions, curve_override == null ? offset_prog : null /*m_values, curve_override != null*/);
				CalculateProgressions(num_progressions, offset_prog, variableActive);
		}