public Material []materialSequence;
    new public Renderer renderer;

    float playerExitTime = float.NegativeInfinity;
    int state = 0;

    bool PlayerStays = false;

    void Awake()
    {
        renderer = gameObject.GetComponent<MeshRenderer>();
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            // Add a little tolerance, so rapid vibration at the edge of collision
            // doesn't advance the state. We need to leave for some time then return.
            if (Time.time - playerExitTime > 0.1f)
                AdvanceState();
            
        }
    }

    void OnCollisionStay(Collision collision)
    {
        if (PlayerStays)
        {
            StartCoroutine(FallThenDestroy(5f, 9f));
            PlayerStays = false;
        }

        if (state == 1)
        {
            StartCoroutine(PlayerCheckStayStatus(1.5f));
        }
    }

    void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            playerExitTime = Time.time;
        }
    }

    void AdvanceState()
    {
        // If we're already falling, ignore further state changes.
        if (state == materialSequence.Length)
            return;

        renderer.sharedMaterial = materialSequence[state];
        state++;

        if (state == materialSequence.Length)
            StartCoroutine(FallThenDestroy(10f, 3f));
    }

    // This lets us animate out the fall before the destruction takes place.
    IEnumerator FallThenDestroy(float distance, float duration)
    {
        PlayerStays = false;
        yield return new WaitForSeconds(0.5f);
        for (float t = 0; t < duration; t += Time.deltaTime)
        {
            // Fall some distance.
            transform.Translate(0, -distance * Time.deltaTime / duration, 0, Space.World);
            // Yield control to the engine to run for a frame, then resume here.
            yield return null;
        }

        // Destroy ourselves once the fall is over.
        Destroy(gameObject);
    }

    IEnumerator PlayerCheckStayStatus(float time)
    {
        yield return new WaitForSeconds(time);
        PlayerStays = true;
        Debug.Log(PlayerStays);
    }

Edited code like this, it works nice but i need to ask when cube falls, my character teleports to nearest cube around instead of falling with it. How can i fix it?