using System; using System.Collections; using System.Collections.Generic; using System.Linq; using DG.Tweening; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.SceneManagement; using UnityEngine.UI; using Bansonic; public class UI_Panel_Main : Singleton_Mono { public int Character_Index { set { character_Index = value; if(character_Index >= 0 && character_Index < data_List.Count) Set_Character_Illustration(Get_Character_Image_Data(character_Index).ally_hero_HD_image); } get => character_Index; } public int character_Index = 0; [SerializeField] List data_List = new List(); public List Data_List => data_List; [SerializeField] Button button_Character_Set; [SerializeField] GameObject ui_Panel_Character; [SerializeField] Button button_Encyclopendia; [SerializeField] GameObject ui_Panel_Encyclopendia; [SerializeField] Transform notebook_father; [SerializeField] Image image_Character; [SerializeField] Button button_Mail; [SerializeField] GameObject ui_Panel_Mail; [SerializeField] Button button_Notice; [SerializeField] GameObject ui_Panel_Notice; [SerializeField] Button button_Level; [SerializeField] GameObject ui_Panel_Level; [SerializeField] MusicPlayer music_Player; [SerializeField] GameObject ui_Panel_Music; [SerializeField] Button button_Story; [SerializeField] GameObject ui_Panel_Story; [SerializeField] Button button_Setting; [SerializeField] GameObject ui_Panel_Setting; [SerializeField] Button button_worldChat; [SerializeField] GameObject worldChatObject; [SerializeField] float prefab_Enter_Time = 0.35f; [SerializeField] float prefab_Enter_Scale_From = 0.92f; [SerializeField] Ease prefab_Enter_Ease = Ease.OutCubic; [SerializeField] Button button_Idol; [SerializeField] GameObject ui_Panel_Idol; [SerializeField] Button button_Select_Music; [SerializeField] string ui_Select_Music_Scene_Name= "selectYourSongFirst"; [Header("Entry Animation")] [SerializeField] bool play_Enter_OnEnable = true; [SerializeField] float enter_Wait_Timeout = 1.5f; [SerializeField] float enter_UI_Speed = 1.25f; [SerializeField] float enter_Zoom_Time = 0.6f; [SerializeField] float enter_Zoom_Scale_From = 1.2f; [SerializeField] Ease enter_Zoom_Ease = Ease.OutCubic; [SerializeField] float enter_Background_Time = 0.6f; [SerializeField] float enter_Background_Scale_From = 1.12f; [SerializeField] Ease enter_Background_Ease = Ease.OutCubic; [SerializeField] float enter_Bar_Time = 0.45f; [SerializeField] float enter_Item_Time = 0.35f; [SerializeField] float enter_Stagger = 0.06f; [SerializeField] float enter_Offset_X = 140f; [SerializeField] float enter_Offset_Y = 120f; [SerializeField] float enter_Item_Offset_X = 40f; [SerializeField] float enter_Item_Offset_Y = 40f; [SerializeField] Ease enter_Move_Ease = Ease.OutCubic; [Header("Background Decorations Entry")] [SerializeField] bool play_Background_Deco_Enter = true; [SerializeField] float bg_Deco_Time = 0.45f; [SerializeField] float bg_Deco_Stagger = 0.04f; [SerializeField] float bg_Deco_Offset = 60f; [SerializeField] float bg_Deco_Rotate = 6f; [SerializeField] float bg_Deco_Scale_From = 0.9f; [SerializeField] Ease bg_Deco_Ease = Ease.OutCubic; [SerializeField] RectTransform background_Bg2; [Header("Background Loop (Disabled)")] [SerializeField] bool play_Background_Loop = false; [SerializeField] float bg_Loop_Offset = 12f; [SerializeField] float bg_Loop_Time = 6f; [SerializeField] Ease bg_Loop_Ease = Ease.InOutSine; [Header("Mouse Gyro")] [SerializeField] bool play_Mouse_Gyro = true; [SerializeField] bool gyro_Require_Enter_Complete = true; [SerializeField] bool gyro_Use_Unscaled = true; [SerializeField] RectTransform gyro_Target; [SerializeField] RectTransform gyro_Character_Rect; [SerializeField] RectTransform gyro_Dialog_Rect; [SerializeField] float gyro_Max_Offset = 5f; [SerializeField] float gyro_Offset_Scale = 7f; [SerializeField] float gyro_Character_Weight = 1f; [SerializeField] float gyro_Dialog_Weight = 1.35f; [SerializeField] float gyro_Background_Weight = 0.8f; [SerializeField] float gyro_RightButtons_Rotation_Weight = 0.6f; [SerializeField] float gyro_DailyTasks_Rotation_Weight = 0.6f; [SerializeField] float gyro_Max_Rotation = 2f; [SerializeField] float gyro_Rotation_X = 1f; [SerializeField] float gyro_Rotation_Y = 1f; [SerializeField] float gyro_Rotation_Z = 0.35f; [SerializeField] float gyro_Smooth = 8f; [SerializeField] bool gyro_Apply_BG_Scale = false; [SerializeField] float gyro_BG_Extra_Scale = 1.06f; [SerializeField] float gyro_All_Offset_Min = 0.6f; [SerializeField] float gyro_All_Offset_Max = 1.2f; [SerializeField] bool gyro_Only_Leaf = true; [SerializeField] bool gyro_Include_BG_Children = false; [SerializeField] float gyro_BG_Child_Offset_Min = 0.2f; [SerializeField] float gyro_BG_Child_Offset_Max = 0.8f; [SerializeField] float gyro_BG_Child_Rotation_Min = 0.1f; [SerializeField] float gyro_BG_Child_Rotation_Max = 0.5f; [Header("Button Interactions")] [SerializeField] bool play_Button_Interact = true; [SerializeField] float button_Hover_Scale = 1.04f; [SerializeField] float button_Press_Scale = 0.96f; [SerializeField] float button_Hover_Time = 0.08f; [SerializeField] float button_Press_Time = 0.06f; [SerializeField] float button_Release_Time = 0.12f; [SerializeField] Ease button_Hover_Ease = Ease.OutQuad; [SerializeField] Ease button_Press_Ease = Ease.OutQuad; [SerializeField] Ease button_Release_Ease = Ease.OutBack; [Header("Right Buttons Hover")] [SerializeField] bool play_RightButtons_Hover = true; [SerializeField] float rightButton_Image_Idle_Offset = 180f; [SerializeField] float rightButton_Image_Final_Offset = 60f; [SerializeField] float rightButton_Image_Move_Time = 0.18f; [SerializeField] Ease rightButton_Image_Ease = Ease.OutCubic; [SerializeField] float rightButton_Text_Flash_Time = 0.06f; [SerializeField] int rightButton_Text_Flash_Count = 2; [SerializeField] float rightButton_Text_Flash_Interval = 0.02f; [Header("Button Raycast Fix")] [SerializeField] bool fix_Button_Raycast = true; [SerializeField] bool fix_Button_Raycast_Log = false; [Header("Entry References")] [SerializeField] RectTransform content_Root; [SerializeField] RectTransform zoom_MainRoot; [SerializeField] RectTransform zoom_BarsRoot; [SerializeField] RectTransform group_Background; [SerializeField] RectTransform group_Top; [SerializeField] RectTransform group_Bottom; [SerializeField] RectTransform group_Center; [SerializeField] RectTransform group_DailyTasks; [SerializeField] RectTransform group_RightButtons; [SerializeField] RectTransform group_RightButtons_Alt; [SerializeField] RectTransform else_Button; [SerializeField] RectTransform group_StartButton; [SerializeField] RectTransform dailyTask_BG; [SerializeField] RectTransform dailyTask_BG_1; [SerializeField] RectTransform dailyTask_BG_2; [SerializeField] RectTransform top_PlayerName; [SerializeField] RectTransform button_Character_Set_Rect; [SerializeField] RectTransform launch_EzGame_Rect; [SerializeField] UI_CharacterDialogController character_Dialog_Controller; [Header("Jiantou Loop")] [SerializeField] bool play_Jiantou_Loop = true; [SerializeField] bool jiantou_Require_Hover = true; [SerializeField] RectTransform jiantou_Left_Template; [SerializeField] RectTransform jiantou_Right_Template; [SerializeField] string jiantou_Name_Contains = "jiantou"; [SerializeField] int jiantou_Pool_Size = 6; [SerializeField] float jiantou_Move_Amplitude = 120f; [SerializeField] float jiantou_Move_Duration = 8f; [SerializeField] float jiantou_Stagger = 0.35f; [SerializeField] float jiantou_Spacing = 180f; [SerializeField] float jiantou_Hover_Move_Duration = 3f; [SerializeField] float jiantou_Hover_Stagger = 0.15f; [SerializeField] float jiantou_Hover_Spacing = 120f; [SerializeField] float jiantou_Random_Y = 0f; [SerializeField] float jiantou_Alpha_Min = 0.35f; [SerializeField] float jiantou_Alpha_Max = 1f; [SerializeField] int jiantou_Flash_Count = 3; [SerializeField] float jiantou_Flash_Time = 0.06f; [SerializeField] float jiantou_Flash_Interval = 0.04f; class JiantouFlow { public RectTransform template; public RectTransform parent; public float direction; public Vector2 basePos; public float endLimitY; public float speed; public float spacing; public readonly List instances = new(); public readonly List startY = new(); } Sequence enter_Sequence; Sequence bars_Sequence; Coroutine enter_Routine; readonly List bg_Loop_Tweens = new(); readonly List top_Items = new(); readonly List task_Items = new(); readonly List bottom_ButtonItems = new(); readonly List right_ButtonItems = new(); readonly List right_ButtonItems_Alt = new(); readonly List center_Extra_Items = new(); readonly List content_Extra_Items = new(); readonly List bg_Loop_Items = new(); readonly Dictionary cached_Pos = new(); readonly Dictionary cached_Scale = new(); readonly Dictionary cached_RotationZ = new(); bool enter_Debug_Logged; bool enter_Played; Vector2 pos_Top; Vector2 pos_Bottom; Vector2 pos_Daily; Vector2 pos_Start; Vector3 scale_Background; Vector3 scale_MainRoot; Vector3 scale_BarsRoot; float enter_Background_Time_Runtime; float enter_Bar_Time_Runtime; float enter_Item_Time_Runtime; float enter_Stagger_Runtime; float enter_Blink_Time_Scale = 1f; float bg_Deco_Time_Runtime; float bg_Deco_Stagger_Runtime; readonly List gyro_Targets = new(); readonly Dictionary gyro_Base_Pos_Map = new(); readonly Dictionary gyro_Base_Rot_Map = new(); readonly Dictionary gyro_Offset_Weight_Map = new(); readonly Dictionary gyro_Rot_Weight_Map = new(); Vector2 gyro_Current_Offset; Vector3 gyro_Current_RotDelta; Vector3 gyro_BG_Base_Scale; bool gyro_BG_Base_Scale_Set; bool gyro_Inited; readonly List jiantou_Flows = new(); bool jiantou_Inited; int gyro_LastFrame = -1; bool jiantou_Running; bool jiantou_Hovered; Coroutine jiantou_Flash_Routine; readonly List jiantou_Flash_Tweens = new(); readonly List button_Tweeners = new(); bool selectScene_Loading; GameObject encyclopedia_Instance; protected override void In_Init() { Cache_Enter_Refs(); } protected override bool Is_Singleton_Auto() { return true; } protected override void OnDestroy() { Kill_Enter_Tweens(); // data_List contains references to assets in Resources, do not Destroy them. data_List.Clear(); base.OnDestroy(); } private void Start() { StartCoroutine(InitDataRoutine()); } private IEnumerator InitDataRoutine() { var rawData = RuntimeResourcesCache.LoadAllAllyHeroes(); data_List = new List(rawData); data_List.Sort((a, b) => a.ally_heroID.CompareTo(b.ally_heroID)); yield return null; // 璇诲彇淇濆瓨鐨勮鑹?ID 骞跺垵濮嬪寲绱㈠紩 int savedHeroID = PlayerPrefs.GetInt("SelectedMainHeroID", -1); if (savedHeroID != -1) { int foundIndex = data_List.FindIndex(h => h.ally_heroID == savedHeroID); if (foundIndex != -1) { character_Index = foundIndex; } } Character_Index = character_Index; if(Character_Index >= 0 && Character_Index < data_List.Count) Set_Character_Illustration(Get_Character_Image_Data(Character_Index).ally_hero_HD_image); if (button_Character_Set != null) button_Character_Set.onClick.AddListener( () => Try_Open_Panel(ui_Panel_Character)); if (button_Mail != null) button_Mail.onClick.AddListener( () => Try_Open_Panel(ui_Panel_Mail)); if (button_Notice != null) button_Notice.onClick.AddListener( () => Try_Open_Panel(ui_Panel_Notice)); if (button_Level != null) button_Level.onClick.AddListener( () => Try_Open_Panel(ui_Panel_Level)); Character_Index = character_Index; if (button_Encyclopendia != null) button_Encyclopendia.onClick.AddListener( () => { Try_Open_Prefab(ui_Panel_Encyclopendia, ref encyclopedia_Instance); DailyTaskEventHub.ReportWatchStory(); }); if (button_Story != null) button_Story.onClick.AddListener( () => { gNotice.error.display("功能未开放"); //Try_Open_Panel(ui_Panel_Story); }); if (button_Idol != null) button_Idol.onClick.AddListener( () => { Toggle_Panel(ui_Panel_Idol); }); if (music_Player != null && music_Player.Button_List != null) music_Player.Button_List.onClick.AddListener( () => Try_Open_Panel(ui_Panel_Music)); if (button_Setting != null) button_Setting.onClick.AddListener( () => Try_Open_Panel(ui_Panel_Setting)); if (worldChatObject != null) worldChatObject.SetActive(false); if (button_worldChat != null && worldChatObject != null) button_worldChat.onClick.AddListener( () => OpenManagedPanel(worldChatObject)); if (button_Select_Music != null) button_Select_Music.onClick.AddListener( () => Try_Load_Select_Scene()); } bool Try_Open_Panel(GameObject panel) { if (panel == null) { return false; } if (panel.activeInHierarchy) { return false; } if (panel == ui_Panel_Setting) { UI_SettingsPanelEnterAnim enterAnim = panel.GetComponent(); if (enterAnim == null) enterAnim = panel.AddComponent(); enterAnim.enabled = true; } panel.SetActive(true); Ensure_Panel_Popup_If_Needed(panel); RegisterManagedPanel(panel); return true; } void Toggle_Panel(GameObject panel) { if (panel == null) { return; } if (panel.activeSelf) { ClosePanelWithExitAnim(panel); return; } if (panel == ui_Panel_Setting) { UI_SettingsPanelEnterAnim enterAnim = panel.GetComponent(); if (enterAnim == null) enterAnim = panel.AddComponent(); enterAnim.enabled = true; } panel.SetActive(true); Ensure_Panel_Popup_If_Needed(panel); RegisterManagedPanel(panel); } GameObject Try_Open_Prefab(GameObject prefab, ref GameObject instance) { if (prefab == null) return null; if (instance == null) { var parent = notebook_father != null ? notebook_father : (transform.parent != null ? transform.parent : transform); instance = Instantiate(prefab, parent); } AssignPrefabCanvasCamera(instance); if (!instance.activeSelf) instance.SetActive(true); Play_Prefab_Enter(instance); RegisterManagedPanel(instance); return instance; } void OpenManagedPanel(GameObject panel) { if (panel == null) { return; } panel.SetActive(true); Ensure_Panel_Popup_If_Needed(panel); RegisterManagedPanel(panel); } void RegisterManagedPanel(GameObject panel) { if (panel == null) { return; } UIBackStack.RegisterOrBump( panel, () => panel != null && panel.activeInHierarchy, () => { if (panel != null) { ClosePanelWithExitAnim(panel); } return true; }); } void AssignPrefabCanvasCamera(GameObject instance) { if (instance == null) return; var canvases = instance.GetComponentsInChildren(true); if (canvases == null || canvases.Length == 0) return; Camera targetCamera = Camera.main; if (targetCamera == null) { var cams = Camera.allCameras; if (cams != null && cams.Length > 0) targetCamera = cams[0]; } if (targetCamera == null) return; for (int i = 0; i < canvases.Length; i++) { var canvas = canvases[i]; if (canvas == null) continue; canvas.worldCamera = targetCamera; } } void Play_Prefab_Enter(GameObject panel) { if (panel == null) return; var rect = panel.transform as RectTransform; if (rect == null) rect = panel.GetComponent(); if (rect == null) return; rect.DOKill(); var cg = panel.GetComponent(); if (cg == null) cg = panel.AddComponent(); cg.DOKill(); rect.localScale = Vector3.one * prefab_Enter_Scale_From; cg.alpha = 0f; rect.DOScale(Vector3.one, prefab_Enter_Time).SetEase(prefab_Enter_Ease); cg.DOFade(1f, prefab_Enter_Time).SetEase(prefab_Enter_Ease); } void Ensure_Panel_Popup_If_Needed(GameObject panel) { if (panel == null || panel == ui_Panel_Setting) { return; } if (panel.GetComponent() != null) { return; } UI_PanelPopupTween tween = panel.GetComponent(); if (tween == null) { panel.AddComponent(); } } void ClosePanelWithExitAnim(GameObject panel) { if (panel == null) { return; } UI_PanelExitUtility.PlayExitThen(panel, () => { if (panel != null) { panel.SetActive(false); } }); } void Try_Load_Select_Scene() { if (selectScene_Loading) { return; } selectScene_Loading = true; // Documentation text normalized. StartCoroutine(LoadSelectSceneAsync()); } IEnumerator LoadSelectSceneAsync() { if (gTransition.LoadScene(ui_Select_Music_Scene_Name, LoadSceneMode.Single)) { while (gTransition.IsBusy) { yield return null; } yield break; } AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(ui_Select_Music_Scene_Name, LoadSceneMode.Single); // Documentation text normalized. while (asyncLoad != null && !asyncLoad.isDone) { yield return null; } } private void OnEnable() { if (SceneManager.GetActiveScene().name == "UI_UI") { play_Mouse_Gyro = false; Reset_Gyro_To_Base(); } enter_Played = false; gyro_Inited = false; Canvas.willRenderCanvases += OnWillRenderCanvases; Setup_Button_Tweens(); Setup_RightButtons_Hover(); Setup_Jiantou_Hover(); Fix_Button_Raycast(); Ensure_Character_Dialog_Controller(); StartCoroutine(Ensure_Character_Dialog_Controller_Delayed()); if (play_Enter_OnEnable) { Start_Enter_Routine(); } else if (play_Jiantou_Loop) { Start_Jiantou_Loop(); } } IEnumerator Ensure_Character_Dialog_Controller_Delayed() { yield return null; Ensure_Character_Dialog_Controller(); yield return null; Ensure_Character_Dialog_Controller(); } void Ensure_Character_Dialog_Controller() { Scene scene = SceneManager.GetActiveScene(); if (!scene.IsValid() || !string.Equals(scene.name, "UI_UI", StringComparison.OrdinalIgnoreCase)) { return; } if (character_Dialog_Controller != null) { if (!character_Dialog_Controller.enabled) { character_Dialog_Controller.enabled = true; } character_Dialog_Controller.RebindSoon(); return; } GameObject host = null; Transform[] all = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); for (int i = 0; i < all.Length; i++) { Transform t = all[i]; if (t == null || t.gameObject.scene != scene) { continue; } if (string.Equals(t.name, "__UICharacterDialogControllerHost", StringComparison.Ordinal)) { host = t.gameObject; break; } } if (host == null) { host = new GameObject("__UICharacterDialogControllerHost"); try { SceneManager.MoveGameObjectToScene(host, scene); } catch { } } UI_CharacterDialogController controller = host.GetComponent(); if (controller == null) { controller = host.AddComponent(); } if (!controller.enabled) { controller.enabled = true; } controller.RebindSoon(); } void Fix_Button_Raycast() { if (!fix_Button_Raycast) { return; } Cache_Enter_Refs(); Apply_Button_RaycastLimiter(group_DailyTasks); Apply_Button_RaycastLimiter(group_RightButtons); Apply_Button_RaycastLimiter(group_RightButtons_Alt); } void Apply_Button_RaycastLimiter(RectTransform root) { if (root == null) { return; } Button[] buttons = root.GetComponentsInChildren