/// <summary> /// 替換角色 /// </summary> /// <param name="chaCtrl">目標chara</param> /// <param name="changeFace">是否替換臉部</param> /// <param name="changeBody">是否替換身體</param> public static void ChangeChara(ChaControl chaCtrl, bool changeFace = true, bool changeBody = true, bool disableDoubleChange = true) { if (Hooks.BlockChanging || null == chaCtrl || null == chaCtrl.chaFile) { return; } FBIOpenUp.SetCharaPath(null, null); if (chaCtrl.chaFile.parameter.sex != SampleChara.chaFile.parameter.sex) { Logger.LogWarning($"Skip changes that differ from Sample Chara's gender: {chaCtrl.fileParam.fullname}"); return; } List <float> originalShapeValueFace; List <float> originalShapeValueBody; ChaFileCustom chaFileCustom = chaCtrl.chaFile.custom; originalShapeValueFace = chaFileCustom.face.shapeValueFace.ToList(); originalShapeValueBody = chaFileCustom.body.shapeValueBody.ToList(); //如果角色第一次替換,紀錄其原始數據至dict //如果在dict內有找到替換紀錄,以其原始數據來做替換 //(不block掉是因為,即使在單次Loading Chara內,此function也會被trigger不止一次) if (chaFileCustomDict.TryGetValue(chaFileCustom, out List <float>[] chaFileCustomStored))
/// <summary> /// 建立紅色書包圖標 /// </summary> /// <param name="gameMode">遊戲模式</param> /// <param name="param">我知道這不安全,但這很方便σ`∀´)σ</param> internal static void DrawRedBagBtn(FBIOpenUp.GameMode gameMode, object param = null) { GameObject original, parent; Vector2 offsetMin, offsetMax; FBIOpenUp.nowGameMode = gameMode; switch (FBIOpenUp.nowGameMode) { case FBIOpenUp.GameMode.Studio: CharaList charaList = param as CharaList; original = GameObject.Find($"StudioScene/Canvas Main Menu/01_Add/{charaList.name}/Button Change"); parent = original.transform.parent.gameObject; offsetMin = new Vector2(-120, -270); offsetMax = new Vector2(-40, -190); break; case FBIOpenUp.GameMode.Maker: original = GameObject.Find("CustomScene/CustomRoot/FrontUIGroup/CustomUIGroup/CvsMenuTree/01_BodyTop/tglShape/ShapeTop/Scroll View/Viewport/Content/grpBtn/btnS"); parent = GameObject.Find("CustomScene/CustomRoot/FrontUIGroup/CustomUIGroup/CvsCoordinateType").gameObject; offsetMin = new Vector2(849.64f, -120f); offsetMax = new Vector2(914.64f, -55f); break; case FBIOpenUp.GameMode.MainGame: original = GameObject.Find("ActionScene/UI/ActionMenuCanvas/ModeAnimation/State"); parent = original.transform.parent.gameObject; offsetMin = new Vector2(0, -80); offsetMax = new Vector2(80, 0); break; case FBIOpenUp.GameMode.FreeH: original = GameObject.Find("Canvas/SubMenu/ClothCategory/ClothFemale/DressCategory/ClothChange"); int i = (int)param; if (i == 1) { parent = GameObject.Find("Canvas/SubMenu/ClothCategory"); } else { parent = GameObject.Find("Canvas/SubMenu/SecondDressCategory"); } offsetMin = new Vector2(5, -198); offsetMax = new Vector2(107, -96); break; default: return; } GameObject redBagBtn = UnityEngine.Object.Instantiate(original, parent.transform); redBagBtn.name = "redBagBtn"; redBagBtn.transform.SetRect(new Vector2(0, 1), new Vector2(0, 1), offsetMin, offsetMax); redBagBtn.GetComponent <Button>().spriteState = new SpriteState(); redBagBtn.GetComponent <Image>().sprite = ImageHelper.LoadNewSprite("FBIOpenUp.Resources.redBag.png", 100, 100); redBagBtn.GetComponent <Button>().onClick.RemoveAllListeners(); for (int i = 0; i < redBagBtn.GetComponent <Button>().onClick.GetPersistentEventCount(); i++) { redBagBtn.GetComponent <Button>().onClick.SetPersistentListenerState(i, UnityEngine.Events.UnityEventCallState.Off); } if (redBagBtn.transform.Find("Text (TMP)")?.gameObject is GameObject go) { GameObject.Destroy(go); } if (redBagBtn.transform.Find("textBtn")?.gameObject is GameObject go2) { GameObject.Destroy(go2); } redBagBtn.GetComponent <Button>().interactable = true; //因為要handle長按,監聽PointerDown、PointerUp Event //在Update()裡面有對Timer累加 redBagBtn.AddComponent <EventTrigger>(); EventTrigger trigger = redBagBtn.gameObject.GetComponent <EventTrigger>(); EventTrigger.Entry pointerDown = new EventTrigger.Entry { eventID = EventTriggerType.PointerDown, callback = new EventTrigger.TriggerEvent() }; pointerDown.callback.AddListener((baseEventData) => { btnClickTimer = 0; downState = true; }); trigger.triggers.Add(pointerDown); EventTrigger.Entry pointerUp = new EventTrigger.Entry { eventID = EventTriggerType.PointerUp, callback = new EventTrigger.TriggerEvent() }; pointerUp.callback.AddListener((baseEventData) => { downState = false; float clickDeltaTime = btnClickTimer; btnClickTimer = 0; if (step != 0) { return; } switch (FBIOpenUp.nowGameMode) { case FBIOpenUp.GameMode.FreeH: //不分長短按 FBIOpenUp.SetEnabled(); if (FBIOpenUp._isenabled) { step = 10; } else { if (FBIOpenUp.Effect_on_ABMX.Value) { step = 2; } else { step = 20; } } ChangeWithoutShiftPicture = true; StepLightAndPlay(); //開ABMX時不變更狀態 if (FBIOpenUp.Effect_on_ABMX.Value) { FBIOpenUp.SetEnabled(); } ChangeRedBagBtn(redBagBtn); break; case FBIOpenUp.GameMode.Maker: FBIOpenUp.SetEnabled(); if (FBIOpenUp._isenabled) { DrawSlidePic(10); } else { if (FBIOpenUp.Effect_on_ABMX.Value) { DrawSlidePic(2); } else { DrawSlidePic(20); } } //Maker開ABMX時、啟用長按時不變更狀態 if (FBIOpenUp.Effect_on_ABMX.Value || (clickDeltaTime >= 1f && FBIOpenUp._isenabled)) { FBIOpenUp.SetEnabled(); } ChangeRedBagBtn(redBagBtn); break; case FBIOpenUp.GameMode.MainGame: //主遊戲不分長短按 FBIOpenUp.SetEnabled(); if (FBIOpenUp._isenabled) { DrawSlidePic(10); } else { if (FBIOpenUp.Effect_on_ABMX.Value) { DrawSlidePic(2); } else { DrawSlidePic(20); } } if (FBIOpenUp.Effect_on_ABMX.Value) { FBIOpenUp.SetEnabled(); } ChangeRedBagBtn(redBagBtn); break; case FBIOpenUp.GameMode.Studio: //Studio長按時調整狀態而不變人 FBIOpenUp.SetEnabled(); if (clickDeltaTime <= 1f) { if (FBIOpenUp._isenabled) { DrawSlidePic(10); } else { if (FBIOpenUp.Effect_on_ABMX.Value) { DrawSlidePic(2); } else { DrawSlidePic(20); } } ChangeRedBagBtn(redBagBtn); } else { if (FBIOpenUp._isenabled) { DrawSlidePic(1); } else { DrawSlidePic(2); } ChangeRedBagBtn(redBagBtn); } break; } }); trigger.triggers.Add(pointerUp); ChangeRedBagBtn(redBagBtn); }