private void DoTransition(BaseCanvasState state, bool active, bool instant)
    {
        if (!state.canvas)
        {
            return;
        }

        if (instant)
        {
            if (state.canvasGroup)
            {
                state.canvasGroup.alpha = active ? 1 : 0;
            }
            if (state.canvas)
            {
                state.canvas.SetActive(active);
            }
            return;
        }

        if (active)
        {
            state.canvas.transform.SetAsLastSibling();
        }

        if (state.canvasGroup)
        {
            if (active)
            {
                state.canvas.SetActive(true);
            }

            state.canvasGroup.DOKill();

            state.canvasGroup.DOFade(active ? 1 : 0, duration).OnComplete(() =>
            {
                if (!active)
                {
                    state.canvas.SetActive(false);
                }
            });
        }
        else if (state.canvas)
        {
            state.canvas.SetActive(active);
        }
    }
 public virtual void Init(BaseCanvasState state)
 {
     //
 }
 public virtual void Enter(BaseCanvasState state)
 {
     //
 }
    public override void Exit(BaseCanvasState state)
    {
        base.Exit(state);

        DoTransition(state, false, false);
    }
    public override void Enter(BaseCanvasState state)
    {
        base.Enter(state);

        DoTransition(state, true, false);
    }
    public override void Init(BaseCanvasState state)
    {
        base.Init(state);

        DoTransition(state, false, true);
    }