3775 lines
112 KiB
C#
3775 lines
112 KiB
C#
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<UI_Panel_Main>
|
|
{
|
|
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<AllyHero_SO> data_List = new List<AllyHero_SO>();
|
|
public List<AllyHero_SO> 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] 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;
|
|
|
|
[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<RectTransform> instances = new();
|
|
public readonly List<float> startY = new();
|
|
}
|
|
|
|
Sequence enter_Sequence;
|
|
Sequence bars_Sequence;
|
|
Coroutine enter_Routine;
|
|
readonly List<Tween> bg_Loop_Tweens = new();
|
|
readonly List<RectTransform> top_Items = new();
|
|
readonly List<RectTransform> task_Items = new();
|
|
readonly List<RectTransform> bottom_ButtonItems = new();
|
|
readonly List<RectTransform> right_ButtonItems = new();
|
|
readonly List<RectTransform> right_ButtonItems_Alt = new();
|
|
readonly List<RectTransform> center_Extra_Items = new();
|
|
readonly List<RectTransform> content_Extra_Items = new();
|
|
readonly List<RectTransform> bg_Loop_Items = new();
|
|
readonly Dictionary<RectTransform, Vector2> cached_Pos = new();
|
|
readonly Dictionary<RectTransform, Vector3> cached_Scale = new();
|
|
readonly Dictionary<RectTransform, float> 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<RectTransform> gyro_Targets = new();
|
|
readonly Dictionary<RectTransform, Vector2> gyro_Base_Pos_Map = new();
|
|
readonly Dictionary<RectTransform, Vector3> gyro_Base_Rot_Map = new();
|
|
readonly Dictionary<RectTransform, float> gyro_Offset_Weight_Map = new();
|
|
readonly Dictionary<RectTransform, float> 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<JiantouFlow> jiantou_Flows = new();
|
|
bool jiantou_Inited;
|
|
int gyro_LastFrame = -1;
|
|
bool jiantou_Running;
|
|
bool jiantou_Hovered;
|
|
Coroutine jiantou_Flash_Routine;
|
|
readonly List<Tween> jiantou_Flash_Tweens = new();
|
|
readonly List<UI_ButtonTween> 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 = Resources.LoadAll<AllyHero_SO>("so/ally");
|
|
data_List = new List<AllyHero_SO>(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.warning.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 (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<UI_SettingsPanelEnterAnim>();
|
|
if (enterAnim == null)
|
|
enterAnim = panel.AddComponent<UI_SettingsPanelEnterAnim>();
|
|
enterAnim.enabled = true;
|
|
}
|
|
panel.SetActive(true);
|
|
return true;
|
|
}
|
|
|
|
void Toggle_Panel(GameObject panel)
|
|
{
|
|
if (panel == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (panel.activeSelf)
|
|
{
|
|
panel.SetActive(false);
|
|
return;
|
|
}
|
|
|
|
if (panel == ui_Panel_Setting)
|
|
{
|
|
UI_SettingsPanelEnterAnim enterAnim = panel.GetComponent<UI_SettingsPanelEnterAnim>();
|
|
if (enterAnim == null)
|
|
enterAnim = panel.AddComponent<UI_SettingsPanelEnterAnim>();
|
|
enterAnim.enabled = true;
|
|
}
|
|
|
|
panel.SetActive(true);
|
|
}
|
|
|
|
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);
|
|
return instance;
|
|
}
|
|
|
|
void AssignPrefabCanvasCamera(GameObject instance)
|
|
{
|
|
if (instance == null) return;
|
|
var canvases = instance.GetComponentsInChildren<Canvas>(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<RectTransform>();
|
|
if (rect == null) return;
|
|
rect.DOKill();
|
|
var cg = panel.GetComponent<CanvasGroup>();
|
|
if (cg == null) cg = panel.AddComponent<CanvasGroup>();
|
|
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 Try_Load_Select_Scene()
|
|
{
|
|
if (selectScene_Loading)
|
|
{
|
|
return;
|
|
}
|
|
selectScene_Loading = true;
|
|
// Documentation text normalized.
|
|
StartCoroutine(LoadSelectSceneAsync());
|
|
}
|
|
|
|
IEnumerator LoadSelectSceneAsync()
|
|
{
|
|
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(ui_Select_Music_Scene_Name, LoadSceneMode.Single);
|
|
|
|
// Documentation text normalized.
|
|
while (!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;
|
|
}
|
|
|
|
GameObject host = null;
|
|
Transform[] all = UnityEngine.Object.FindObjectsByType<Transform>(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<UI_CharacterDialogController>();
|
|
if (controller == null)
|
|
{
|
|
controller = host.AddComponent<UI_CharacterDialogController>();
|
|
}
|
|
|
|
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<Button>(true);
|
|
for (int i = 0; i < buttons.Length; i++)
|
|
{
|
|
Button button = buttons[i];
|
|
if (button == null)
|
|
{
|
|
continue;
|
|
}
|
|
Graphic target = button.targetGraphic != null ? button.targetGraphic : button.GetComponent<Graphic>();
|
|
if (target == null)
|
|
{
|
|
continue;
|
|
}
|
|
Graphic[] graphics = button.GetComponentsInChildren<Graphic>(true);
|
|
for (int j = 0; j < graphics.Length; j++)
|
|
{
|
|
Graphic g = graphics[j];
|
|
if (g == null)
|
|
{
|
|
continue;
|
|
}
|
|
g.raycastTarget = g == target;
|
|
}
|
|
if (fix_Button_Raycast_Log)
|
|
{
|
|
Debug.Log($"[UI_Panel_Main] Raycast limited for '{button.name}' under '{root.name}'. TargetGraphic='{target.name}'.");
|
|
}
|
|
}
|
|
}
|
|
private void OnDisable()
|
|
{
|
|
if (enter_Routine != null)
|
|
{
|
|
StopCoroutine(enter_Routine);
|
|
enter_Routine = null;
|
|
}
|
|
Kill_Enter_Tweens();
|
|
Reset_Gyro_To_Base();
|
|
Stop_Jiantou_Loop();
|
|
button_Tweeners.Clear();
|
|
Canvas.willRenderCanvases -= OnWillRenderCanvases;
|
|
}
|
|
void Setup_Button_Tweens()
|
|
{
|
|
if (!play_Button_Interact)
|
|
{
|
|
return;
|
|
}
|
|
Cache_Enter_Refs();
|
|
button_Tweeners.Clear();
|
|
Transform root = transform;
|
|
Button[] buttons = root.GetComponentsInChildren<Button>(true);
|
|
for (int i = 0; i < buttons.Length; i++)
|
|
{
|
|
Button button = buttons[i];
|
|
if (button == null)
|
|
{
|
|
continue;
|
|
}
|
|
UI_ButtonTween tweener = button.GetComponent<UI_ButtonTween>();
|
|
if (tweener == null)
|
|
{
|
|
tweener = button.gameObject.AddComponent<UI_ButtonTween>();
|
|
}
|
|
tweener.ApplyConfig(button_Hover_Scale, button_Press_Scale, button_Hover_Time, button_Press_Time,
|
|
button_Release_Time, button_Hover_Ease, button_Press_Ease, button_Release_Ease);
|
|
button_Tweeners.Add(tweener);
|
|
}
|
|
}
|
|
void Setup_Jiantou_Hover()
|
|
{
|
|
if (!play_Jiantou_Loop || !jiantou_Require_Hover)
|
|
{
|
|
return;
|
|
}
|
|
Cache_Enter_Refs();
|
|
RectTransform startRect = group_StartButton;
|
|
if (startRect == null)
|
|
{
|
|
startRect = Find_Rect(transform, "Button_Start", "Start", "START");
|
|
}
|
|
if (startRect == null)
|
|
{
|
|
return;
|
|
}
|
|
Button startButton = startRect.GetComponent<Button>();
|
|
if (startButton == null)
|
|
{
|
|
startButton = startRect.GetComponentInChildren<Button>(true);
|
|
}
|
|
if (startButton == null)
|
|
{
|
|
return;
|
|
}
|
|
UI_JiantouHover hover = startButton.GetComponent<UI_JiantouHover>();
|
|
if (hover == null)
|
|
{
|
|
hover = startButton.gameObject.AddComponent<UI_JiantouHover>();
|
|
}
|
|
hover.Bind(this);
|
|
if (!jiantou_Inited)
|
|
{
|
|
Cache_Jiantou_Templates();
|
|
Build_Jiantou_Pool();
|
|
jiantou_Inited = jiantou_Flows.Count > 0;
|
|
}
|
|
Hide_Jiantou_All();
|
|
}
|
|
void Setup_StartButton_Hover(Button startButton)
|
|
{
|
|
if (startButton == null)
|
|
{
|
|
return;
|
|
}
|
|
UI_StartButtonHover hover = startButton.GetComponent<UI_StartButtonHover>();
|
|
if (hover == null)
|
|
{
|
|
hover = startButton.gameObject.AddComponent<UI_StartButtonHover>();
|
|
}
|
|
hover.ApplyTexts("鎵ц浠诲姟", "Start", "鎰忓織澶嶆紨", "REITERATION OF WILL");
|
|
}
|
|
void Setup_RightButtons_Hover()
|
|
{
|
|
if (!play_RightButtons_Hover)
|
|
{
|
|
return;
|
|
}
|
|
Cache_Enter_Refs();
|
|
if (group_RightButtons == null)
|
|
{
|
|
return;
|
|
}
|
|
Button[] buttons = group_RightButtons.GetComponentsInChildren<Button>(true);
|
|
for (int i = 0; i < buttons.Length; i++)
|
|
{
|
|
Button button = buttons[i];
|
|
if (button == null)
|
|
{
|
|
continue;
|
|
}
|
|
UI_RightButtonHover hover = button.GetComponent<UI_RightButtonHover>();
|
|
if (hover == null)
|
|
{
|
|
hover = button.gameObject.AddComponent<UI_RightButtonHover>();
|
|
}
|
|
hover.ApplyConfig(rightButton_Image_Idle_Offset, rightButton_Image_Final_Offset, rightButton_Image_Move_Time,
|
|
rightButton_Image_Ease, rightButton_Text_Flash_Time, rightButton_Text_Flash_Count, rightButton_Text_Flash_Interval);
|
|
}
|
|
}
|
|
private void LateUpdate()
|
|
{
|
|
if (play_Mouse_Gyro)
|
|
{
|
|
if (!gyro_Require_Enter_Complete || enter_Sequence == null || !enter_Sequence.IsPlaying())
|
|
{
|
|
if (gyro_LastFrame != Time.frameCount)
|
|
{
|
|
Update_Gyro();
|
|
}
|
|
}
|
|
}
|
|
Update_Jiantou_Loop();
|
|
}
|
|
void OnWillRenderCanvases()
|
|
{
|
|
if (!play_Mouse_Gyro)
|
|
{
|
|
return;
|
|
}
|
|
if (gyro_Require_Enter_Complete && enter_Sequence != null && enter_Sequence.IsPlaying())
|
|
{
|
|
return;
|
|
}
|
|
if (gyro_LastFrame == Time.frameCount)
|
|
{
|
|
return;
|
|
}
|
|
Update_Gyro();
|
|
}
|
|
void Update_Gyro()
|
|
{
|
|
gyro_LastFrame = Time.frameCount;
|
|
if (!gyro_Inited)
|
|
{
|
|
Ensure_Gyro_Targets();
|
|
Capture_Gyro_Base();
|
|
}
|
|
if (gyro_Targets.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
float width = Screen.width;
|
|
float height = Screen.height;
|
|
if (width <= 0f || height <= 0f)
|
|
{
|
|
return;
|
|
}
|
|
Vector2 center = new Vector2(width * 0.5f, height * 0.5f);
|
|
Vector2 delta = (Vector2)Input.mousePosition - center;
|
|
Vector2 norm = new Vector2(
|
|
center.x > 0f ? delta.x / center.x : 0f,
|
|
center.y > 0f ? delta.y / center.y : 0f);
|
|
norm = Vector2.ClampMagnitude(norm, 1f);
|
|
|
|
Vector2 targetOffset = new Vector2(norm.x * gyro_Max_Offset, 0f);
|
|
targetOffset *= Mathf.Max(gyro_Offset_Scale, 0f);
|
|
Vector3 targetRotDelta = new Vector3(
|
|
-norm.y * gyro_Max_Rotation * gyro_Rotation_X,
|
|
norm.x * gyro_Max_Rotation * gyro_Rotation_Y,
|
|
norm.x * gyro_Max_Rotation * gyro_Rotation_Z);
|
|
float dt = gyro_Use_Unscaled ? Time.unscaledDeltaTime : Time.deltaTime;
|
|
float t = 1f - Mathf.Exp(-Mathf.Max(gyro_Smooth, 0.01f) * dt);
|
|
gyro_Current_Offset = Vector2.Lerp(gyro_Current_Offset, targetOffset, t);
|
|
gyro_Current_RotDelta = Vector3.Lerp(gyro_Current_RotDelta, targetRotDelta, t);
|
|
|
|
for (int i = 0; i < gyro_Targets.Count; i++)
|
|
{
|
|
RectTransform target = gyro_Targets[i];
|
|
if (target == null || !gyro_Base_Pos_Map.TryGetValue(target, out Vector2 basePos))
|
|
{
|
|
continue;
|
|
}
|
|
float offsetWeight = gyro_Offset_Weight_Map.TryGetValue(target, out float ow) ? ow : 1f;
|
|
float rotWeight = gyro_Rot_Weight_Map.TryGetValue(target, out float rw) ? rw : 1f;
|
|
target.anchoredPosition = basePos + gyro_Current_Offset * offsetWeight;
|
|
if (gyro_Base_Rot_Map.TryGetValue(target, out Vector3 baseRot))
|
|
{
|
|
Vector3 euler = baseRot + gyro_Current_RotDelta * rotWeight;
|
|
target.localEulerAngles = euler;
|
|
}
|
|
}
|
|
}
|
|
public AllyHero_SO Get_Character_Image_Data(int index)
|
|
{
|
|
if(index < 0 || index >= data_List.Count) return null;
|
|
return data_List[index];
|
|
}
|
|
public AllyHero_SO Get_Character_Image_Data()
|
|
{
|
|
if(character_Index < 0 || character_Index >= data_List.Count) return null;
|
|
return data_List[character_Index];
|
|
}
|
|
public void Set_Character_Illustration(Sprite sprite)
|
|
{
|
|
|
|
if (c_Character_Illustration_Anim != null)
|
|
{
|
|
StopCoroutine(c_Character_Illustration_Anim);
|
|
}
|
|
if (image_Character.TryGetComponent(out CanvasGroup canvasGroup))
|
|
{
|
|
c_Character_Illustration_Anim = StartCoroutine(C_Character_Illustration_Anim(canvasGroup, () =>
|
|
{
|
|
image_Character.sprite = sprite;
|
|
// image_Character.SetNativeSize(); // 娉ㄩ噴鎺?SetNativeSize 浠ラ槻鏀瑰彉鐩爣鍥剧墖澶у皬
|
|
}));
|
|
}
|
|
|
|
}
|
|
Coroutine c_Character_Illustration_Anim;
|
|
[SerializeField] float character_Illustration_Time = 0.5f;
|
|
IEnumerator C_Character_Illustration_Anim(CanvasGroup canvasGroup, Action onHide)
|
|
{
|
|
float a = 1f / character_Illustration_Time;
|
|
while (canvasGroup.alpha > 0)
|
|
{
|
|
canvasGroup.alpha -= a * Time.unscaledDeltaTime;
|
|
yield return null;
|
|
}
|
|
onHide?.Invoke();
|
|
while (canvasGroup.alpha < 1)
|
|
{
|
|
canvasGroup.alpha += a * Time.unscaledDeltaTime;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
void Cache_Enter_Refs()
|
|
{
|
|
Ensure_Scene_Ref(ref group_Top);
|
|
Ensure_Scene_Ref(ref group_Bottom);
|
|
Ensure_Scene_Ref(ref group_Background);
|
|
Ensure_Scene_Ref(ref group_Center);
|
|
Ensure_Scene_Ref(ref group_DailyTasks);
|
|
Ensure_Scene_Ref(ref group_RightButtons);
|
|
Ensure_Scene_Ref(ref group_RightButtons_Alt);
|
|
Ensure_Scene_Ref(ref else_Button);
|
|
Ensure_Scene_Ref(ref group_StartButton);
|
|
Ensure_Scene_Ref(ref top_PlayerName);
|
|
Ensure_Scene_Ref(ref zoom_MainRoot);
|
|
Ensure_Scene_Ref(ref zoom_BarsRoot);
|
|
Ensure_Scene_Ref(ref button_Character_Set_Rect);
|
|
Ensure_Scene_Ref(ref launch_EzGame_Rect);
|
|
|
|
if (content_Root == null)
|
|
{
|
|
content_Root = transform.Find("Content") as RectTransform;
|
|
}
|
|
Transform searchRoot = content_Root != null ? content_Root : transform;
|
|
if (zoom_MainRoot == null)
|
|
{
|
|
zoom_MainRoot = content_Root != null ? content_Root : transform as RectTransform;
|
|
}
|
|
if (group_Background == null)
|
|
{
|
|
group_Background = Find_Rect(searchRoot, "BG");
|
|
}
|
|
if (background_Bg2 == null && group_Background != null)
|
|
{
|
|
background_Bg2 = Find_Rect(group_Background, "bg2", "BG2", "BackGround_2", "Background_2", "BackGround2", "Background2");
|
|
if (background_Bg2 == null && group_Background.childCount > 1)
|
|
{
|
|
background_Bg2 = group_Background.GetChild(group_Background.childCount - 1) as RectTransform;
|
|
}
|
|
}
|
|
if (background_Bg2 == null)
|
|
{
|
|
background_Bg2 = Find_Rect(searchRoot, "bg2", "BG2", "BackGround_2", "Background_2", "BackGround2", "Background2");
|
|
}
|
|
if (background_Bg2 == null)
|
|
{
|
|
background_Bg2 = Find_Rect_Global("bg2", "BG2", "BackGround_2", "Background_2", "BackGround2", "Background2");
|
|
}
|
|
if (group_Top == null)
|
|
{
|
|
group_Top = Find_Rect(searchRoot, "TOP", "Top", "TopBar", "Top_Bar");
|
|
}
|
|
if (group_Bottom == null)
|
|
{
|
|
group_Bottom = Find_Rect(searchRoot, "BTM", "Bottom", "BottomBar", "Bottom_Bar");
|
|
}
|
|
if (group_Center == null)
|
|
{
|
|
group_Center = Find_Rect(searchRoot, "CTR", "Center", "Middle");
|
|
}
|
|
if (group_DailyTasks == null)
|
|
{
|
|
group_DailyTasks = Find_Rect(group_Center != null ? group_Center : searchRoot, "UI_DAILY_TASKS", "DailyTasks");
|
|
}
|
|
if (group_DailyTasks != null)
|
|
{
|
|
if (dailyTask_BG == null)
|
|
{
|
|
dailyTask_BG = Find_Rect(group_DailyTasks, "DTask BG", "DTASK BG", "DTask_BG");
|
|
}
|
|
if (dailyTask_BG_1 == null)
|
|
{
|
|
dailyTask_BG_1 = Find_Rect(group_DailyTasks, "DTask BG (1)", "DTASK BG (1)", "DTask_BG (1)");
|
|
}
|
|
if (dailyTask_BG_2 == null)
|
|
{
|
|
dailyTask_BG_2 = Find_Rect(group_DailyTasks, "DTask BG (2)", "DTASK BG (2)", "DTask_BG (2)");
|
|
}
|
|
}
|
|
if (group_RightButtons == null)
|
|
{
|
|
group_RightButtons = Find_Rect(group_Center != null ? group_Center : searchRoot, "R_OTHER_BUTTON_G", "RightButtons", "Right_Button_G");
|
|
}
|
|
if (group_RightButtons_Alt == null)
|
|
{
|
|
group_RightButtons_Alt = Find_Rect(group_Center != null ? group_Center : searchRoot, "R_OTHER_BUTTON_G2", "RightButtons2", "Right_Button_G2");
|
|
}
|
|
if (else_Button == null)
|
|
{
|
|
else_Button = Find_Rect(group_Center != null ? group_Center : searchRoot, "else_button", "Else_Button", "ELSE_BUTTON");
|
|
}
|
|
if (group_StartButton == null)
|
|
{
|
|
group_StartButton = Find_Rect(searchRoot, "Button_Start", "Start", "START");
|
|
}
|
|
if (top_PlayerName == null && group_Top != null)
|
|
{
|
|
top_PlayerName = Find_Rect(group_Top, "UI_PLAYER", "Player", "PlayerName");
|
|
}
|
|
if (button_Character_Set_Rect == null)
|
|
{
|
|
if (button_Character_Set != null && Is_Scene_Object(button_Character_Set))
|
|
{
|
|
button_Character_Set_Rect = button_Character_Set.transform as RectTransform;
|
|
}
|
|
}
|
|
if (button_Character_Set_Rect == null)
|
|
{
|
|
button_Character_Set_Rect = Find_Rect(group_Center != null ? group_Center : searchRoot, "Button_CHARACTER_SET", "CHARACTER_SET", "Character_Set");
|
|
}
|
|
if (button_Character_Set_Rect == null)
|
|
{
|
|
button_Character_Set_Rect = Find_Rect_Global("Button_CHARACTER_SET", "CHARACTER_SET", "Character_Set");
|
|
}
|
|
if (launch_EzGame_Rect == null)
|
|
{
|
|
launch_EzGame_Rect = Find_Rect(searchRoot, "launchEzGame", "LaunchEzGame", "launch_ezgame");
|
|
}
|
|
if (launch_EzGame_Rect == null)
|
|
{
|
|
launch_EzGame_Rect = Find_Rect_Global("launchEzGame", "LaunchEzGame", "launch_ezgame");
|
|
}
|
|
if (gyro_Character_Rect == null && image_Character != null && Is_Scene_Object(image_Character))
|
|
{
|
|
gyro_Character_Rect = image_Character.transform as RectTransform;
|
|
}
|
|
if (gyro_Dialog_Rect == null)
|
|
{
|
|
gyro_Dialog_Rect = Find_Rect(searchRoot, "UI_DIALOG", "Dialog", "UI_Dialog");
|
|
}
|
|
if (group_DailyTasks == null)
|
|
{
|
|
group_DailyTasks = Find_Rect_Global("UI_DAILY_TASKS", "DailyTasks");
|
|
}
|
|
if (dailyTask_BG == null)
|
|
{
|
|
dailyTask_BG = Find_Rect_Global("DTask BG", "DTASK BG", "DTask_BG");
|
|
}
|
|
if (dailyTask_BG_1 == null)
|
|
{
|
|
dailyTask_BG_1 = Find_Rect_Global("DTask BG (1)", "DTASK BG (1)", "DTask_BG (1)");
|
|
}
|
|
if (dailyTask_BG_2 == null)
|
|
{
|
|
dailyTask_BG_2 = Find_Rect_Global("DTask BG (2)", "DTASK BG (2)", "DTask_BG (2)");
|
|
}
|
|
if (group_DailyTasks != null && group_Center == null)
|
|
{
|
|
group_Center = group_DailyTasks.parent as RectTransform;
|
|
}
|
|
if (group_RightButtons == null)
|
|
{
|
|
group_RightButtons = Find_Rect_Global("R_OTHER_BUTTON_G", "RightButtons", "Right_Button_G");
|
|
}
|
|
if (group_RightButtons_Alt == null)
|
|
{
|
|
group_RightButtons_Alt = Find_Rect_Global("R_OTHER_BUTTON_G2", "RightButtons2", "Right_Button_G2");
|
|
}
|
|
if (else_Button == null)
|
|
{
|
|
else_Button = Find_Rect_Global("else_button", "Else_Button", "ELSE_BUTTON");
|
|
}
|
|
if (content_Root == null && group_Center != null)
|
|
{
|
|
content_Root = group_Center.parent as RectTransform;
|
|
searchRoot = content_Root != null ? content_Root : searchRoot;
|
|
}
|
|
if (group_Top == null)
|
|
{
|
|
group_Top = Find_Rect(searchRoot, "TOP", "Top", "TopBar", "Top_Bar");
|
|
}
|
|
if (group_Bottom == null)
|
|
{
|
|
group_Bottom = Find_Rect(searchRoot, "BTM", "Bottom", "BottomBar", "Bottom_Bar", "bottom", "bbotom");
|
|
}
|
|
if (group_Top == null)
|
|
{
|
|
group_Top = Find_Rect_Global("TOP", "Top", "TopBar", "Top_Bar");
|
|
}
|
|
if (group_Bottom == null)
|
|
{
|
|
group_Bottom = Find_Rect_Global("BTM", "Bottom", "BottomBar", "Bottom_Bar", "bottom", "bbotom");
|
|
}
|
|
if (zoom_BarsRoot == null)
|
|
{
|
|
RectTransform topParent = group_Top != null ? group_Top.parent as RectTransform : null;
|
|
RectTransform bottomParent = group_Bottom != null ? group_Bottom.parent as RectTransform : null;
|
|
if (topParent != null && topParent == bottomParent)
|
|
{
|
|
zoom_BarsRoot = topParent;
|
|
}
|
|
else if (topParent != null)
|
|
{
|
|
zoom_BarsRoot = topParent;
|
|
}
|
|
else if (bottomParent != null)
|
|
{
|
|
zoom_BarsRoot = bottomParent;
|
|
}
|
|
}
|
|
if (content_Root != null)
|
|
{
|
|
if (group_Top == null)
|
|
{
|
|
group_Top = Find_Bar_By_Position(content_Root, true);
|
|
}
|
|
if (group_Bottom == null)
|
|
{
|
|
group_Bottom = Find_Bar_By_Position(content_Root, false);
|
|
}
|
|
}
|
|
if (group_Top != null && content_Root == null)
|
|
{
|
|
content_Root = group_Top.parent as RectTransform;
|
|
}
|
|
if (group_Bottom != null && content_Root == null)
|
|
{
|
|
content_Root = group_Bottom.parent as RectTransform;
|
|
}
|
|
if (group_Top == null || group_Bottom == null)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
void Cache_Enter_Defaults()
|
|
{
|
|
Prune_Cached_Pos();
|
|
top_Items.Clear();
|
|
task_Items.Clear();
|
|
bottom_ButtonItems.Clear();
|
|
right_ButtonItems.Clear();
|
|
right_ButtonItems_Alt.Clear();
|
|
center_Extra_Items.Clear();
|
|
content_Extra_Items.Clear();
|
|
bg_Loop_Items.Clear();
|
|
|
|
if (zoom_MainRoot != null)
|
|
{
|
|
scale_MainRoot = zoom_MainRoot.localScale;
|
|
}
|
|
if (zoom_BarsRoot != null)
|
|
{
|
|
scale_BarsRoot = zoom_BarsRoot.localScale;
|
|
}
|
|
if (group_Background != null)
|
|
{
|
|
scale_Background = group_Background.localScale;
|
|
}
|
|
if (group_Top != null)
|
|
{
|
|
Cache_Pos(group_Top);
|
|
pos_Top = cached_Pos[group_Top];
|
|
}
|
|
if (group_Bottom != null)
|
|
{
|
|
Cache_Pos(group_Bottom);
|
|
pos_Bottom = cached_Pos[group_Bottom];
|
|
}
|
|
if (group_DailyTasks != null)
|
|
{
|
|
Cache_Pos(group_DailyTasks);
|
|
pos_Daily = cached_Pos[group_DailyTasks];
|
|
}
|
|
if (group_StartButton != null)
|
|
{
|
|
Cache_Pos(group_StartButton);
|
|
pos_Start = cached_Pos[group_StartButton];
|
|
}
|
|
if (button_Character_Set_Rect != null)
|
|
{
|
|
Cache_Pos(button_Character_Set_Rect);
|
|
}
|
|
if (launch_EzGame_Rect != null)
|
|
{
|
|
Cache_Pos(launch_EzGame_Rect);
|
|
}
|
|
|
|
if (group_Top != null)
|
|
{
|
|
foreach (Transform child in group_Top)
|
|
{
|
|
RectTransform rect = child as RectTransform;
|
|
if (rect == null || rect == top_PlayerName)
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Background_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Jiantou_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
top_Items.Add(rect);
|
|
}
|
|
top_Items.Sort(Compare_By_X);
|
|
foreach (var item in top_Items)
|
|
{
|
|
Cache_Pos(item);
|
|
}
|
|
}
|
|
|
|
if (group_DailyTasks != null)
|
|
{
|
|
foreach (Transform child in group_DailyTasks)
|
|
{
|
|
RectTransform rect = child as RectTransform;
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Background_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Jiantou_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
task_Items.Add(rect);
|
|
}
|
|
task_Items.Sort(Compare_By_X);
|
|
foreach (var item in task_Items)
|
|
{
|
|
Cache_Pos(item);
|
|
}
|
|
}
|
|
|
|
if (group_Bottom != null || group_StartButton != null)
|
|
{
|
|
HashSet<RectTransform> bottomSet = new();
|
|
if (group_Bottom != null)
|
|
{
|
|
foreach (var button in group_Bottom.GetComponentsInChildren<Button>(true))
|
|
{
|
|
if (button == null) continue;
|
|
bottomSet.Add(button.transform as RectTransform);
|
|
}
|
|
}
|
|
if (group_StartButton != null && group_StartButton.GetComponent<Button>() != null)
|
|
{
|
|
bottomSet.Add(group_StartButton);
|
|
}
|
|
foreach (var item in bottomSet)
|
|
{
|
|
if (item != null)
|
|
{
|
|
bottom_ButtonItems.Add(item);
|
|
}
|
|
}
|
|
bottom_ButtonItems.Sort(Compare_By_X);
|
|
foreach (var item in bottom_ButtonItems)
|
|
{
|
|
Cache_Pos(item);
|
|
}
|
|
}
|
|
|
|
if (group_RightButtons != null)
|
|
{
|
|
HashSet<RectTransform> rightSet = new();
|
|
foreach (var button in group_RightButtons.GetComponentsInChildren<Button>(true))
|
|
{
|
|
if (button == null) continue;
|
|
rightSet.Add(button.transform as RectTransform);
|
|
}
|
|
foreach (var item in rightSet)
|
|
{
|
|
if (item != null)
|
|
{
|
|
right_ButtonItems.Add(item);
|
|
}
|
|
}
|
|
right_ButtonItems.Sort(Compare_By_Y_Desc);
|
|
foreach (var item in right_ButtonItems)
|
|
{
|
|
Cache_Pos(item);
|
|
}
|
|
}
|
|
|
|
if (group_RightButtons_Alt != null)
|
|
{
|
|
HashSet<RectTransform> altSet = new();
|
|
foreach (Transform child in group_RightButtons_Alt)
|
|
{
|
|
RectTransform rect = child as RectTransform;
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
altSet.Add(rect);
|
|
}
|
|
foreach (var item in altSet)
|
|
{
|
|
if (item != null)
|
|
{
|
|
right_ButtonItems_Alt.Add(item);
|
|
}
|
|
}
|
|
right_ButtonItems_Alt.Sort(Compare_By_Y_Desc);
|
|
foreach (var item in right_ButtonItems_Alt)
|
|
{
|
|
Cache_Pos(item);
|
|
}
|
|
}
|
|
|
|
if (group_Center != null)
|
|
{
|
|
foreach (Transform child in group_Center)
|
|
{
|
|
RectTransform rect = child as RectTransform;
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (rect == group_DailyTasks || rect == group_RightButtons || rect == group_RightButtons_Alt || rect == group_StartButton)
|
|
{
|
|
continue;
|
|
}
|
|
if (rect == button_Character_Set_Rect || rect == launch_EzGame_Rect)
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Background_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Jiantou_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
center_Extra_Items.Add(rect);
|
|
}
|
|
center_Extra_Items.Sort(Compare_By_X);
|
|
foreach (var item in center_Extra_Items)
|
|
{
|
|
Cache_Pos(item);
|
|
}
|
|
}
|
|
|
|
if (content_Root != null)
|
|
{
|
|
foreach (Transform child in content_Root)
|
|
{
|
|
RectTransform rect = child as RectTransform;
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (rect == group_Background || rect == group_Top || rect == group_Bottom || rect == group_Center || rect == group_StartButton)
|
|
{
|
|
continue;
|
|
}
|
|
if (rect == button_Character_Set_Rect || rect == launch_EzGame_Rect)
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Background_Name(rect.name) || Is_Jiantou_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_BG2(rect))
|
|
{
|
|
continue;
|
|
}
|
|
if (Has_Jiantou_Descendant(rect))
|
|
{
|
|
continue;
|
|
}
|
|
if (group_Top != null && group_Top.IsChildOf(rect))
|
|
{
|
|
continue;
|
|
}
|
|
if (group_Bottom != null && group_Bottom.IsChildOf(rect))
|
|
{
|
|
continue;
|
|
}
|
|
content_Extra_Items.Add(rect);
|
|
}
|
|
content_Extra_Items.Sort(Compare_By_X);
|
|
foreach (var item in content_Extra_Items)
|
|
{
|
|
Cache_Pos(item);
|
|
}
|
|
}
|
|
|
|
if (group_Background != null)
|
|
{
|
|
foreach (Transform child in group_Background)
|
|
{
|
|
RectTransform rect = child as RectTransform;
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Jiantou_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
bg_Loop_Items.Add(rect);
|
|
Cache_Pos(rect);
|
|
Cache_Scale(rect);
|
|
Cache_Rotation(rect);
|
|
}
|
|
}
|
|
if (background_Bg2 != null && !bg_Loop_Items.Contains(background_Bg2))
|
|
{
|
|
bg_Loop_Items.Add(background_Bg2);
|
|
Cache_Pos(background_Bg2);
|
|
Cache_Scale(background_Bg2);
|
|
Cache_Rotation(background_Bg2);
|
|
}
|
|
|
|
Cache_Pos(group_Top);
|
|
Cache_Pos(group_Bottom);
|
|
Cache_Pos(group_DailyTasks);
|
|
Cache_Pos(group_StartButton);
|
|
Cache_Pos(button_Character_Set_Rect);
|
|
Cache_Pos(launch_EzGame_Rect);
|
|
}
|
|
void Kill_Enter_Tweens()
|
|
{
|
|
if (enter_Sequence != null)
|
|
{
|
|
enter_Sequence.Kill();
|
|
enter_Sequence = null;
|
|
}
|
|
Kill_Bars_Tweens();
|
|
Stop_Background_Loop();
|
|
Kill_Target(zoom_MainRoot);
|
|
Kill_Target(zoom_BarsRoot);
|
|
Kill_Target(group_Background);
|
|
Kill_Target(group_Top);
|
|
Kill_Target(group_Bottom);
|
|
Kill_Target(group_DailyTasks);
|
|
Kill_Target(group_RightButtons);
|
|
Kill_Target(group_RightButtons_Alt);
|
|
Kill_Target(group_StartButton);
|
|
Kill_Target(top_PlayerName);
|
|
Kill_Target(button_Character_Set_Rect);
|
|
Kill_Target(launch_EzGame_Rect);
|
|
for (int i = 0; i < top_Items.Count; i++)
|
|
{
|
|
Kill_Target(top_Items[i]);
|
|
}
|
|
for (int i = 0; i < task_Items.Count; i++)
|
|
{
|
|
Kill_Target(task_Items[i]);
|
|
}
|
|
for (int i = 0; i < bottom_ButtonItems.Count; i++)
|
|
{
|
|
Kill_Target(bottom_ButtonItems[i]);
|
|
}
|
|
for (int i = 0; i < right_ButtonItems.Count; i++)
|
|
{
|
|
Kill_Target(right_ButtonItems[i]);
|
|
}
|
|
for (int i = 0; i < right_ButtonItems_Alt.Count; i++)
|
|
{
|
|
Kill_Target(right_ButtonItems_Alt[i]);
|
|
}
|
|
for (int i = 0; i < center_Extra_Items.Count; i++)
|
|
{
|
|
Kill_Target(center_Extra_Items[i]);
|
|
}
|
|
for (int i = 0; i < content_Extra_Items.Count; i++)
|
|
{
|
|
Kill_Target(content_Extra_Items[i]);
|
|
}
|
|
for (int i = 0; i < bg_Loop_Items.Count; i++)
|
|
{
|
|
Kill_Target(bg_Loop_Items[i]);
|
|
}
|
|
}
|
|
void Kill_Bars_Tweens()
|
|
{
|
|
if (bars_Sequence != null)
|
|
{
|
|
bars_Sequence.Kill();
|
|
bars_Sequence = null;
|
|
}
|
|
Kill_Target(group_Top);
|
|
Kill_Target(group_Bottom);
|
|
for (int i = 0; i < top_Items.Count; i++)
|
|
{
|
|
Kill_Target(top_Items[i]);
|
|
}
|
|
}
|
|
public void Play_Enter_Anim()
|
|
{
|
|
enter_Played = true;
|
|
Cache_Enter_Refs();
|
|
Kill_Enter_Tweens();
|
|
Cache_Enter_Defaults();
|
|
Update_Enter_Runtime_Times();
|
|
|
|
transform.localScale = Vector3.one;
|
|
bool applyBarsZoom = zoom_BarsRoot != null
|
|
&& zoom_BarsRoot != zoom_MainRoot
|
|
&& (zoom_MainRoot == null || !zoom_BarsRoot.IsChildOf(zoom_MainRoot));
|
|
if (zoom_MainRoot != null)
|
|
{
|
|
zoom_MainRoot.localScale = scale_MainRoot * enter_Zoom_Scale_From;
|
|
}
|
|
if (applyBarsZoom)
|
|
{
|
|
zoom_BarsRoot.localScale = scale_BarsRoot * enter_Zoom_Scale_From;
|
|
}
|
|
|
|
if (group_Background != null)
|
|
{
|
|
group_Background.localScale = scale_Background * enter_Background_Scale_From;
|
|
}
|
|
for (int i = 0; i < bg_Loop_Items.Count; i++)
|
|
{
|
|
RectTransform rect = bg_Loop_Items[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (cached_Pos.TryGetValue(rect, out Vector2 pos))
|
|
{
|
|
rect.anchoredPosition = pos;
|
|
}
|
|
if (cached_Scale.TryGetValue(rect, out Vector3 scale))
|
|
{
|
|
rect.localScale = scale;
|
|
}
|
|
if (cached_RotationZ.TryGetValue(rect, out float rotZ))
|
|
{
|
|
Vector3 euler = rect.localEulerAngles;
|
|
euler.z = rotZ;
|
|
rect.localEulerAngles = euler;
|
|
}
|
|
}
|
|
if (group_Top != null)
|
|
{
|
|
group_Top.anchoredPosition = pos_Top + Vector2.up * enter_Offset_Y;
|
|
}
|
|
if (group_Bottom != null)
|
|
{
|
|
group_Bottom.anchoredPosition = pos_Bottom - Vector2.up * enter_Offset_Y;
|
|
}
|
|
if (group_DailyTasks != null)
|
|
{
|
|
group_DailyTasks.anchoredPosition = pos_Daily + Vector2.left * enter_Offset_X;
|
|
}
|
|
if (group_StartButton != null)
|
|
{
|
|
group_StartButton.anchoredPosition = pos_Start;
|
|
}
|
|
|
|
for (int i = 0; i < top_Items.Count; i++)
|
|
{
|
|
Prepare_Item(top_Items[i], Vector2.down * enter_Item_Offset_Y, true);
|
|
}
|
|
for (int i = 0; i < task_Items.Count; i++)
|
|
{
|
|
Prepare_Item(task_Items[i], Vector2.left * enter_Item_Offset_X, true);
|
|
}
|
|
for (int i = 0; i < bottom_ButtonItems.Count; i++)
|
|
{
|
|
Prepare_Item(bottom_ButtonItems[i], Vector2.down * enter_Item_Offset_Y, true);
|
|
}
|
|
for (int i = 0; i < right_ButtonItems.Count; i++)
|
|
{
|
|
Prepare_Item(right_ButtonItems[i], Vector2.right * enter_Offset_X, true);
|
|
}
|
|
for (int i = 0; i < right_ButtonItems_Alt.Count; i++)
|
|
{
|
|
Prepare_FadeOnly(right_ButtonItems_Alt[i]);
|
|
}
|
|
if (group_RightButtons_Alt != null)
|
|
{
|
|
Prepare_FadeOnly(group_RightButtons_Alt);
|
|
}
|
|
for (int i = 0; i < center_Extra_Items.Count; i++)
|
|
{
|
|
Prepare_Item(center_Extra_Items[i], Vector2.down * enter_Item_Offset_Y, true);
|
|
}
|
|
for (int i = 0; i < content_Extra_Items.Count; i++)
|
|
{
|
|
Prepare_Item(content_Extra_Items[i], Vector2.down * enter_Item_Offset_Y, true);
|
|
}
|
|
if (button_Character_Set_Rect != null
|
|
&& !top_Items.Contains(button_Character_Set_Rect)
|
|
&& !task_Items.Contains(button_Character_Set_Rect)
|
|
&& !bottom_ButtonItems.Contains(button_Character_Set_Rect)
|
|
&& !right_ButtonItems.Contains(button_Character_Set_Rect))
|
|
{
|
|
Prepare_Item(button_Character_Set_Rect, Vector2.down * enter_Item_Offset_Y, true);
|
|
}
|
|
if (launch_EzGame_Rect != null
|
|
&& !top_Items.Contains(launch_EzGame_Rect)
|
|
&& !task_Items.Contains(launch_EzGame_Rect)
|
|
&& !bottom_ButtonItems.Contains(launch_EzGame_Rect)
|
|
&& !right_ButtonItems.Contains(launch_EzGame_Rect))
|
|
{
|
|
Prepare_Item(launch_EzGame_Rect, Vector2.right * enter_Offset_X, true);
|
|
}
|
|
if (top_PlayerName != null)
|
|
{
|
|
CanvasGroup playerGroup = Ensure_CanvasGroup(top_PlayerName.gameObject);
|
|
playerGroup.alpha = 0f;
|
|
}
|
|
if (play_Background_Deco_Enter)
|
|
{
|
|
for (int i = 0; i < bg_Loop_Items.Count; i++)
|
|
{
|
|
Prepare_Background_Deco(bg_Loop_Items[i], i);
|
|
}
|
|
}
|
|
|
|
enter_Sequence = DOTween.Sequence();
|
|
enter_Sequence.SetUpdate(true);
|
|
enter_Sequence.SetAutoKill(false);
|
|
enter_Sequence.OnKill(() => enter_Sequence = null);
|
|
if (zoom_MainRoot != null)
|
|
{
|
|
enter_Sequence.Insert(0f, zoom_MainRoot.DOScale(scale_MainRoot, enter_Zoom_Time).SetEase(enter_Zoom_Ease));
|
|
}
|
|
if (applyBarsZoom)
|
|
{
|
|
enter_Sequence.Insert(0f, zoom_BarsRoot.DOScale(scale_BarsRoot, enter_Zoom_Time).SetEase(enter_Zoom_Ease));
|
|
}
|
|
|
|
if (group_Background != null)
|
|
{
|
|
enter_Sequence.Append(group_Background.DOScale(scale_Background, enter_Background_Time_Runtime)
|
|
.SetEase(enter_Background_Ease));
|
|
}
|
|
if (play_Background_Deco_Enter)
|
|
{
|
|
float decoStart = 0f;
|
|
for (int i = 0; i < bg_Loop_Items.Count; i++)
|
|
{
|
|
RectTransform rect = bg_Loop_Items[i];
|
|
float at = decoStart + (bg_Deco_Stagger_Runtime * i);
|
|
Animate_Background_Deco(enter_Sequence, rect, at);
|
|
}
|
|
}
|
|
|
|
if (play_Background_Loop || play_Mouse_Gyro || play_Jiantou_Loop)
|
|
{
|
|
enter_Sequence.OnComplete(() =>
|
|
{
|
|
if (play_Background_Loop)
|
|
{
|
|
Start_Background_Loop();
|
|
}
|
|
if (play_Mouse_Gyro)
|
|
{
|
|
Capture_Gyro_Base();
|
|
}
|
|
if (play_Jiantou_Loop)
|
|
{
|
|
Start_Jiantou_Loop();
|
|
}
|
|
});
|
|
}
|
|
|
|
float uiStart = enter_Sequence.Duration();
|
|
|
|
if (group_Top != null)
|
|
{
|
|
enter_Sequence.Insert(uiStart, group_Top.DOAnchorPos(pos_Top, enter_Bar_Time_Runtime).SetEase(enter_Move_Ease));
|
|
}
|
|
if (group_Bottom != null)
|
|
{
|
|
enter_Sequence.Insert(uiStart, group_Bottom.DOAnchorPos(pos_Bottom, enter_Bar_Time_Runtime).SetEase(enter_Move_Ease));
|
|
}
|
|
if (group_DailyTasks != null)
|
|
{
|
|
enter_Sequence.Insert(uiStart, group_DailyTasks.DOAnchorPos(pos_Daily, enter_Bar_Time_Runtime).SetEase(enter_Move_Ease));
|
|
}
|
|
|
|
float topItemsStart = uiStart + enter_Bar_Time_Runtime * 0.6f;
|
|
for (int i = 0; i < top_Items.Count; i++)
|
|
{
|
|
RectTransform item = top_Items[i];
|
|
float at = topItemsStart + (enter_Stagger_Runtime * i);
|
|
Animate_Item(enter_Sequence, item, at);
|
|
}
|
|
|
|
if (top_PlayerName != null)
|
|
{
|
|
CanvasGroup playerGroup = Ensure_CanvasGroup(top_PlayerName.gameObject);
|
|
Sequence blink = DOTween.Sequence().SetUpdate(true);
|
|
blink.Append(playerGroup.DOFade(1f, 0.15f * enter_Blink_Time_Scale));
|
|
blink.AppendInterval(0.05f * enter_Blink_Time_Scale);
|
|
blink.Append(playerGroup.DOFade(0.2f, 0.1f * enter_Blink_Time_Scale));
|
|
blink.Append(playerGroup.DOFade(1f, 0.2f * enter_Blink_Time_Scale));
|
|
enter_Sequence.Insert(topItemsStart + enter_Stagger_Runtime * 0.5f, blink);
|
|
}
|
|
if (button_Character_Set_Rect != null)
|
|
{
|
|
float characterStart = topItemsStart + enter_Stagger_Runtime * (top_Items.Count + 0.5f);
|
|
Animate_Item(enter_Sequence, button_Character_Set_Rect, characterStart);
|
|
}
|
|
|
|
float tasksItemsStart = uiStart + enter_Bar_Time_Runtime * 0.7f;
|
|
for (int i = 0; i < task_Items.Count; i++)
|
|
{
|
|
RectTransform item = task_Items[i];
|
|
float at = tasksItemsStart + (enter_Stagger_Runtime * i);
|
|
Animate_Item(enter_Sequence, item, at);
|
|
}
|
|
|
|
float bottomItemsStart = uiStart + enter_Bar_Time_Runtime * 0.7f;
|
|
for (int i = 0; i < bottom_ButtonItems.Count; i++)
|
|
{
|
|
RectTransform item = bottom_ButtonItems[i];
|
|
float at = bottomItemsStart + (enter_Stagger_Runtime * i);
|
|
Animate_Item(enter_Sequence, item, at);
|
|
}
|
|
|
|
float rightStart = uiStart + 0.05f;
|
|
for (int i = 0; i < right_ButtonItems.Count; i++)
|
|
{
|
|
RectTransform item = right_ButtonItems[i];
|
|
float at = rightStart + (enter_Stagger_Runtime * i);
|
|
Animate_Item(enter_Sequence, item, at);
|
|
}
|
|
float altStart = uiStart + 0.05f;
|
|
for (int i = 0; i < right_ButtonItems_Alt.Count; i++)
|
|
{
|
|
RectTransform item = right_ButtonItems_Alt[i];
|
|
float at = altStart + (enter_Stagger_Runtime * i);
|
|
Animate_Flicker(enter_Sequence, item, at, 3, 0.045f, 0.02f);
|
|
}
|
|
if (group_RightButtons_Alt != null)
|
|
{
|
|
Animate_Flicker(enter_Sequence, group_RightButtons_Alt, altStart, 3, 0.045f, 0.02f);
|
|
}
|
|
float centerExtraStart = uiStart + enter_Bar_Time_Runtime * 0.5f;
|
|
for (int i = 0; i < center_Extra_Items.Count; i++)
|
|
{
|
|
RectTransform item = center_Extra_Items[i];
|
|
float at = centerExtraStart + (enter_Stagger_Runtime * i);
|
|
Animate_Item(enter_Sequence, item, at);
|
|
}
|
|
float contentExtraStart = centerExtraStart + enter_Stagger_Runtime * 0.25f;
|
|
for (int i = 0; i < content_Extra_Items.Count; i++)
|
|
{
|
|
RectTransform item = content_Extra_Items[i];
|
|
float at = contentExtraStart + (enter_Stagger_Runtime * i);
|
|
Animate_Item(enter_Sequence, item, at);
|
|
}
|
|
if (launch_EzGame_Rect != null)
|
|
{
|
|
float ezStart = rightStart + enter_Stagger_Runtime * (right_ButtonItems.Count + 0.5f);
|
|
Animate_Item(enter_Sequence, launch_EzGame_Rect, ezStart);
|
|
}
|
|
|
|
}
|
|
|
|
public void Bind_Top_Bottom(RectTransform top, RectTransform bottom)
|
|
{
|
|
if (Is_Scene_Object(top))
|
|
{
|
|
group_Top = top;
|
|
}
|
|
if (Is_Scene_Object(bottom))
|
|
{
|
|
group_Bottom = bottom;
|
|
}
|
|
enter_Debug_Logged = false;
|
|
Setup_Button_Tweens();
|
|
if (!gameObject.activeInHierarchy || !play_Enter_OnEnable)
|
|
{
|
|
return;
|
|
}
|
|
if (!enter_Played)
|
|
{
|
|
Start_Enter_Routine();
|
|
return;
|
|
}
|
|
Play_Bars_Anim();
|
|
}
|
|
|
|
void Start_Enter_Routine()
|
|
{
|
|
if (enter_Played)
|
|
{
|
|
return;
|
|
}
|
|
if (enter_Routine != null)
|
|
{
|
|
StopCoroutine(enter_Routine);
|
|
}
|
|
enter_Routine = StartCoroutine(C_Wait_For_Bars_And_Play());
|
|
}
|
|
IEnumerator C_Wait_For_Bars_And_Play()
|
|
{
|
|
float endTime = Time.unscaledTime + enter_Wait_Timeout;
|
|
while (Time.unscaledTime < endTime)
|
|
{
|
|
Cache_Enter_Refs();
|
|
if (Has_Valid_Bars())
|
|
{
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
if (!Has_Valid_Bars())
|
|
{
|
|
if (!enter_Debug_Logged)
|
|
{
|
|
enter_Debug_Logged = true;
|
|
Debug.LogWarning("[UI_Panel_Main] TOP/BTM not found after wait. Please assign references in Inspector or check hierarchy names.");
|
|
}
|
|
}
|
|
Play_Enter_Anim();
|
|
enter_Routine = null;
|
|
}
|
|
bool Has_Valid_Bars()
|
|
{
|
|
return Is_Scene_Object(group_Top) && Is_Scene_Object(group_Bottom);
|
|
}
|
|
List<RectTransform> Collect_Bottom_Items()
|
|
{
|
|
List<RectTransform> items = new();
|
|
if (group_Bottom == null)
|
|
{
|
|
return items;
|
|
}
|
|
HashSet<RectTransform> set = new();
|
|
foreach (var button in group_Bottom.GetComponentsInChildren<Button>(true))
|
|
{
|
|
if (button == null)
|
|
{
|
|
continue;
|
|
}
|
|
RectTransform rect = button.transform as RectTransform;
|
|
if (rect != null)
|
|
{
|
|
set.Add(rect);
|
|
}
|
|
}
|
|
items.AddRange(set);
|
|
items.Sort(Compare_By_X);
|
|
return items;
|
|
}
|
|
|
|
void Play_Bars_Anim()
|
|
{
|
|
Cache_Enter_Refs();
|
|
Kill_Bars_Tweens();
|
|
Cache_Enter_Defaults();
|
|
Update_Enter_Runtime_Times();
|
|
|
|
if (!Is_Scene_Object(group_Top) || !Is_Scene_Object(group_Bottom))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (group_Top != null)
|
|
{
|
|
group_Top.anchoredPosition = pos_Top + Vector2.up * enter_Offset_Y;
|
|
}
|
|
if (group_Bottom != null)
|
|
{
|
|
group_Bottom.anchoredPosition = pos_Bottom - Vector2.up * enter_Offset_Y;
|
|
}
|
|
|
|
for (int i = 0; i < top_Items.Count; i++)
|
|
{
|
|
Prepare_Item(top_Items[i], Vector2.down * enter_Item_Offset_Y, true);
|
|
}
|
|
|
|
List<RectTransform> bottomItems = Collect_Bottom_Items();
|
|
for (int i = 0; i < bottomItems.Count; i++)
|
|
{
|
|
Prepare_Item(bottomItems[i], Vector2.down * enter_Item_Offset_Y, true);
|
|
}
|
|
|
|
if (top_PlayerName != null)
|
|
{
|
|
CanvasGroup playerGroup = Ensure_CanvasGroup(top_PlayerName.gameObject);
|
|
playerGroup.alpha = 0f;
|
|
}
|
|
|
|
bars_Sequence = DOTween.Sequence();
|
|
bars_Sequence.SetUpdate(true);
|
|
bars_Sequence.SetAutoKill(false);
|
|
bars_Sequence.OnKill(() => bars_Sequence = null);
|
|
bars_Sequence.Append(group_Top.DOAnchorPos(pos_Top, enter_Bar_Time_Runtime).SetEase(enter_Move_Ease));
|
|
|
|
float topItemsStart = bars_Sequence.Duration();
|
|
for (int i = 0; i < top_Items.Count; i++)
|
|
{
|
|
RectTransform item = top_Items[i];
|
|
float at = topItemsStart + (enter_Stagger_Runtime * i);
|
|
Animate_Item(bars_Sequence, item, at);
|
|
}
|
|
if (top_PlayerName != null)
|
|
{
|
|
CanvasGroup playerGroup = Ensure_CanvasGroup(top_PlayerName.gameObject);
|
|
Sequence blink = DOTween.Sequence().SetUpdate(true);
|
|
blink.Append(playerGroup.DOFade(1f, 0.15f * enter_Blink_Time_Scale));
|
|
blink.AppendInterval(0.05f * enter_Blink_Time_Scale);
|
|
blink.Append(playerGroup.DOFade(0.2f, 0.1f * enter_Blink_Time_Scale));
|
|
blink.Append(playerGroup.DOFade(1f, 0.2f * enter_Blink_Time_Scale));
|
|
bars_Sequence.Insert(topItemsStart + enter_Stagger_Runtime * 0.5f, blink);
|
|
}
|
|
|
|
float bottomStart = topItemsStart + enter_Bar_Time_Runtime * 0.5f;
|
|
bars_Sequence.Insert(bottomStart, group_Bottom.DOAnchorPos(pos_Bottom, enter_Bar_Time_Runtime).SetEase(enter_Move_Ease));
|
|
|
|
float bottomItemsStart = bottomStart + enter_Bar_Time_Runtime;
|
|
for (int i = 0; i < bottomItems.Count; i++)
|
|
{
|
|
RectTransform item = bottomItems[i];
|
|
float at = bottomItemsStart + (enter_Stagger_Runtime * i);
|
|
Animate_Item(bars_Sequence, item, at);
|
|
}
|
|
}
|
|
|
|
void Start_Background_Loop()
|
|
{
|
|
if (!play_Background_Loop || bg_Loop_Items.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
Stop_Background_Loop();
|
|
for (int i = 0; i < bg_Loop_Items.Count; i++)
|
|
{
|
|
RectTransform rect = bg_Loop_Items[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (!cached_Pos.TryGetValue(rect, out Vector2 origin))
|
|
{
|
|
origin = rect.anchoredPosition;
|
|
cached_Pos[rect] = origin;
|
|
}
|
|
float dir = (i % 2 == 0) ? 1f : -1f;
|
|
Vector2 offset = new(bg_Loop_Offset * dir, bg_Loop_Offset * -dir * 0.6f);
|
|
rect.anchoredPosition = origin;
|
|
Tween tween = rect.DOAnchorPos(origin + offset, bg_Loop_Time + i * 0.3f)
|
|
.SetEase(bg_Loop_Ease)
|
|
.SetLoops(-1, LoopType.Yoyo)
|
|
.SetUpdate(true);
|
|
bg_Loop_Tweens.Add(tween);
|
|
}
|
|
}
|
|
void Stop_Background_Loop()
|
|
{
|
|
for (int i = 0; i < bg_Loop_Tweens.Count; i++)
|
|
{
|
|
Tween tween = bg_Loop_Tweens[i];
|
|
if (tween != null)
|
|
{
|
|
tween.Kill();
|
|
}
|
|
}
|
|
bg_Loop_Tweens.Clear();
|
|
for (int i = 0; i < bg_Loop_Items.Count; i++)
|
|
{
|
|
RectTransform rect = bg_Loop_Items[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (cached_Pos.TryGetValue(rect, out Vector2 pos))
|
|
{
|
|
rect.anchoredPosition = pos;
|
|
}
|
|
if (cached_Scale.TryGetValue(rect, out Vector3 scale))
|
|
{
|
|
rect.localScale = scale;
|
|
}
|
|
if (cached_RotationZ.TryGetValue(rect, out float rotZ))
|
|
{
|
|
Vector3 euler = rect.localEulerAngles;
|
|
euler.z = rotZ;
|
|
rect.localEulerAngles = euler;
|
|
}
|
|
CanvasGroup group = rect.GetComponent<CanvasGroup>();
|
|
if (group != null)
|
|
{
|
|
group.alpha = 1f;
|
|
}
|
|
}
|
|
}
|
|
void Cache_Pos(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!cached_Pos.ContainsKey(rect))
|
|
{
|
|
cached_Pos.Add(rect, rect.anchoredPosition);
|
|
}
|
|
}
|
|
void Cache_Scale(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!cached_Scale.ContainsKey(rect))
|
|
{
|
|
cached_Scale.Add(rect, rect.localScale);
|
|
}
|
|
}
|
|
void Cache_Rotation(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!cached_RotationZ.ContainsKey(rect))
|
|
{
|
|
cached_RotationZ.Add(rect, rect.localEulerAngles.z);
|
|
}
|
|
}
|
|
void Prune_Cached_Pos()
|
|
{
|
|
if (cached_Pos.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
List<RectTransform> toRemove = null;
|
|
foreach (var kvp in cached_Pos)
|
|
{
|
|
if (kvp.Key == null)
|
|
{
|
|
if (toRemove == null)
|
|
{
|
|
toRemove = new List<RectTransform>();
|
|
}
|
|
toRemove.Add(kvp.Key);
|
|
}
|
|
}
|
|
if (toRemove != null)
|
|
{
|
|
for (int i = 0; i < toRemove.Count; i++)
|
|
{
|
|
cached_Pos.Remove(toRemove[i]);
|
|
cached_Scale.Remove(toRemove[i]);
|
|
cached_RotationZ.Remove(toRemove[i]);
|
|
}
|
|
}
|
|
}
|
|
void Prepare_Background_Deco(RectTransform rect, int index)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
if (Is_BG2(rect))
|
|
{
|
|
Cache_Pos(rect);
|
|
Cache_Scale(rect);
|
|
Cache_Rotation(rect);
|
|
CanvasGroup bg2Group = Ensure_CanvasGroup(rect.gameObject);
|
|
if (bg2Group != null)
|
|
{
|
|
bg2Group.alpha = 0f;
|
|
}
|
|
return;
|
|
}
|
|
Cache_Pos(rect);
|
|
Cache_Scale(rect);
|
|
Cache_Rotation(rect);
|
|
int seed = Stable_Hash(rect.name) + (index + 1) * 17;
|
|
float offsetX = Mathf.Lerp(-bg_Deco_Offset, bg_Deco_Offset, Hash01(seed, 1));
|
|
float offsetY = Mathf.Lerp(-bg_Deco_Offset, bg_Deco_Offset, Hash01(seed, 2));
|
|
float rotate = Mathf.Lerp(-bg_Deco_Rotate, bg_Deco_Rotate, Hash01(seed, 3));
|
|
float scaleMul = Mathf.Lerp(bg_Deco_Scale_From, bg_Deco_Scale_From + 0.15f, Hash01(seed, 4));
|
|
|
|
rect.anchoredPosition = cached_Pos[rect] + new Vector2(offsetX, offsetY);
|
|
rect.localScale = cached_Scale[rect] * Mathf.Max(0.01f, scaleMul);
|
|
Vector3 euler = rect.localEulerAngles;
|
|
euler.z = cached_RotationZ[rect] + rotate;
|
|
rect.localEulerAngles = euler;
|
|
|
|
CanvasGroup group = Ensure_CanvasGroup(rect.gameObject);
|
|
if (group != null)
|
|
{
|
|
group.alpha = 0f;
|
|
}
|
|
}
|
|
void Animate_Background_Deco(Sequence sequence, RectTransform rect, float at)
|
|
{
|
|
if (sequence == null || rect == null)
|
|
{
|
|
return;
|
|
}
|
|
bool isBg2 = Is_BG2(rect);
|
|
if (isBg2)
|
|
{
|
|
Animate_Flicker(sequence, rect, at, 3, 0.05f, 0.03f);
|
|
return;
|
|
}
|
|
if (cached_Pos.TryGetValue(rect, out Vector2 targetPos))
|
|
{
|
|
sequence.Insert(at, rect.DOAnchorPos(targetPos, bg_Deco_Time_Runtime).SetEase(bg_Deco_Ease));
|
|
}
|
|
if (cached_Scale.TryGetValue(rect, out Vector3 targetScale))
|
|
{
|
|
sequence.Insert(at, rect.DOScale(targetScale, bg_Deco_Time_Runtime).SetEase(bg_Deco_Ease));
|
|
}
|
|
if (cached_RotationZ.TryGetValue(rect, out float targetRotZ))
|
|
{
|
|
sequence.Insert(at, rect.DORotate(new Vector3(0f, 0f, targetRotZ), bg_Deco_Time_Runtime, RotateMode.Fast));
|
|
}
|
|
if (rect.TryGetComponent(out CanvasGroup group))
|
|
{
|
|
sequence.Insert(at, group.DOFade(1f, bg_Deco_Time_Runtime).SetEase(bg_Deco_Ease));
|
|
}
|
|
}
|
|
void Prepare_Item(RectTransform rect, Vector2 offset, bool fade)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
Cache_Pos(rect);
|
|
rect.anchoredPosition = cached_Pos[rect] + offset;
|
|
if (fade)
|
|
{
|
|
CanvasGroup group = Ensure_CanvasGroup(rect.gameObject);
|
|
group.alpha = 0f;
|
|
}
|
|
}
|
|
void Prepare_FadeOnly(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
Cache_Pos(rect);
|
|
CanvasGroup group = Ensure_CanvasGroup(rect.gameObject);
|
|
if (group != null)
|
|
{
|
|
group.alpha = 0f;
|
|
}
|
|
}
|
|
void Animate_Item(Sequence sequence, RectTransform rect, float at)
|
|
{
|
|
if (sequence == null || rect == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!cached_Pos.TryGetValue(rect, out Vector2 target))
|
|
{
|
|
target = rect.anchoredPosition;
|
|
}
|
|
float duration = enter_Item_Time_Runtime > 0f ? enter_Item_Time_Runtime : enter_Item_Time;
|
|
sequence.Insert(at, rect.DOAnchorPos(target, duration).SetEase(enter_Move_Ease));
|
|
if (rect.TryGetComponent(out CanvasGroup group))
|
|
{
|
|
sequence.Insert(at, group.DOFade(1f, duration).SetEase(enter_Move_Ease));
|
|
}
|
|
}
|
|
void Animate_Flicker(Sequence sequence, RectTransform rect, float at, int flashes, float flashTime, float interval)
|
|
{
|
|
if (sequence == null || rect == null)
|
|
{
|
|
return;
|
|
}
|
|
CanvasGroup group = Ensure_CanvasGroup(rect.gameObject);
|
|
if (group == null)
|
|
{
|
|
return;
|
|
}
|
|
group.alpha = 0f;
|
|
int count = Mathf.Max(1, flashes);
|
|
float time = Mathf.Max(0.01f, flashTime);
|
|
float gap = Mathf.Max(0f, interval);
|
|
Sequence flicker = DOTween.Sequence().SetUpdate(true);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
flicker.Append(group.DOFade(1f, time).SetEase(Ease.OutQuad));
|
|
flicker.Append(group.DOFade(0f, time).SetEase(Ease.InQuad));
|
|
if (gap > 0f)
|
|
{
|
|
flicker.AppendInterval(gap);
|
|
}
|
|
}
|
|
flicker.Append(group.DOFade(1f, time).SetEase(Ease.OutQuad));
|
|
sequence.Insert(at, flicker);
|
|
}
|
|
void Kill_Target(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
DOTween.Kill(rect);
|
|
if (rect.TryGetComponent(out CanvasGroup group))
|
|
{
|
|
DOTween.Kill(group);
|
|
}
|
|
}
|
|
CanvasGroup Ensure_CanvasGroup(GameObject target)
|
|
{
|
|
if (target == null)
|
|
{
|
|
return null;
|
|
}
|
|
target.Try_Get_Component(out CanvasGroup canvasGroup);
|
|
return canvasGroup;
|
|
}
|
|
RectTransform Find_Rect(Transform root, params string[] names)
|
|
{
|
|
if (root == null || names == null || names.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
for (int i = 0; i < names.Length; i++)
|
|
{
|
|
string name = names[i];
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
continue;
|
|
}
|
|
Transform direct = root.Find(name);
|
|
if (direct != null)
|
|
{
|
|
return direct as RectTransform;
|
|
}
|
|
}
|
|
RectTransform[] rects = root.GetComponentsInChildren<RectTransform>(true);
|
|
for (int i = 0; i < rects.Length; i++)
|
|
{
|
|
RectTransform rect = rects[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
for (int j = 0; j < names.Length; j++)
|
|
{
|
|
string name = names[j];
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
continue;
|
|
}
|
|
if (string.Equals(rect.name, name, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return rect;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
RectTransform Find_Rect_Global(params string[] names)
|
|
{
|
|
if (names == null || names.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
RectTransform[] rects = UnityEngine.Object.FindObjectsByType<RectTransform>(FindObjectsInactive.Include, FindObjectsSortMode.InstanceID);
|
|
RectTransform exact = Find_Rect_In_List(rects, names, false);
|
|
if (exact != null)
|
|
{
|
|
return exact;
|
|
}
|
|
return Find_Rect_In_List(rects, names, true);
|
|
}
|
|
void Ensure_Scene_Ref(ref RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!Is_Scene_Object(rect))
|
|
{
|
|
rect = null;
|
|
}
|
|
}
|
|
bool Is_Scene_Object(Component component)
|
|
{
|
|
if (component == null)
|
|
{
|
|
return false;
|
|
}
|
|
return component.gameObject.scene.IsValid();
|
|
}
|
|
RectTransform Find_Rect_In_List(RectTransform[] rects, string[] names, bool allowContains)
|
|
{
|
|
if (rects == null)
|
|
{
|
|
return null;
|
|
}
|
|
for (int i = 0; i < rects.Length; i++)
|
|
{
|
|
RectTransform rect = rects[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
string rectName = rect.name;
|
|
for (int j = 0; j < names.Length; j++)
|
|
{
|
|
string name = names[j];
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
continue;
|
|
}
|
|
if (allowContains)
|
|
{
|
|
if (rectName.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
|
|
{
|
|
return rect;
|
|
}
|
|
}
|
|
else if (string.Equals(rectName, name, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return rect;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
RectTransform Find_Bar_By_Position(RectTransform root, bool isTop)
|
|
{
|
|
if (root == null)
|
|
{
|
|
return null;
|
|
}
|
|
RectTransform[] rects = root.GetComponentsInChildren<RectTransform>(true);
|
|
RectTransform best = null;
|
|
float bestY = isTop ? float.NegativeInfinity : float.PositiveInfinity;
|
|
for (int i = 0; i < rects.Length; i++)
|
|
{
|
|
RectTransform rect = rects[i];
|
|
if (rect == null || rect == root)
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Background_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
float width = rect.rect.width;
|
|
float height = rect.rect.height;
|
|
if (width < height * 1.8f)
|
|
{
|
|
continue;
|
|
}
|
|
float y = rect.position.y;
|
|
if (isTop)
|
|
{
|
|
if (y > bestY)
|
|
{
|
|
bestY = y;
|
|
best = rect;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (y < bestY)
|
|
{
|
|
bestY = y;
|
|
best = rect;
|
|
}
|
|
}
|
|
}
|
|
return best;
|
|
}
|
|
int Get_Hierarchy_Depth(RectTransform rect, RectTransform root)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return 0;
|
|
}
|
|
int depth = 0;
|
|
Transform current = rect.parent;
|
|
while (current != null && current != root)
|
|
{
|
|
depth++;
|
|
current = current.parent;
|
|
}
|
|
return depth;
|
|
}
|
|
bool Has_Selected_Ancestor(RectTransform rect, HashSet<RectTransform> selected, RectTransform root)
|
|
{
|
|
if (rect == null || selected == null || selected.Count == 0)
|
|
{
|
|
return false;
|
|
}
|
|
Transform current = rect.parent;
|
|
while (current != null && current != root)
|
|
{
|
|
RectTransform parentRect = current as RectTransform;
|
|
if (parentRect != null && selected.Contains(parentRect))
|
|
{
|
|
return true;
|
|
}
|
|
current = current.parent;
|
|
}
|
|
return false;
|
|
}
|
|
bool Is_Gyro_Root(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (rect.GetComponent<Selectable>() != null)
|
|
{
|
|
return true;
|
|
}
|
|
if (rect.GetComponent<Graphic>() != null)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
int Compare_By_X(RectTransform a, RectTransform b)
|
|
{
|
|
if (a == null && b == null)
|
|
{
|
|
return 0;
|
|
}
|
|
if (a == null)
|
|
{
|
|
return 1;
|
|
}
|
|
if (b == null)
|
|
{
|
|
return -1;
|
|
}
|
|
int cmp = a.position.x.CompareTo(b.position.x);
|
|
if (cmp != 0)
|
|
{
|
|
return cmp;
|
|
}
|
|
return b.position.y.CompareTo(a.position.y);
|
|
}
|
|
int Compare_By_Y_Desc(RectTransform a, RectTransform b)
|
|
{
|
|
if (a == null && b == null)
|
|
{
|
|
return 0;
|
|
}
|
|
if (a == null)
|
|
{
|
|
return 1;
|
|
}
|
|
if (b == null)
|
|
{
|
|
return -1;
|
|
}
|
|
int cmp = b.position.y.CompareTo(a.position.y);
|
|
if (cmp != 0)
|
|
{
|
|
return cmp;
|
|
}
|
|
return a.position.x.CompareTo(b.position.x);
|
|
}
|
|
bool Is_Background_Name(string name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
return false;
|
|
}
|
|
string lower = name.ToLowerInvariant();
|
|
if (lower.Contains("background") || lower.Contains("mask"))
|
|
{
|
|
return true;
|
|
}
|
|
if (lower == "bg")
|
|
{
|
|
return true;
|
|
}
|
|
if (lower.EndsWith("_bg") || lower.EndsWith(" bg"))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool Is_Jiantou_Name(string name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
return false;
|
|
}
|
|
string key = string.IsNullOrEmpty(jiantou_Name_Contains) ? "jiantou" : jiantou_Name_Contains;
|
|
return name.IndexOf(key, StringComparison.OrdinalIgnoreCase) >= 0;
|
|
}
|
|
bool Is_BG2_Name(string name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
return false;
|
|
}
|
|
string lower = name.ToLowerInvariant();
|
|
if (lower.Contains("bg2") || lower.Contains("background_2") || lower.Contains("background2"))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool Is_BG2(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (background_Bg2 != null && rect == background_Bg2)
|
|
{
|
|
return true;
|
|
}
|
|
if (Is_BG2_Name(rect.name))
|
|
{
|
|
return true;
|
|
}
|
|
if (background_Bg2 == null && group_Background != null && group_Background.childCount > 1)
|
|
{
|
|
RectTransform lastChild = group_Background.GetChild(group_Background.childCount - 1) as RectTransform;
|
|
if (rect == lastChild)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
bool Has_Jiantou_Descendant(Transform root)
|
|
{
|
|
if (root == null)
|
|
{
|
|
return false;
|
|
}
|
|
for (int i = 0; i < root.childCount; i++)
|
|
{
|
|
Transform child = root.GetChild(i);
|
|
if (child == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (Is_Jiantou_Name(child.name))
|
|
{
|
|
return true;
|
|
}
|
|
if (Has_Jiantou_Descendant(child))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
int Stable_Hash(string text)
|
|
{
|
|
if (string.IsNullOrEmpty(text))
|
|
{
|
|
return 0;
|
|
}
|
|
unchecked
|
|
{
|
|
int hash = 23;
|
|
for (int i = 0; i < text.Length; i++)
|
|
{
|
|
hash = (hash * 31) + text[i];
|
|
}
|
|
return hash;
|
|
}
|
|
}
|
|
float Hash01(int seed, int salt)
|
|
{
|
|
unchecked
|
|
{
|
|
uint value = (uint)(seed ^ (salt * 0x9E3779B9));
|
|
value ^= value >> 16;
|
|
value *= 0x85ebca6b;
|
|
value ^= value >> 13;
|
|
return (value & 0xFFFF) / 65535f;
|
|
}
|
|
}
|
|
void Update_Enter_Runtime_Times()
|
|
{
|
|
float speed = Mathf.Max(enter_UI_Speed, 0.01f);
|
|
enter_Background_Time_Runtime = enter_Background_Time / speed;
|
|
enter_Bar_Time_Runtime = enter_Bar_Time / speed;
|
|
enter_Item_Time_Runtime = enter_Item_Time / speed;
|
|
enter_Stagger_Runtime = enter_Stagger / speed;
|
|
enter_Blink_Time_Scale = 1f / speed;
|
|
bg_Deco_Time_Runtime = bg_Deco_Time / speed;
|
|
bg_Deco_Stagger_Runtime = bg_Deco_Stagger / speed;
|
|
}
|
|
void Capture_Gyro_Base()
|
|
{
|
|
Ensure_Gyro_Targets();
|
|
if (gyro_Targets.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
gyro_Base_Pos_Map.Clear();
|
|
gyro_Base_Rot_Map.Clear();
|
|
for (int i = 0; i < gyro_Targets.Count; i++)
|
|
{
|
|
RectTransform target = gyro_Targets[i];
|
|
if (target == null)
|
|
{
|
|
continue;
|
|
}
|
|
gyro_Base_Pos_Map[target] = target.anchoredPosition;
|
|
gyro_Base_Rot_Map[target] = target.localEulerAngles;
|
|
}
|
|
gyro_Current_Offset = Vector2.zero;
|
|
gyro_Current_RotDelta = Vector3.zero;
|
|
if (gyro_Apply_BG_Scale && group_Background != null && gyro_Targets.Contains(group_Background))
|
|
{
|
|
if (!gyro_BG_Base_Scale_Set)
|
|
{
|
|
gyro_BG_Base_Scale = group_Background.localScale;
|
|
gyro_BG_Base_Scale_Set = true;
|
|
}
|
|
float extra = Mathf.Max(gyro_BG_Extra_Scale, 1f);
|
|
group_Background.localScale = gyro_BG_Base_Scale * extra;
|
|
}
|
|
gyro_Inited = true;
|
|
}
|
|
void Ensure_Gyro_Targets()
|
|
{
|
|
gyro_Targets.Clear();
|
|
gyro_Offset_Weight_Map.Clear();
|
|
gyro_Rot_Weight_Map.Clear();
|
|
Cache_Enter_Refs();
|
|
|
|
RectTransform characterRect = gyro_Character_Rect;
|
|
if (characterRect == null && image_Character != null && Is_Scene_Object(image_Character))
|
|
{
|
|
characterRect = image_Character.transform as RectTransform;
|
|
}
|
|
|
|
RectTransform dialogRect = gyro_Dialog_Rect;
|
|
RectTransform backgroundRect = group_Background;
|
|
|
|
if (Is_Scene_Object(backgroundRect))
|
|
{
|
|
float w = Mathf.Abs(gyro_Background_Weight);
|
|
Add_Gyro_Target(backgroundRect, -w, -w, true);
|
|
}
|
|
if (Is_Scene_Object(characterRect))
|
|
{
|
|
float w = Mathf.Abs(gyro_Character_Weight);
|
|
Add_Gyro_Target(characterRect, w, w, false);
|
|
}
|
|
if (Is_Scene_Object(dialogRect))
|
|
{
|
|
float w = Mathf.Abs(gyro_Dialog_Weight);
|
|
Add_Gyro_Target(dialogRect, w, w, false);
|
|
}
|
|
if (Is_Scene_Object(group_RightButtons))
|
|
{
|
|
float w = Mathf.Abs(gyro_RightButtons_Rotation_Weight);
|
|
Add_Gyro_Target(group_RightButtons, 0f, w, false);
|
|
}
|
|
if (Is_Scene_Object(group_RightButtons_Alt))
|
|
{
|
|
float w = Mathf.Abs(gyro_RightButtons_Rotation_Weight);
|
|
Add_Gyro_Target(group_RightButtons_Alt, 0f, w, false);
|
|
}
|
|
if (Is_Scene_Object(group_DailyTasks))
|
|
{
|
|
float w = Mathf.Abs(gyro_DailyTasks_Rotation_Weight);
|
|
Add_Gyro_Target(group_DailyTasks, 0f, w, false);
|
|
}
|
|
if (Is_Scene_Object(dailyTask_BG) && (group_DailyTasks == null || !dailyTask_BG.IsChildOf(group_DailyTasks)))
|
|
{
|
|
float w = Mathf.Abs(gyro_DailyTasks_Rotation_Weight);
|
|
Add_Gyro_Target(dailyTask_BG, 0f, w, false);
|
|
}
|
|
if (Is_Scene_Object(dailyTask_BG_1) && (group_DailyTasks == null || !dailyTask_BG_1.IsChildOf(group_DailyTasks)))
|
|
{
|
|
float w = Mathf.Abs(gyro_DailyTasks_Rotation_Weight);
|
|
Add_Gyro_Target(dailyTask_BG_1, 0f, w, false);
|
|
}
|
|
if (Is_Scene_Object(dailyTask_BG_2) && (group_DailyTasks == null || !dailyTask_BG_2.IsChildOf(group_DailyTasks)))
|
|
{
|
|
float w = Mathf.Abs(gyro_DailyTasks_Rotation_Weight);
|
|
Add_Gyro_Target(dailyTask_BG_2, 0f, w, false);
|
|
}
|
|
if (Is_Scene_Object(else_Button))
|
|
{
|
|
float w = Mathf.Abs(gyro_RightButtons_Rotation_Weight);
|
|
Add_Gyro_Target(else_Button, 0f, w, false);
|
|
}
|
|
}
|
|
void Reset_Gyro_To_Base()
|
|
{
|
|
if (gyro_Targets.Count > 0)
|
|
{
|
|
for (int i = 0; i < gyro_Targets.Count; i++)
|
|
{
|
|
RectTransform target = gyro_Targets[i];
|
|
if (target == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (gyro_Base_Pos_Map.TryGetValue(target, out Vector2 basePos))
|
|
{
|
|
target.anchoredPosition = basePos;
|
|
}
|
|
if (gyro_Base_Rot_Map.TryGetValue(target, out Vector3 baseRot))
|
|
{
|
|
target.localEulerAngles = baseRot;
|
|
}
|
|
}
|
|
}
|
|
if (gyro_BG_Base_Scale_Set && group_Background != null)
|
|
{
|
|
group_Background.localScale = gyro_BG_Base_Scale;
|
|
}
|
|
gyro_BG_Base_Scale_Set = false;
|
|
gyro_Targets.Clear();
|
|
gyro_Base_Pos_Map.Clear();
|
|
gyro_Base_Rot_Map.Clear();
|
|
gyro_Offset_Weight_Map.Clear();
|
|
gyro_Rot_Weight_Map.Clear();
|
|
gyro_Current_Offset = Vector2.zero;
|
|
gyro_Current_RotDelta = Vector3.zero;
|
|
gyro_Inited = false;
|
|
}
|
|
void Start_Jiantou_Loop()
|
|
{
|
|
if (!play_Jiantou_Loop)
|
|
{
|
|
return;
|
|
}
|
|
Cache_Enter_Refs();
|
|
if (!jiantou_Inited)
|
|
{
|
|
Cache_Jiantou_Templates();
|
|
Build_Jiantou_Pool();
|
|
jiantou_Inited = jiantou_Flows.Count > 0;
|
|
}
|
|
if (jiantou_Require_Hover && !jiantou_Hovered)
|
|
{
|
|
Hide_Jiantou_All();
|
|
jiantou_Running = false;
|
|
return;
|
|
}
|
|
Restart_Jiantou_Loop();
|
|
}
|
|
void Stop_Jiantou_Loop()
|
|
{
|
|
jiantou_Running = false;
|
|
Stop_Jiantou_Flash();
|
|
for (int f = 0; f < jiantou_Flows.Count; f++)
|
|
{
|
|
JiantouFlow flow = jiantou_Flows[f];
|
|
if (flow == null)
|
|
{
|
|
continue;
|
|
}
|
|
for (int i = 0; i < flow.instances.Count; i++)
|
|
{
|
|
RectTransform rect = flow.instances[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
Kill_Target(rect);
|
|
rect.anchoredPosition = flow.basePos;
|
|
if (rect != flow.template)
|
|
{
|
|
rect.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
flow.startY.Clear();
|
|
}
|
|
}
|
|
void Hide_Jiantou_All()
|
|
{
|
|
Stop_Jiantou_Flash();
|
|
for (int f = 0; f < jiantou_Flows.Count; f++)
|
|
{
|
|
JiantouFlow flow = jiantou_Flows[f];
|
|
if (flow == null)
|
|
{
|
|
continue;
|
|
}
|
|
for (int i = 0; i < flow.instances.Count; i++)
|
|
{
|
|
RectTransform rect = flow.instances[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
CanvasGroup group = Ensure_CanvasGroup(rect.gameObject);
|
|
if (group != null)
|
|
{
|
|
group.alpha = 0f;
|
|
}
|
|
if (rect != flow.template)
|
|
{
|
|
rect.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void Show_Jiantou_All()
|
|
{
|
|
for (int f = 0; f < jiantou_Flows.Count; f++)
|
|
{
|
|
JiantouFlow flow = jiantou_Flows[f];
|
|
if (flow == null)
|
|
{
|
|
continue;
|
|
}
|
|
for (int i = 0; i < flow.instances.Count; i++)
|
|
{
|
|
RectTransform rect = flow.instances[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
rect.gameObject.SetActive(true);
|
|
}
|
|
}
|
|
}
|
|
public void On_Jiantou_Hover_Enter()
|
|
{
|
|
if (!play_Jiantou_Loop || !jiantou_Require_Hover)
|
|
{
|
|
return;
|
|
}
|
|
jiantou_Hovered = true;
|
|
Start_Jiantou_Loop();
|
|
if (jiantou_Flash_Routine != null)
|
|
{
|
|
StopCoroutine(jiantou_Flash_Routine);
|
|
}
|
|
jiantou_Flash_Routine = StartCoroutine(C_Jiantou_Flash_Then_Run());
|
|
StartCoroutine(C_Ensure_Jiantou_Run());
|
|
}
|
|
public void On_Jiantou_Hover_Exit()
|
|
{
|
|
if (!play_Jiantou_Loop || !jiantou_Require_Hover)
|
|
{
|
|
return;
|
|
}
|
|
jiantou_Hovered = false;
|
|
jiantou_Running = false;
|
|
Stop_Jiantou_Flash();
|
|
Hide_Jiantou_All();
|
|
}
|
|
IEnumerator C_Jiantou_Flash_Then_Run()
|
|
{
|
|
jiantou_Running = false;
|
|
Stop_Jiantou_Flash();
|
|
Show_Jiantou_All();
|
|
float flashTime = Mathf.Max(jiantou_Flash_Time, 0.01f);
|
|
int flashCount = Mathf.Max(1, jiantou_Flash_Count);
|
|
float interval = Mathf.Max(jiantou_Flash_Interval, 0f);
|
|
for (int f = 0; f < jiantou_Flows.Count; f++)
|
|
{
|
|
JiantouFlow flow = jiantou_Flows[f];
|
|
if (flow == null)
|
|
{
|
|
continue;
|
|
}
|
|
for (int i = 0; i < flow.instances.Count; i++)
|
|
{
|
|
RectTransform rect = flow.instances[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
CanvasGroup group = Ensure_CanvasGroup(rect.gameObject);
|
|
if (group == null)
|
|
{
|
|
continue;
|
|
}
|
|
group.alpha = 0f;
|
|
Tween flash = group.DOFade(1f, flashTime)
|
|
.SetEase(Ease.InOutQuad)
|
|
.SetLoops(flashCount * 2, LoopType.Yoyo)
|
|
.SetUpdate(true);
|
|
jiantou_Flash_Tweens.Add(flash);
|
|
}
|
|
}
|
|
float wait = (flashTime * 2f * flashCount) + interval;
|
|
if (wait > 0f)
|
|
{
|
|
yield return gyro_Use_Unscaled ? new WaitForSecondsRealtime(wait) : new WaitForSeconds(wait);
|
|
}
|
|
for (int i = 0; i < jiantou_Flash_Tweens.Count; i++)
|
|
{
|
|
Tween tween = jiantou_Flash_Tweens[i];
|
|
if (tween != null)
|
|
{
|
|
tween.Kill();
|
|
}
|
|
}
|
|
jiantou_Flash_Tweens.Clear();
|
|
for (int f = 0; f < jiantou_Flows.Count; f++)
|
|
{
|
|
JiantouFlow flow = jiantou_Flows[f];
|
|
if (flow == null)
|
|
{
|
|
continue;
|
|
}
|
|
for (int i = 0; i < flow.instances.Count; i++)
|
|
{
|
|
RectTransform rect = flow.instances[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (rect.TryGetComponent(out CanvasGroup group))
|
|
{
|
|
group.alpha = 1f;
|
|
}
|
|
}
|
|
}
|
|
if (jiantou_Hovered)
|
|
{
|
|
Restart_Jiantou_Loop();
|
|
}
|
|
jiantou_Running = jiantou_Hovered;
|
|
jiantou_Flash_Routine = null;
|
|
}
|
|
IEnumerator C_Ensure_Jiantou_Run()
|
|
{
|
|
float flashTime = Mathf.Max(jiantou_Flash_Time, 0.01f);
|
|
int flashCount = Mathf.Max(1, jiantou_Flash_Count);
|
|
float interval = Mathf.Max(jiantou_Flash_Interval, 0f);
|
|
float wait = (flashTime * 2f * flashCount) + interval + 0.05f;
|
|
if (wait > 0f)
|
|
{
|
|
yield return gyro_Use_Unscaled ? new WaitForSecondsRealtime(wait) : new WaitForSeconds(wait);
|
|
}
|
|
if (jiantou_Hovered)
|
|
{
|
|
Restart_Jiantou_Loop();
|
|
}
|
|
}
|
|
void Stop_Jiantou_Flash()
|
|
{
|
|
if (jiantou_Flash_Routine != null)
|
|
{
|
|
StopCoroutine(jiantou_Flash_Routine);
|
|
jiantou_Flash_Routine = null;
|
|
}
|
|
for (int i = 0; i < jiantou_Flash_Tweens.Count; i++)
|
|
{
|
|
Tween tween = jiantou_Flash_Tweens[i];
|
|
if (tween != null)
|
|
{
|
|
tween.Kill();
|
|
}
|
|
}
|
|
jiantou_Flash_Tweens.Clear();
|
|
}
|
|
void Update_Jiantou_Loop()
|
|
{
|
|
if (!play_Jiantou_Loop || !jiantou_Running || jiantou_Flows.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
float dt = gyro_Use_Unscaled ? Time.unscaledDeltaTime : Time.deltaTime;
|
|
if (dt <= 0f)
|
|
{
|
|
return;
|
|
}
|
|
for (int f = 0; f < jiantou_Flows.Count; f++)
|
|
{
|
|
JiantouFlow flow = jiantou_Flows[f];
|
|
if (flow == null || flow.instances.Count == 0 || flow.speed <= 0f)
|
|
{
|
|
continue;
|
|
}
|
|
float delta = flow.speed * dt * flow.direction;
|
|
for (int i = 0; i < flow.instances.Count; i++)
|
|
{
|
|
RectTransform rect = flow.instances[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
Vector2 pos = rect.anchoredPosition;
|
|
pos.y += delta;
|
|
rect.anchoredPosition = pos;
|
|
if (flow.direction > 0f && pos.y > flow.endLimitY)
|
|
{
|
|
float resetY = (flow.startY.Count > i) ? flow.startY[i] : flow.basePos.y;
|
|
rect.anchoredPosition = new Vector2(flow.basePos.x, resetY);
|
|
}
|
|
else if (flow.direction < 0f && pos.y < flow.endLimitY)
|
|
{
|
|
float resetY = (flow.startY.Count > i) ? flow.startY[i] : flow.basePos.y;
|
|
rect.anchoredPosition = new Vector2(flow.basePos.x, resetY);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void Cache_Jiantou_Templates()
|
|
{
|
|
jiantou_Flows.Clear();
|
|
RectTransform left = jiantou_Left_Template;
|
|
RectTransform right = jiantou_Right_Template;
|
|
|
|
if (left == null || right == null)
|
|
{
|
|
RectTransform[] rects = content_Root != null
|
|
? content_Root.GetComponentsInChildren<RectTransform>(true)
|
|
: UnityEngine.Object.FindObjectsByType<RectTransform>(FindObjectsInactive.Include, FindObjectsSortMode.InstanceID);
|
|
List<RectTransform> candidates = new();
|
|
for (int i = 0; i < rects.Length; i++)
|
|
{
|
|
RectTransform rect = rects[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (!Is_Jiantou_Name(rect.name))
|
|
{
|
|
continue;
|
|
}
|
|
string lowerName = rect.name.ToLowerInvariant();
|
|
if (lowerName.Contains("_loop_") || lowerName.Contains("_flow_"))
|
|
{
|
|
continue;
|
|
}
|
|
candidates.Add(rect);
|
|
}
|
|
candidates.Sort((a, b) => Get_Rect_Area(b).CompareTo(Get_Rect_Area(a)));
|
|
if (left == null && candidates.Count > 0)
|
|
{
|
|
left = candidates[0];
|
|
}
|
|
if (right == null && candidates.Count > 1)
|
|
{
|
|
right = candidates[1];
|
|
}
|
|
}
|
|
|
|
if (left != null && right != null && left == right)
|
|
{
|
|
right = null;
|
|
}
|
|
if (left != null && right != null && left.position.x > right.position.x)
|
|
{
|
|
RectTransform temp = left;
|
|
left = right;
|
|
right = temp;
|
|
}
|
|
if (left != null && right != null)
|
|
{
|
|
Add_Jiantou_Flow(left, 1f);
|
|
Add_Jiantou_Flow(right, -1f);
|
|
}
|
|
else if (left != null)
|
|
{
|
|
float dir = left.position.x <= 0f ? 1f : -1f;
|
|
Add_Jiantou_Flow(left, dir);
|
|
}
|
|
else if (right != null)
|
|
{
|
|
float dir = right.position.x >= 0f ? -1f : 1f;
|
|
Add_Jiantou_Flow(right, dir);
|
|
}
|
|
}
|
|
void Add_Jiantou_Flow(RectTransform template, float direction)
|
|
{
|
|
if (template == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!Is_Scene_Object(template))
|
|
{
|
|
return;
|
|
}
|
|
JiantouFlow flow = new JiantouFlow
|
|
{
|
|
template = template,
|
|
parent = template.parent as RectTransform,
|
|
direction = direction,
|
|
basePos = template.anchoredPosition
|
|
};
|
|
jiantou_Flows.Add(flow);
|
|
}
|
|
void Build_Jiantou_Pool()
|
|
{
|
|
if (jiantou_Flows.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
int poolSize = Mathf.Max(1, jiantou_Pool_Size);
|
|
for (int f = 0; f < jiantou_Flows.Count; f++)
|
|
{
|
|
JiantouFlow flow = jiantou_Flows[f];
|
|
if (flow == null || flow.template == null)
|
|
{
|
|
continue;
|
|
}
|
|
flow.instances.Clear();
|
|
flow.startY.Clear();
|
|
RectTransform template = flow.template;
|
|
RectTransform parent = template.parent as RectTransform;
|
|
flow.parent = parent;
|
|
List<RectTransform> pool = new();
|
|
pool.Add(template);
|
|
|
|
List<RectTransform> extras = new();
|
|
if (parent != null)
|
|
{
|
|
for (int i = 0; i < parent.childCount; i++)
|
|
{
|
|
RectTransform child = parent.GetChild(i) as RectTransform;
|
|
if (child == null || child == template)
|
|
{
|
|
continue;
|
|
}
|
|
if (child.name.StartsWith($"{template.name}_Loop_", StringComparison.Ordinal)
|
|
|| child.name.StartsWith($"{template.name}_Flow_", StringComparison.Ordinal))
|
|
{
|
|
extras.Add(child);
|
|
}
|
|
}
|
|
}
|
|
extras.Sort((a, b) => string.CompareOrdinal(a.name, b.name));
|
|
for (int i = 0; i < extras.Count; i++)
|
|
{
|
|
RectTransform child = extras[i];
|
|
if (pool.Count < poolSize)
|
|
{
|
|
pool.Add(child);
|
|
}
|
|
else
|
|
{
|
|
child.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
for (int i = pool.Count; i < poolSize; i++)
|
|
{
|
|
RectTransform instance = Instantiate(template, parent);
|
|
if (instance == null)
|
|
{
|
|
continue;
|
|
}
|
|
instance.name = $"{template.name}_Loop_{i}";
|
|
pool.Add(instance);
|
|
}
|
|
for (int i = 0; i < pool.Count; i++)
|
|
{
|
|
RectTransform instance = pool[i];
|
|
if (instance == null)
|
|
{
|
|
continue;
|
|
}
|
|
instance.gameObject.SetActive(true);
|
|
flow.instances.Add(instance);
|
|
}
|
|
}
|
|
}
|
|
void Restart_Jiantou_Loop()
|
|
{
|
|
Stop_Jiantou_Loop();
|
|
if (jiantou_Flows.Count == 0 || jiantou_Move_Duration <= 0f)
|
|
{
|
|
return;
|
|
}
|
|
float duration = Mathf.Max(jiantou_Move_Duration, 0.01f);
|
|
float staggerValue = jiantou_Stagger;
|
|
float spacingValue = jiantou_Spacing;
|
|
if (jiantou_Hovered)
|
|
{
|
|
if (jiantou_Hover_Move_Duration > 0f)
|
|
{
|
|
duration = Mathf.Max(jiantou_Hover_Move_Duration, 0.01f);
|
|
}
|
|
if (jiantou_Hover_Stagger > 0f)
|
|
{
|
|
staggerValue = jiantou_Hover_Stagger;
|
|
}
|
|
if (jiantou_Hover_Spacing > 0f)
|
|
{
|
|
spacingValue = jiantou_Hover_Spacing;
|
|
}
|
|
}
|
|
for (int f = 0; f < jiantou_Flows.Count; f++)
|
|
{
|
|
JiantouFlow flow = jiantou_Flows[f];
|
|
if (flow == null || flow.template == null || flow.instances.Count == 0)
|
|
{
|
|
continue;
|
|
}
|
|
flow.basePos = flow.template.anchoredPosition;
|
|
flow.parent = flow.template.parent as RectTransform;
|
|
float parentHeight = Get_Rect_Height(flow.parent);
|
|
float fallbackHeight = Get_Rect_Height(content_Root);
|
|
if (parentHeight <= 0f || Mathf.Abs(flow.basePos.y) > parentHeight * 0.6f)
|
|
{
|
|
parentHeight = fallbackHeight;
|
|
}
|
|
if (parentHeight <= 0f)
|
|
{
|
|
parentHeight = Screen.height;
|
|
}
|
|
float rectHeight = Get_Rect_Height(flow.template);
|
|
float extra = Mathf.Max(jiantou_Move_Amplitude, 0f);
|
|
flow.endLimitY = flow.direction > 0f
|
|
? (parentHeight * 0.5f + rectHeight * 0.5f + extra)
|
|
: (-parentHeight * 0.5f - rectHeight * 0.5f - extra);
|
|
float distanceToEnd = Mathf.Abs(flow.endLimitY - flow.basePos.y);
|
|
flow.speed = distanceToEnd / duration;
|
|
float staggerTime = Mathf.Max(staggerValue, 0.01f);
|
|
float minSpacing = Mathf.Max(1f, rectHeight * 1.1f);
|
|
float targetSpacing = spacingValue > 0f ? spacingValue : minSpacing;
|
|
flow.spacing = Mathf.Max(minSpacing, targetSpacing);
|
|
float jitter = 0f;
|
|
flow.startY.Clear();
|
|
for (int i = 0; i < flow.instances.Count; i++)
|
|
{
|
|
RectTransform rect = flow.instances[i];
|
|
if (rect == null)
|
|
{
|
|
continue;
|
|
}
|
|
rect.gameObject.SetActive(true);
|
|
float startY = flow.basePos.y + jitter - flow.direction * flow.spacing * i;
|
|
rect.anchoredPosition = new Vector2(flow.basePos.x, startY);
|
|
flow.startY.Add(startY);
|
|
CanvasGroup group = Ensure_CanvasGroup(rect.gameObject);
|
|
if (group != null)
|
|
{
|
|
group.alpha = UnityEngine.Random.Range(jiantou_Alpha_Min, jiantou_Alpha_Max);
|
|
}
|
|
}
|
|
}
|
|
jiantou_Running = !jiantou_Require_Hover || jiantou_Hovered;
|
|
}
|
|
float Get_Rect_Width(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return 0f;
|
|
}
|
|
float width = rect.rect.width;
|
|
if (width <= 0f)
|
|
{
|
|
width = rect.sizeDelta.x;
|
|
}
|
|
return Mathf.Abs(width);
|
|
}
|
|
float Get_Rect_Height(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return 0f;
|
|
}
|
|
float height = rect.rect.height;
|
|
if (height <= 0f)
|
|
{
|
|
height = rect.sizeDelta.y;
|
|
}
|
|
return Mathf.Abs(height);
|
|
}
|
|
float Get_Rect_Area(RectTransform rect)
|
|
{
|
|
return Get_Rect_Width(rect) * Get_Rect_Height(rect);
|
|
}
|
|
void Add_Gyro_Target(RectTransform rect, float offsetWeight, float rotWeight, bool allowBG)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return;
|
|
}
|
|
if (Is_Top_Bottom_Related(rect))
|
|
{
|
|
return;
|
|
}
|
|
if (!allowBG && Is_BG_Related(rect))
|
|
{
|
|
return;
|
|
}
|
|
if (!allowBG && Is_Jiantou_Name(rect.name))
|
|
{
|
|
return;
|
|
}
|
|
if (!allowBG && Has_Jiantou_Descendant(rect))
|
|
{
|
|
return;
|
|
}
|
|
if (gyro_Offset_Weight_Map.ContainsKey(rect))
|
|
{
|
|
return;
|
|
}
|
|
gyro_Targets.Add(rect);
|
|
gyro_Offset_Weight_Map[rect] = Mathf.Clamp(offsetWeight, -2f, 2f);
|
|
gyro_Rot_Weight_Map[rect] = Mathf.Clamp(rotWeight, -2f, 2f);
|
|
}
|
|
float Get_Gyro_Weight(RectTransform rect, int index)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return 1f;
|
|
}
|
|
float min = Mathf.Min(gyro_All_Offset_Min, gyro_All_Offset_Max);
|
|
float max = Mathf.Max(gyro_All_Offset_Min, gyro_All_Offset_Max);
|
|
int seed = Stable_Hash(rect.name) + (index + 1) * 97;
|
|
float weight = Mathf.Lerp(min, max, Hash01(seed, 1));
|
|
if (content_Root != null)
|
|
{
|
|
float contentArea = content_Root.rect.width * content_Root.rect.height;
|
|
float rectArea = rect.rect.width * rect.rect.height;
|
|
if (contentArea > 1f && rectArea > 0f)
|
|
{
|
|
float size01 = Mathf.Clamp01(rectArea / contentArea);
|
|
float sizeFactor = Mathf.Lerp(1.25f, 0.75f, size01);
|
|
weight *= sizeFactor;
|
|
}
|
|
}
|
|
return Mathf.Clamp(weight, 0f, 2f);
|
|
}
|
|
bool Is_BG_Related(RectTransform rect)
|
|
{
|
|
if (rect == null || group_Background == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (rect == group_Background)
|
|
{
|
|
return true;
|
|
}
|
|
return rect.IsChildOf(group_Background);
|
|
}
|
|
bool Is_Top_Bottom_Related(RectTransform rect)
|
|
{
|
|
if (rect == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (group_Top != null && (rect == group_Top || rect.IsChildOf(group_Top)))
|
|
{
|
|
return true;
|
|
}
|
|
if (group_Bottom != null && (rect == group_Bottom || rect.IsChildOf(group_Bottom)))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
public class UI_ButtonTween : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler,
|
|
IPointerUpHandler, ISelectHandler, IDeselectHandler
|
|
{
|
|
float hoverScale = 1.04f;
|
|
float pressScale = 0.96f;
|
|
float hoverTime = 0.08f;
|
|
float pressTime = 0.06f;
|
|
float releaseTime = 0.12f;
|
|
Ease hoverEase = Ease.OutQuad;
|
|
Ease pressEase = Ease.OutQuad;
|
|
Ease releaseEase = Ease.OutBack;
|
|
Vector3 baseScale = Vector3.one;
|
|
Tween scaleTween;
|
|
bool pointerInside;
|
|
bool pointerDown;
|
|
bool selected;
|
|
|
|
public void ApplyConfig(float hoverScaleValue, float pressScaleValue, float hoverTimeValue, float pressTimeValue,
|
|
float releaseTimeValue, Ease hoverEaseValue, Ease pressEaseValue, Ease releaseEaseValue)
|
|
{
|
|
hoverScale = hoverScaleValue;
|
|
pressScale = pressScaleValue;
|
|
hoverTime = hoverTimeValue;
|
|
pressTime = pressTimeValue;
|
|
releaseTime = releaseTimeValue;
|
|
hoverEase = hoverEaseValue;
|
|
pressEase = pressEaseValue;
|
|
releaseEase = releaseEaseValue;
|
|
baseScale = transform.localScale;
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
baseScale = transform.localScale;
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
KillTween();
|
|
transform.localScale = baseScale;
|
|
pointerInside = false;
|
|
pointerDown = false;
|
|
selected = false;
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
KillTween();
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
pointerInside = true;
|
|
if (!pointerDown)
|
|
{
|
|
ApplyScale(hoverScale, hoverTime, hoverEase);
|
|
}
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
pointerInside = false;
|
|
if (!pointerDown && !selected)
|
|
{
|
|
ApplyScale(1f, hoverTime, hoverEase);
|
|
}
|
|
}
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
pointerDown = true;
|
|
ApplyScale(pressScale, pressTime, pressEase);
|
|
}
|
|
|
|
public void OnPointerUp(PointerEventData eventData)
|
|
{
|
|
pointerDown = false;
|
|
float target = (pointerInside || selected) ? hoverScale : 1f;
|
|
ApplyScale(target, releaseTime, releaseEase);
|
|
}
|
|
|
|
public void OnSelect(BaseEventData eventData)
|
|
{
|
|
selected = true;
|
|
if (!pointerDown)
|
|
{
|
|
ApplyScale(hoverScale, hoverTime, hoverEase);
|
|
}
|
|
}
|
|
|
|
public void OnDeselect(BaseEventData eventData)
|
|
{
|
|
selected = false;
|
|
if (!pointerDown && !pointerInside)
|
|
{
|
|
ApplyScale(1f, hoverTime, hoverEase);
|
|
}
|
|
}
|
|
|
|
void ApplyScale(float targetScale, float time, Ease ease)
|
|
{
|
|
KillTween();
|
|
scaleTween = transform.DOScale(baseScale * targetScale, Mathf.Max(time, 0.01f))
|
|
.SetEase(ease)
|
|
.SetUpdate(true);
|
|
}
|
|
|
|
void KillTween()
|
|
{
|
|
if (scaleTween != null)
|
|
{
|
|
scaleTween.Kill();
|
|
scaleTween = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class UI_RightButtonHover : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
|
{
|
|
float idleOffset = 60f;
|
|
float finalOffset = 0f;
|
|
float moveTime = 0.18f;
|
|
Ease moveEase = Ease.OutCubic;
|
|
float textFlashTime = 0.06f;
|
|
int textFlashCount = 2;
|
|
float textFlashInterval = 0.02f;
|
|
RectTransform imageRect;
|
|
Vector2 imageBasePos;
|
|
CanvasGroup imageGroup;
|
|
readonly List<CanvasGroup> textGroups = new();
|
|
Tween imageTween;
|
|
|
|
public void ApplyConfig(float idleOffsetValue, float finalOffsetValue, float moveTimeValue, Ease moveEaseValue,
|
|
float textFlashTimeValue, int textFlashCountValue, float textFlashIntervalValue)
|
|
{
|
|
idleOffset = Mathf.Max(0f, idleOffsetValue);
|
|
// Keep icon inside the button frame: positive config means "shift left by this amount".
|
|
// Use a softened offset so icon sits slightly more to the right.
|
|
finalOffset = -Mathf.Abs(finalOffsetValue) * 0.75f;
|
|
moveTime = Mathf.Max(0.01f, moveTimeValue);
|
|
moveEase = moveEaseValue;
|
|
textFlashTime = Mathf.Max(0.01f, textFlashTimeValue);
|
|
textFlashCount = Mathf.Max(1, textFlashCountValue);
|
|
textFlashInterval = Mathf.Max(0f, textFlashIntervalValue);
|
|
CacheTargets();
|
|
SetIdleState();
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
CacheTargets();
|
|
SetIdleState();
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
KillTweens();
|
|
}
|
|
|
|
void CacheTargets()
|
|
{
|
|
if (imageRect == null)
|
|
{
|
|
Transform imageChild = transform.Find("Image");
|
|
if (imageChild != null)
|
|
{
|
|
imageRect = imageChild as RectTransform;
|
|
}
|
|
}
|
|
if (imageRect != null)
|
|
{
|
|
imageBasePos = imageRect.anchoredPosition;
|
|
if (imageGroup == null)
|
|
{
|
|
imageGroup = imageRect.GetComponent<CanvasGroup>();
|
|
if (imageGroup == null)
|
|
imageGroup = imageRect.gameObject.AddComponent<CanvasGroup>();
|
|
}
|
|
}
|
|
textGroups.Clear();
|
|
for (int i = 0; i < transform.childCount; i++)
|
|
{
|
|
Transform child = transform.GetChild(i);
|
|
if (child == null)
|
|
{
|
|
continue;
|
|
}
|
|
string lower = child.name.ToLowerInvariant();
|
|
if (lower == "image" || lower == "boarder" || lower == "border")
|
|
{
|
|
continue;
|
|
}
|
|
Text uiText = child.GetComponent<Text>();
|
|
if (uiText != null)
|
|
{
|
|
CanvasGroup group = child.GetComponent<CanvasGroup>();
|
|
if (group == null)
|
|
{
|
|
group = child.gameObject.AddComponent<CanvasGroup>();
|
|
}
|
|
textGroups.Add(group);
|
|
continue;
|
|
}
|
|
Component tmp = child.GetComponent("TMP_Text");
|
|
if (tmp != null)
|
|
{
|
|
CanvasGroup group = child.GetComponent<CanvasGroup>();
|
|
if (group == null)
|
|
{
|
|
group = child.gameObject.AddComponent<CanvasGroup>();
|
|
}
|
|
textGroups.Add(group);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SetIdleState()
|
|
{
|
|
if (imageRect != null)
|
|
{
|
|
// Keep icon at its final position; only toggle visibility on hover.
|
|
imageRect.anchoredPosition = imageBasePos + Vector2.right * finalOffset;
|
|
}
|
|
if (imageGroup != null)
|
|
{
|
|
imageGroup.alpha = 0f; // hidden until hover
|
|
}
|
|
for (int i = 0; i < textGroups.Count; i++)
|
|
{
|
|
if (textGroups[i] != null)
|
|
{
|
|
// Text should always be visible (no flash-in).
|
|
textGroups[i].alpha = 1f;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
FlashImage();
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
HideImage();
|
|
}
|
|
|
|
void FlashImage()
|
|
{
|
|
if (imageRect == null || imageGroup == null)
|
|
{
|
|
return;
|
|
}
|
|
if (imageTween != null)
|
|
{
|
|
imageTween.Kill();
|
|
imageTween = null;
|
|
}
|
|
|
|
// Ensure icon is at its final position (no translation anim).
|
|
imageRect.anchoredPosition = imageBasePos + Vector2.right * finalOffset;
|
|
|
|
// Flash-in (blink) on hover, then stay visible.
|
|
imageGroup.alpha = 0f;
|
|
Sequence seq = DOTween.Sequence().SetUpdate(true);
|
|
for (int c = 0; c < textFlashCount; c++)
|
|
{
|
|
seq.Append(imageGroup.DOFade(1f, textFlashTime).SetEase(Ease.OutQuad));
|
|
seq.Append(imageGroup.DOFade(0f, textFlashTime).SetEase(Ease.InQuad));
|
|
if (textFlashInterval > 0f)
|
|
{
|
|
seq.AppendInterval(textFlashInterval);
|
|
}
|
|
}
|
|
seq.Append(imageGroup.DOFade(1f, textFlashTime).SetEase(Ease.OutQuad));
|
|
imageTween = seq;
|
|
}
|
|
|
|
void HideImage()
|
|
{
|
|
if (imageTween != null)
|
|
{
|
|
imageTween.Kill();
|
|
imageTween = null;
|
|
}
|
|
if (imageGroup != null)
|
|
{
|
|
imageGroup.alpha = 0f;
|
|
}
|
|
}
|
|
|
|
void KillTweens()
|
|
{
|
|
HideImage();
|
|
}
|
|
}
|
|
|
|
public class UI_JiantouHover : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
|
{
|
|
UI_Panel_Main main;
|
|
|
|
public void Bind(UI_Panel_Main target)
|
|
{
|
|
main = target;
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
if (main != null)
|
|
{
|
|
main.On_Jiantou_Hover_Enter();
|
|
}
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
if (main != null)
|
|
{
|
|
main.On_Jiantou_Hover_Exit();
|
|
}
|
|
}
|
|
}
|
|
|
|
public class UI_StartButtonHover : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
|
{
|
|
string offCn = "鎵ц浠诲姟";
|
|
string offEn = "Start";
|
|
string onCn = "鎰忓織澶嶆紨";
|
|
string onEn = "REITERATION OF WILL";
|
|
float charInterval = 0.03f;
|
|
Text cnText;
|
|
Text enText;
|
|
Component cnTmp;
|
|
Component enTmp;
|
|
Coroutine animateRoutine;
|
|
|
|
public void ApplyTexts(string offCnValue, string offEnValue, string onCnValue, string onEnValue)
|
|
{
|
|
offCn = offCnValue;
|
|
offEn = offEnValue;
|
|
onCn = onCnValue;
|
|
onEn = onEnValue;
|
|
CacheTexts();
|
|
SetText(offCn, cnText, cnTmp);
|
|
SetText(offEn, enText, enTmp);
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
CacheTexts();
|
|
SetText(offCn, cnText, cnTmp);
|
|
SetText(offEn, enText, enTmp);
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
if (animateRoutine != null)
|
|
{
|
|
StopCoroutine(animateRoutine);
|
|
animateRoutine = null;
|
|
}
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
if (animateRoutine != null)
|
|
{
|
|
StopCoroutine(animateRoutine);
|
|
}
|
|
animateRoutine = StartCoroutine(C_TypeTexts(onCn, onEn));
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
if (animateRoutine != null)
|
|
{
|
|
StopCoroutine(animateRoutine);
|
|
animateRoutine = null;
|
|
}
|
|
SetText(offCn, cnText, cnTmp);
|
|
SetText(offEn, enText, enTmp);
|
|
}
|
|
|
|
void CacheTexts()
|
|
{
|
|
if (cnText != null || cnTmp != null)
|
|
{
|
|
return;
|
|
}
|
|
Text[] texts = GetComponentsInChildren<Text>(true);
|
|
for (int i = 0; i < texts.Length; i++)
|
|
{
|
|
Text t = texts[i];
|
|
string lower = t.name.ToLowerInvariant();
|
|
if (lower.Contains("start") || lower.Contains("will") || lower.Contains("reiter"))
|
|
{
|
|
enText = t;
|
|
}
|
|
else
|
|
{
|
|
cnText = t;
|
|
}
|
|
}
|
|
Component[] tmps = GetComponentsInChildren<Component>(true);
|
|
for (int i = 0; i < tmps.Length; i++)
|
|
{
|
|
Component comp = tmps[i];
|
|
if (comp == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (!comp.GetType().Name.Contains("TMP_Text"))
|
|
{
|
|
continue;
|
|
}
|
|
string lower = comp.name.ToLowerInvariant();
|
|
if (lower.Contains("start") || lower.Contains("will") || lower.Contains("reiter"))
|
|
{
|
|
enTmp = comp;
|
|
}
|
|
else
|
|
{
|
|
cnTmp = comp;
|
|
}
|
|
}
|
|
}
|
|
|
|
IEnumerator C_TypeTexts(string targetCn, string targetEn)
|
|
{
|
|
bool cnDone = false;
|
|
bool enDone = false;
|
|
if (!string.IsNullOrEmpty(targetCn))
|
|
{
|
|
StartCoroutine(C_TypeText(targetCn, cnText, cnTmp, () => cnDone = true));
|
|
}
|
|
else
|
|
{
|
|
cnDone = true;
|
|
}
|
|
if (!string.IsNullOrEmpty(targetEn))
|
|
{
|
|
StartCoroutine(C_TypeText(targetEn, enText, enTmp, () => enDone = true));
|
|
}
|
|
else
|
|
{
|
|
enDone = true;
|
|
}
|
|
while (!cnDone || !enDone)
|
|
{
|
|
yield return null;
|
|
}
|
|
animateRoutine = null;
|
|
}
|
|
|
|
IEnumerator C_TypeText(string target, Text uiText, Component tmpText, Action onDone)
|
|
{
|
|
if (string.IsNullOrEmpty(target))
|
|
{
|
|
onDone?.Invoke();
|
|
yield break;
|
|
}
|
|
char[] chars = target.ToCharArray();
|
|
bool useDot = false;
|
|
for (int i = 0; i < chars.Length; i++)
|
|
{
|
|
if (chars[i] > 127)
|
|
{
|
|
useDot = true;
|
|
break;
|
|
}
|
|
}
|
|
string randomChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
for (int i = 0; i <= chars.Length; i++)
|
|
{
|
|
string prefix = new string(chars, 0, i);
|
|
string suffix = "";
|
|
if (i < chars.Length)
|
|
{
|
|
int remain = chars.Length - i;
|
|
char[] filler = new char[remain];
|
|
for (int r = 0; r < remain; r++)
|
|
{
|
|
filler[r] = useDot ? '.' : randomChars[(i + r) % randomChars.Length];
|
|
}
|
|
suffix = new string(filler);
|
|
}
|
|
SetText(prefix + suffix, uiText, tmpText);
|
|
yield return new WaitForSecondsRealtime(charInterval);
|
|
}
|
|
SetText(target, uiText, tmpText);
|
|
onDone?.Invoke();
|
|
}
|
|
|
|
void SetText(string value, Text uiText, Component tmpText)
|
|
{
|
|
if (uiText != null)
|
|
{
|
|
uiText.text = value;
|
|
return;
|
|
}
|
|
if (tmpText != null)
|
|
{
|
|
var prop = tmpText.GetType().GetProperty("text");
|
|
if (prop != null)
|
|
{
|
|
prop.SetValue(tmpText, value, null);
|
|
}
|
|
}
|
|
}
|
|
}
|