public void Progress(float timeStep)
    {
        RectTransform   textTrans             = null;
        bool            textPaused            = false;
        bool            progressText          = false;
        int             textStage             = INVALID_TEXT_STAGE;
        float           stageDuration         = 0f;
        float           stageElapsed          = 0f;
        float           stageRate             = 0f;
        bool            keepStage             = false;
        SpritedStringUI text                  = null;
        Color           textColor             = Color.white;
        Vector3         textScale             = Vector3.one;
        Vector2         textIncreasedScale    = Vector2.zero;
        bool            textRemoved           = false;
        int             textEvolution         = INVALID_TEXT_EVOLUTION;
        float           textElapsed           = 0f;
        Transform       textOriginTrans       = null;
        Vector2         textOriginWorld       = Vector2.zero;
        Vector2         textOriginCanvas      = Vector2.zero;
        Vector3         completeWorldPos      = Vector3.zero;
        Vector2         currentOriginWorldPos = Vector2.zero;
        Vector2         textSpeed             = Vector2.zero;

        if (textTransforms != null)
        {
            for (int i = 0; i < textTransforms.Length; i++)
            {
                textPaused = textPauseds[i];

                /*halmeida - if a text was added during a game pause, I will progress it during the pause and I will continue
                 * progressing it after the game is unpaused, because I don't want it to get stuck in the screen until the next pause.
                 * However, if a text was added when the game was unpaused, I will only progress it while the game is unpaused.*/
                progressText = (textPaused || (!textPaused && !paused));
                if (progressText)
                {
                    textTrans   = textTransforms[i];
                    text        = texts[i];
                    textStage   = textStages[i];
                    stageRate   = 0f;
                    textRemoved = false;
                    switch (textStage)
                    {
                    case TEXT_STAGE_SHOW:
                        stageDuration = textDurationsShow[i];
                        if (stageDuration <= 0f)
                        {
                            stageRate = 1f;
                        }
                        else
                        {
                            stageElapsed  = textStageElapseds[i];
                            stageElapsed += timeStep;
                            stageRate     = stageElapsed / stageDuration;
                            stageRate     = (stageRate > 1f) ? 1f : stageRate;
                            textColor     = text.GetGeneralColor();
                            textColor.a   = Mathf.Lerp(0f, 1f, stageRate);
                            text.SetGeneralColor(textColor);
                            textIncreasedScale   = textIncreasedScales[i];
                            textScale            = textTrans.localScale;
                            textScale.x          = Mathf.Lerp(textIncreasedScale.x, 1f, stageRate);
                            textScale.y          = Mathf.Lerp(textIncreasedScale.y, 1f, stageRate);
                            textTrans.localScale = textScale;
                        }
                        break;

                    case TEXT_STAGE_PLAIN:
                        stageDuration = textDurationsPlain[i];
                        if (stageDuration <= 0f)
                        {
                            stageRate = 1f;
                        }
                        else
                        {
                            stageElapsed  = textStageElapseds[i];
                            stageElapsed += timeStep;
                            stageRate     = stageElapsed / stageDuration;
                            stageRate     = (stageRate > 1f) ? 1f : stageRate;
                        }
                        break;

                    case TEXT_STAGE_HIDE:
                        stageDuration = textDurationsHide[i];
                        if (stageDuration <= 0f)
                        {
                            stageRate = 1f;
                        }
                        else
                        {
                            stageElapsed  = textStageElapseds[i];
                            stageElapsed += timeStep;
                            stageRate     = stageElapsed / stageDuration;
                            stageRate     = (stageRate > 1f) ? 1f : stageRate;
                            textColor     = text.GetGeneralColor();
                            textColor.a   = Mathf.Lerp(1f, 0f, stageRate);
                            text.SetGeneralColor(textColor);
                            textIncreasedScale   = textIncreasedScales[i];
                            textScale            = textTrans.localScale;
                            textScale.x          = Mathf.Lerp(1f, textIncreasedScale.x, stageRate);
                            textScale.y          = Mathf.Lerp(1f, textIncreasedScale.y, stageRate);
                            textTrans.localScale = textScale;
                        }
                        break;

                    case TEXT_STAGE_OVER:
                        RemoveCanvasText(i);
                        textRemoved = true;
                        break;
                    }
                    if (textRemoved)
                    {
                        if (textTransforms != null)
                        {
                            i--;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        textEvolution = textEvolutions[i];
                        if ((textEvolution == TEXT_EVOLUTION_NONE_WAIT) && endWaitingTexts)
                        {
                            textEvolutions[i] = TEXT_EVOLUTION_NONE_GO;
                            textEvolution     = TEXT_EVOLUTION_NONE_GO;
                        }
                        if (stageRate == 1f)
                        {
                            keepStage = ((textEvolution == TEXT_EVOLUTION_NONE_WAIT) && (textStage == TEXT_STAGE_PLAIN));
                            if (!keepStage)
                            {
                                textStage++;
                                textStages[i]        = textStage;
                                textStageElapseds[i] = 0f;
                            }
                            else
                            {
                                textStageElapseds[i] = stageElapsed;
                            }
                        }
                        else
                        {
                            textStageElapseds[i] = stageElapsed;
                        }
                        textElapsed     = textElapseds[i];
                        textElapsed    += timeStep;
                        textElapseds[i] = textElapsed;
                        textOriginTrans = textOriginTransforms[i];
                        textOriginWorld = textOriginPositions[i];
                        if (textOriginTrans != null)
                        {
                            completeWorldPos       = textOriginTrans.position;
                            currentOriginWorldPos  = new Vector2(completeWorldPos.x, completeWorldPos.y);
                            currentOriginWorldPos += textOriginWorld;
                        }
                        else
                        {
                            currentOriginWorldPos = textOriginWorld;
                        }
                        if (TransformWorldToCanvasPosition(currentOriginWorldPos, ref textOriginCanvas))
                        {
                            textSpeed = textSpeeds[i];
                            textTrans.anchoredPosition = textOriginCanvas + (textElapsed * textSpeed);
                        }
                        text.FeedPositionToMaterial();
                    }
                }
            }
        }
        endWaitingTexts = false;
    }
    private bool AddCanvasText(string textString, SymbolDatabase textFont, Color textColor, Vector4 textColorGradient, int textEvolution,
                               Transform originTransform, Vector2 originWorldPosition, bool workDuringPause)
    {
        GameObject      textObject         = null;
        RectTransform   textTrans          = null;
        SpritedStringUI text               = null;
        int             textIndex          = -1;
        Vector3         completeWorldPos   = Vector3.zero;
        Vector2         currentWorldPos    = Vector2.zero;
        Vector2         canvasPosition     = Vector2.zero;
        Vector2         textSpeed          = Vector2.zero;
        Vector2         textIncreasedScale = Vector2.zero;
        Color           textGeneralColor   = Color.white;
        float           textDurationShow   = 0f;
        float           textDurationPlain  = 0f;
        float           textDurationHide   = 0f;
        int             textStage          = INVALID_TEXT_STAGE;

        if (originTransform != null)
        {
            completeWorldPos = originTransform.position;
            currentWorldPos  = new Vector2(completeWorldPos.x, completeWorldPos.y);

            /*halmeida - in case there is an origin transform, the originWorldPosition vector is interpreted as an offset
             * from the transform's position.*/
            currentWorldPos += originWorldPosition;
        }
        else
        {
            currentWorldPos = originWorldPosition;
        }
        if (TransformWorldToCanvasPosition(currentWorldPos, ref canvasPosition))
        {
            textIndex  = (textObjects == null) ? 0 : textObjects.Length;
            textObject = new GameObject("UIText" + textIndex, typeof(RectTransform));
            if (textObject != null)
            {
                textTrans = textObject.GetComponent <RectTransform>();
                text      = textObject.AddComponent <SpritedStringUI>();
                if (text != null)
                {
                    text.SetSymbolSource(textFont);
                    text.ToggleRaycastTargeting(false);
                    text.SetValue(textString);
                    textTrans.SetParent(interfaceCanvasTrans, false);
                    textTrans.anchoredPosition = canvasPosition;
                    switch (textEvolution)
                    {
                    case TEXT_EVOLUTION_ASCENT:
                        textSpeed.y        = TEXT_ASCENT_SPEED;
                        textGeneralColor   = text.GetGeneralColor();
                        textGeneralColor.a = 0f;
                        text.SetGeneralColor(textGeneralColor);
                        textStage            = TEXT_STAGE_SHOW;
                        textIncreasedScale   = new Vector2(TEXT_ASCENT_START_SCALE_X, TEXT_ASCENT_START_SCALE_Y);
                        textTrans.localScale = new Vector3(textIncreasedScale.x, textIncreasedScale.y, 1f);
                        textDurationShow     = TEXT_ASCENT_DURATION_SHOW;
                        textDurationPlain    = TEXT_ASCENT_DURATION_PLAIN;
                        textDurationHide     = TEXT_ASCENT_DURATION_HIDE;
                        break;

                    case TEXT_EVOLUTION_STAY:
                        textGeneralColor   = text.GetGeneralColor();
                        textGeneralColor.a = 0f;
                        text.SetGeneralColor(textGeneralColor);
                        textStage            = TEXT_STAGE_SHOW;
                        textIncreasedScale   = new Vector2(TEXT_STAY_START_SCALE_X, TEXT_STAY_START_SCALE_Y);
                        textTrans.localScale = new Vector3(textIncreasedScale.x, textIncreasedScale.y, 1f);
                        textDurationShow     = TEXT_STAY_DURATION_SHOW;
                        textDurationPlain    = TEXT_STAY_DURATION_PLAIN;
                        textDurationHide     = TEXT_STAY_DURATION_HIDE;
                        break;

                    case TEXT_EVOLUTION_NONE_WAIT:
                    case TEXT_EVOLUTION_NONE_GO:
                        textGeneralColor   = text.GetGeneralColor();
                        textGeneralColor.a = 0f;
                        text.SetGeneralColor(textGeneralColor);
                        textStage            = TEXT_STAGE_SHOW;
                        textIncreasedScale   = new Vector2(TEXT_NONE_START_SCALE_X, TEXT_NONE_START_SCALE_Y);
                        textTrans.localScale = new Vector3(textIncreasedScale.x, textIncreasedScale.y, 1f);
                        textDurationShow     = TEXT_NONE_DURATION_SHOW;
                        textDurationPlain    = TEXT_NONE_DURATION_PLAIN;
                        textDurationHide     = TEXT_NONE_DURATION_HIDE;
                        break;
                    }
                    text.SetColor(textColor, textColorGradient);
                    UsefulFunctions.IncreaseArray <GameObject>(ref textObjects, textObject);
                    UsefulFunctions.IncreaseArray <RectTransform>(ref textTransforms, textTrans);
                    UsefulFunctions.IncreaseArray <SpritedStringUI>(ref texts, text);
                    UsefulFunctions.IncreaseArray <int>(ref textEvolutions, textEvolution);
                    UsefulFunctions.IncreaseArray <Transform>(ref textOriginTransforms, originTransform);
                    UsefulFunctions.IncreaseArray <Vector2>(ref textOriginPositions, originWorldPosition);
                    UsefulFunctions.IncreaseArray <Vector2>(ref textSpeeds, textSpeed);
                    UsefulFunctions.IncreaseArray <Vector2>(ref textIncreasedScales, textIncreasedScale);
                    UsefulFunctions.IncreaseArray <float>(ref textDurationsShow, textDurationShow);
                    UsefulFunctions.IncreaseArray <float>(ref textDurationsPlain, textDurationPlain);
                    UsefulFunctions.IncreaseArray <float>(ref textDurationsHide, textDurationHide);
                    UsefulFunctions.IncreaseArray <int>(ref textStages, textStage);
                    UsefulFunctions.IncreaseArray <float>(ref textStageElapseds, 0f);
                    UsefulFunctions.IncreaseArray <float>(ref textElapseds, 0f);
                    UsefulFunctions.IncreaseArray <bool>(ref textPauseds, workDuringPause);
                    return(true);
                }
            }
            textTrans = null;
            if (textObject != null)
            {
                Destroy(textObject);
            }
        }
        return(false);
    }