private static void SwapAnimation(object __instance)
        {
            if (swapAnimationInfo == null)
            {
                return;
            }

            RuntimeAnimatorController femaleCtrl = null;
            RuntimeAnimatorController maleCtrl   = null;

            if (!string.IsNullOrEmpty(swapAnimationInfo.PathFemale) || !string.IsNullOrEmpty(swapAnimationInfo.ControllerFemale))
            {
                femaleCtrl = AssetBundleManager.LoadAsset(swapAnimationInfo.PathFemale, swapAnimationInfo.ControllerFemale, typeof(RuntimeAnimatorController)).GetAsset <RuntimeAnimatorController>();
            }
            if (!string.IsNullOrEmpty(swapAnimationInfo.PathMale) || !string.IsNullOrEmpty(swapAnimationInfo.ControllerMale))
            {
                maleCtrl = AssetBundleManager.LoadAsset(swapAnimationInfo.PathMale, swapAnimationInfo.ControllerMale, typeof(RuntimeAnimatorController)).GetAsset <RuntimeAnimatorController>();
            }

            var t_hsp  = Traverse.Create(__instance);
            var female = t_hsp.Field <List <ChaControl> >("lstFemale").Value[0];
            var male   = t_hsp.Field <ChaControl>("male").Value;

            ////TODO: lstFemale[1], male1

            if (femaleCtrl != null)
            {
                female.animBody.runtimeAnimatorController = SetupAnimatorOverrideController(female.animBody.runtimeAnimatorController, femaleCtrl);
            }
            if (maleCtrl != null)
            {
                male.animBody.runtimeAnimatorController = SetupAnimatorOverrideController(male.animBody.runtimeAnimatorController, maleCtrl);
            }

            var mi = t_hsp.Field <List <MotionIK> >("lstMotionIK").Value;

            mi.ForEach(mik => mik.Release());
            mi.Clear();

            //TODO: MotionIKData.
            mi.Add(new MotionIK(female));
            mi.Add(new MotionIK(male));
            mi.ForEach(mik =>
            {
                mik.SetPartners(mi);
                mik.Reset();
            });

            swapAnimationInfo = null;
        }
        private static void LoadMotionList(HSprite __instance, List <HSceneProc.AnimationListInfo> _lstAnimInfo, GameObject _objParent)
        {
            if (_lstAnimInfo == null || _lstAnimInfo.Count == 0)
            {
                return;
            }


            var       buttonParent = _objParent.transform;
            Transform scrollT      = null;

            if (vrType != null || UseGrid.Value)
            {
                DestroyImmediate(_objParent.GetComponent <VerticalLayoutGroup>());
                DestroyImmediate(_objParent.GetComponent <GridLayoutGroup>());
                DestroyImmediate(_objParent.GetComponent <ContentSizeFitter>());
                var glg = _objParent.AddComponent <GridLayoutGroup>();
                glg.cellSize        = new Vector2(200, 35);
                glg.startAxis       = GridLayoutGroup.Axis.Vertical;
                glg.startCorner     = GridLayoutGroup.Corner.UpperRight;
                glg.constraint      = GridLayoutGroup.Constraint.FixedRowCount;
                glg.constraintCount = 15;
                glg.childAlignment  = TextAnchor.UpperRight;
            }
            else
            {
                var buttons = _objParent.transform.Cast <Transform>().ToList();

                var go = DefaultControls.CreateScrollView(new DefaultControls.Resources());
                go.transform.SetParent(_objParent.transform, false);
                var scroll = go.GetComponent <ScrollRect>();
                scroll.horizontal                    = false;
                scroll.scrollSensitivity             = 32f;
                scroll.movementType                  = ScrollRect.MovementType.Clamped;
                scroll.horizontalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHide;
                scroll.verticalScrollbarVisibility   = ScrollRect.ScrollbarVisibility.AutoHide;
                DestroyImmediate(scroll.horizontalScrollbar.gameObject);
                DestroyImmediate(scroll.verticalScrollbar.gameObject);
                DestroyImmediate(scroll.GetComponent <Image>());

                var copyTarget   = GameObject.Find("Canvas").transform.Find("clothesFileWindow/Window/WinRect/ListArea/Scroll View/Scrollbar Vertical").gameObject;
                var newScrollbar = Instantiate(copyTarget, go.transform);
                scroll.verticalScrollbar = newScrollbar.GetComponent <Scrollbar>();
                newScrollbar.transform.SetRect(1f, 0f, 1f, 1f, 0f, 0f, 18f);

                var triggerEvent = new EventTrigger.TriggerEvent();
                triggerEvent.AddListener(x => GlobalMethod.SetCameraMoveFlag(__instance.flags.ctrlCamera, false));
                var eventTrigger = newScrollbar.AddComponent <EventTrigger>();
                eventTrigger.triggers.Add(new EventTrigger.Entry {
                    eventID = EventTriggerType.PointerDown, callback = triggerEvent
                });

                var vlg = _objParent.GetComponent <VerticalLayoutGroup>();
                var csf = _objParent.GetComponent <ContentSizeFitter>();
                vlg.enabled = false;
                csf.enabled = false;
                CopyComponent(vlg, scroll.content.gameObject).enabled = true;
                CopyComponent(csf, scroll.content.gameObject).enabled = true;

                buttons.ForEach(x => x.SetParent(scroll.content));

                buttonParent = scroll.content;
                scrollT      = scroll.gameObject.transform;
            }


            var first = _lstAnimInfo[0];

            if (!animationDict.TryGetValue(first.mode, out var swapAnimations))
            {
                return;
            }

            var animListInfo = lstAnimInfo[(int)first.mode];

            foreach (var anim in swapAnimations.Where(x => (int)x.kindHoushi == first.kindHoushi && (!x.categories.Any() || x.categories.Contains(category))))
            {
                var donorInfo = animListInfo.FirstOrDefault(x => x.id == anim.DonorPoseId).DeepCopy();
                if (donorInfo == null)
                {
                    Logger.LogWarning($"No donor: {anim.Mode} {anim.DonorPoseId}");
                    continue;
                }

                if (anim.NeckDonorId >= 0 && anim.NeckDonorId != anim.DonorPoseId)
                {
                    donorInfo.paramFemale.fileMotionNeck = animListInfo.First(x => x.id == anim.NeckDonorId).paramFemale.fileMotionNeck;
                }
                if (anim.FileMotionNeck != null)
                {
                    donorInfo.paramFemale.fileMotionNeck = anim.FileMotionNeck;
                }
                if (anim.IsFemaleInitiative != null)
                {
                    donorInfo.isFemaleInitiative = anim.IsFemaleInitiative.Value;
                }
                if (anim.FileSiruPaste != null && SiruPasteFiles.TryGetValue(anim.FileSiruPaste.ToLower(), out var fileSiruPaste))
                {
                    donorInfo.paramFemale.fileSiruPaste = fileSiruPaste;
                }
                //if(anim.MotionIKDonor >= 0 && anim.NeckDonorId != anim.DonorPoseId)
                //    donorInfo.paramFemale.path.file = animListInfo.First(x => x.id == anim.MotionIKDonor).paramFemale.path.file;

                var btn = Instantiate(__instance.objMotionListNode, buttonParent, false);
                btn.AddComponent <HSprite.AnimationInfoComponent>().info          = donorInfo;
                btn.transform.FindLoop("Background").GetComponent <Image>().color = buttonColor;

                var label = btn.GetComponentInChildren <TextMeshProUGUI>();
                label.text  = anim.AnimationName;
                label.color = Color.black;

                //TODO: wat
                var tgl = btn.GetComponent <Toggle>();
                tgl.group   = _objParent.GetComponent <ToggleGroup>();
                tgl.enabled = false;
                tgl.enabled = true;

                btn.GetComponent <SceneAssist.PointerAction>().listClickAction.Add(() =>
                {
                    swapAnimationInfo = anim;
                    __instance.OnChangePlaySelect(btn);
                });

                btn.SetActive(true);
                if (__instance.flags.nowAnimationInfo == donorInfo)
                {
                    btn.GetComponent <Toggle>().isOn = true;
                }
            }

            // order all buttons by name
            var allButtons = buttonParent.Cast <Transform>().OrderBy(x => x.GetComponentInChildren <TextMeshProUGUI>().text).ToList();

            foreach (var t in allButtons)
            {
                // disable New text
                var newT = t.FindLoop("New");
                if (newT)
                {
                    newT.gameObject.SetActive(false);
                }

                if (SortPositions.Value)
                {
                    t.SetAsLastSibling();
                }

                var textMeshGo = t.FindLoop("TextMeshPro Text").gameObject;
                var textMesh   = textMeshGo.GetComponent <TextMeshProUGUI>();
                textMesh.enableWordWrapping = false;
                textMesh.overflowMode       = TextOverflowModes.Overflow; // disable ... after text

                // add scrolling text if text is long enough
                var rectT = (RectTransform)t;
                if (rectT.sizeDelta.x < textMesh.preferredWidth)
                {
                    textMesh.alignment = TextAlignmentOptions.CaplineLeft;

                    var txtScroll = textMeshGo.AddComponent <TextScroll>();
                    txtScroll.textMesh  = textMesh;
                    txtScroll.transBase = rectT;
                }
            }

            if (scrollT != null && allButtons.Count > 8)
            {
                scrollT.SetRect(0f, 0f, 1f, 1f, -5f, -100f, -5f, 100f);
            }
        }