using System; using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UIElements; /* 本文件控制游戏右侧的菜单按键逻辑 */ public class MenuController : MonoBehaviour { // Start is called once before the first execution of Update after the MonoBehaviour is created private VisualElement mainMenu; private List subMenus = new(); //private bool isSubMenuShow = false; private GameObject uiPlaceholder; // Manu会控制其他子菜单显示和隐藏,因此所有子菜单都必须挂载在UI Placeholder下 private GameObject vamUI; // vamUI = Voice and Manu UI; private GameObject shoppingUI, statusUI, warehouseUI; // 对应点击菜单后展开的几个子菜单 void OnEnable() { Debug.Log("manu controller start"); uiPlaceholder = GameObject.Find("UI Placeholder"); vamUI = uiPlaceholder.transform.Find("VoiceAndMenu").gameObject; shoppingUI = uiPlaceholder.transform.Find("ShoppingUI").gameObject; statusUI = uiPlaceholder.transform.Find("Status").gameObject; warehouseUI = uiPlaceholder.transform.Find("Warehouse").gameObject; var root = GetComponent().rootVisualElement; var menuArea = root.Q("menuArea"); mainMenu = menuArea.Q("mainMenu"); var home = menuArea.Q("home"); subMenus.Add(home); var playground = menuArea.Q("playground"); subMenus.Add(playground); var shop = menuArea.Q("shop"); subMenus.Add(shop); var warehouse = menuArea.Q("warehouse"); subMenus.Add(warehouse); var cameraBtn = menuArea.Q("camera"); subMenus.Add(cameraBtn); var status = menuArea.Q("status"); subMenus.Add(status); mainMenu.RegisterCallback(e => MainMenuClick(e)); // root加载完成后,所有element算出位置后再进行计算 root.RegisterCallback(e => OnMainMenuClickGeometryChanged(e)); // 绑定按键点击事件 playground.RegisterCallback(e => PlayGroundClick(e)); shop.RegisterCallback(e => ShopClick(e)); warehouse.RegisterCallback(e => WarehouseClick(e)); status.RegisterCallback(e => StatusClick(e)); cameraBtn.RegisterCallback(e => CameraClick(e)); } private void OnDisable() { subMenus.Clear(); // 因为启动时候调用OnEable数据会被重复加载 } // Update is called once per frame void Update() { CollapseMenuCheck(); } Vector2 CalcPosition(Vector2 curPosition, float angle, float distance) { float radians = angle * Mathf.Deg2Rad; float x = curPosition.x + distance * Mathf.Cos(radians); float y = curPosition.y - distance * Mathf.Sin(radians); Vector2 newPosition = new Vector2(x, y); return new Vector2(x, y); } // 初始化所有按键的位置 void InitialSubMenu() { foreach (var subMenu in subMenus) { subMenu.style.left = mainMenu.resolvedStyle.left; subMenu.style.top = mainMenu.resolvedStyle.top; subMenu.visible = false; } } // 点击主按键后所有子按键展开并显示 void MainMenuClick(ClickEvent evt) { if (MenuData.isMenuShowed) { MenuReset(); return; } // curAngle 初始角度,angleDelta 2个子菜单之间角度,distance 弹出距离,showTimer 显示时间 float curAngle = 75f; float angleDelta = 40f; float distance = 70f; //float showTimer = 3.0f; foreach (var subMenu in subMenus) { subMenu.visible = true; var newPosition = CalcPosition(mainMenu.layout.position, curAngle, distance); //subMenu.layout.position.Set(newPosition.x, newPosition.y); subMenu.style.left = newPosition.x; subMenu.style.top = newPosition.y; if (subMenu.name == "home") { Debug.Log(subMenu.name + " " + newPosition.x + " " + newPosition.y); } curAngle += angleDelta; } mainMenu.transform.scale = new Vector2(0.8f, 0.8f); //Invoke("MenuReset", showTimer); //isSubMenuShow = true; MenuData.isMenuShowed = true; MenuData.menuShowTime = DateTime.Now; } // 初始化后屏幕尺寸变化时候调用。在此处应用于第一次屏幕初始化完成。 void OnMainMenuClickGeometryChanged(GeometryChangedEvent evt) { //VisualElement targetElement = evt.target as VisualElement; InitialSubMenu(); } void MenuReset() { //yield return new WaitForSeconds(3.0f); mainMenu.transform.scale = new Vector2(1.0f, 1.0f); MenuData.isMenuShowed = false; InitialSubMenu(); } void PlayGroundClick(ClickEvent evt) { SceneManager.LoadScene("Playground", LoadSceneMode.Single); } void ShopClick(ClickEvent evt) { vamUI.SetActive(false); shoppingUI.SetActive(true); } void WarehouseClick(ClickEvent evt) { vamUI.SetActive(false); warehouseUI.SetActive(true); } void StatusClick(ClickEvent evt) { vamUI.SetActive(false); statusUI.SetActive(true); } void CameraClick(ClickEvent evt) { } // 菜单打开后收回菜单 void CollapseMenuCheck() { if (MenuData.isMenuShowed) { // 计算两个时间点之间的差值 TimeSpan difference = DateTime.Now - MenuData.menuShowTime; // 检查差值是否超过3秒 if (difference.TotalSeconds > 3) { MenuReset(); } } } } public static class MenuData { public static bool isMenuShowed = false; public static DateTime menuShowTime; }