void UpdateTailAlgorithm()
        {
            TailCalculations_Begin();  // Root definition

            if (framesToSimulate != 0) // If framerate not defined then framesToSimulate is always == 1
            {
                if (UseCollision)
                {
                    BeginCollisionsUpdate();               // Updating colliders to collide with
                }
                // If post processing is needed we computing reference coordinates
                bool postProcesses = PostProcessingNeeded();

                MotionInfluenceLimiting();

                for (int i = 0; i < framesToSimulate; i++) // Simulating update frames
                {
                    SimulateTailMotionFrame(postProcesses);
                }

                // Updating root bone position
                TailSegments[_tc_startI].transform.position = TailSegments[_tc_startI].ProceduralPositionWeightBlended;
                TailSegments[_tc_startI].RefreshFinalPos(TailSegments[_tc_startI].ProceduralPositionWeightBlended);
                //TailSegments[_tc_startI].RefreshFinalLocalPos(TailSegments[_tc_startI].transform.localPosition);

                // Applying calculated coords to transforms
                if (_tc_startII > -1)
                {
                    TailSegment child = TailSegments[_tc_startII]; // Used in while() loops below
                    while (child != GhostChild)
                    {
                        // Calculate rotation
                        TailCalculations_SegmentRotation(child, child.LastKeyframeLocalPosition);

                        // Apply coords to segments
                        TailCalculations_ApplySegmentMotion(child);
                        child = child.ChildBone;
                    }
                }

                // If ghost child has transform let's apply motion too (change rotation of last bone)
                TailCalculations_SegmentRotation(GhostChild, GhostChild.LastKeyframeLocalPosition);
                GhostChild.ParentBone.transform.rotation = GhostChild.ParentBone.TrueTargetRotation;
                GhostChild.ParentBone.RefreshFinalRot(GhostChild.ParentBone.TrueTargetRotation);

                if (GhostChild.transform)
                {
                    GhostChild.RefreshFinalPos(GhostChild.transform.position);
                    GhostChild.RefreshFinalRot(GhostChild.transform.rotation);
                }
            }
            else // Skipping tail motion simulation and just applying coords computed lately
            // Executed only when using target UpdateRate
            {
                if (InterpolateRate)
                {
                    secPeriodDelta = rateDelta / 24f;
                    deltaForLerps  = secPeriodDelta; // Unify delta value not amplified -> 1f / rate

                    SimulateTailMotionFrame(PostProcessingNeeded());

                    if (_tc_startII > -1)
                    {
                        TailSegment child = TailSegments[_tc_startII];
                        while (child != GhostChild)
                        {
                            TailCalculations_SegmentRotation(child, child.LastKeyframeLocalPosition);
                            TailCalculations_ApplySegmentMotion(child);
                            child = child.ChildBone;
                        }
                    }

                    TailCalculations_SegmentRotation(GhostChild, GhostChild.LastKeyframeLocalPosition);
                    GhostChild.ParentBone.transform.rotation = GhostChild.ParentBone.TrueTargetRotation;
                    GhostChild.ParentBone.RefreshFinalRot(GhostChild.ParentBone.TrueTargetRotation);
                }
                else
                {
                    if (_tc_startI > -1)
                    {
                        TailSegment segment = TailSegments[_tc_startI];

                        while (segment != null)
                        {
                            if (segment.transform)
                            {
                                segment.transform.position = segment.LastFinalPosition;
                                segment.transform.rotation = segment.LastFinalRotation;
                            }
                            else
                            {
                                break;
                            }

                            segment = segment.ChildBone;
                        }
                    }
                    else
                    {
                    }
                }
            }
        }