Este es mi codigo, quiero entender porque la ultima rotacion de head o tails la hace abruptamente

using UnityEngine;
using System.Collections;

public class CoinFlip : MonoBehaviour
{
    [SerializeField] private Camera mainCamera;
    [SerializeField] private float distanceFromCamera = 2f;
    [SerializeField] private float distanceFromCameraY = -2f;
    [SerializeField] private float tossHeight = 2f;
    [SerializeField] private float flipSpeed = 720f;
    [SerializeField] private float duration = 1.5f;
    [SerializeField] private float bounceHeight = 0.2f; // Altura máxima del rebote
    [SerializeField] private float bounceDuration = 0.3f; // Duración del rebote

    private bool isFlipping = false;
    private Quaternion initialRotation;
    private Quaternion headsRotation;
    private Quaternion tailsRotation;

    void Start()
    {
        initialRotation = transform.rotation;
        
        headsRotation = initialRotation; 
        tailsRotation = Quaternion.Euler(180, 0, 0);

        if (mainCamera == null)
            mainCamera = Camera.main;
    }
    
    public void Update()
    {
        if (Input.GetKeyDown(KeyCode.T))
        {
            StartFlip();
        }
    }

    public void StartFlip()
    {
        if (!isFlipping)
        {
            isFlipping = true;
            StartCoroutine(FlipCoinRoutine());
        }
    }

    private IEnumerator FlipCoinRoutine()
    {
        bool isHeads = Random.Range(0, 2) == 0;

        PositionCoinInFrontOfCamera();

        float elapsed = 0f;
        float verticalSpeed = 4 * tossHeight / duration;

        Quaternion targetRotation = isHeads ? headsRotation : tailsRotation;

        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float progress = elapsed / duration;

            // Movimiento vertical
            float yOffset = verticalSpeed * elapsed * (1 - progress);
            transform.position = mainCamera.transform.position + mainCamera.transform.forward * distanceFromCamera +
                                 mainCamera.transform.up * distanceFromCameraY + Vector3.up * yOffset;

            // Si estamos en la primera parte de la animación, gira la moneda rápidamente
            if (progress <= 0.8f)
            {
                float currentFlipSpeed = Mathf.Lerp(flipSpeed, 0, progress);
                transform.Rotate(Vector3.right, currentFlipSpeed * Time.deltaTime, Space.Self);
            }
            else
            {
                // Última parte de la animación: ajusta la rotación gradualmente hacia el targetRotation
                float angleX = Mathf.LerpAngle(transform.rotation.eulerAngles.x, targetRotation.eulerAngles.x, (progress - 0.8f) / 0.2f);
                transform.rotation = Quaternion.Euler(angleX, transform.rotation.eulerAngles.y, transform.rotation.eulerAngles.z);
            }

            yield return null;
        }

        // Asegura la rotación exacta al final
        transform.rotation = targetRotation;

        // Iniciar el rebote final
        yield return StartCoroutine(BounceRoutine());

        isFlipping = false;
    }



    private IEnumerator BounceRoutine()
    {
        float elapsed = 0f;
        Vector3 startPosition = transform.position;
        Vector3 bouncePeak = startPosition + Vector3.up * bounceHeight;

        while (elapsed < bounceDuration)
        {
            elapsed += Time.deltaTime;
            float progress = elapsed / bounceDuration;

            // Movimiento de rebote utilizando una curva de amortiguación
            float height = Mathf.Lerp(bounceHeight, 0, progress);
            transform.position = startPosition + Vector3.up * height;

            yield return null;
        }

        // Asegura la posición final exacta
        transform.position = startPosition;
    }

    private void PositionCoinInFrontOfCamera()
    {
        transform.position = mainCamera.transform.position + mainCamera.transform.forward * distanceFromCamera;
        transform.rotation = initialRotation;
    }
}