unity 環形循環切換UI

環形ui管理器

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using System.Collections;
using Unity.VisualScripting;public class LevelSelector : MonoBehaviour
{public GameObject levelButtonPrefab; // 關卡按鈕的Prefabpublic Transform levelGroup;public int levelCount = 6; // 關卡數量public float radius = 300f; // 半徑public float moveDuration = 1f; // 移動持續時間public float yOffsetStep = 80f; // Y軸偏移步長public Button nextLevelButton;public Button previousLevelButton; private List<GameObject> levelButtons = new List<GameObject>();private List<float> yOffsets;private List<int> sortOrders;private float angleStep;private float currentAngle = 0f;void Start(){// 計算每個按鈕之間的角度angleStep = 360f / levelCount;// 自動計算對稱的Y軸偏移量yOffsets = CalculateSymmetricYOffsets(levelCount);// 初始化排序順序sortOrders = CalculateRenderingOrder(levelCount);// 創建關卡按鈕并設置它們的位置for (int i = 0; i < levelCount; i++){GameObject levelButton = Instantiate(levelButtonPrefab, levelGroup);levelButton.gameObject.name = i.ToString();levelButton.GetComponentInChildren<Text>().text = i.ToString();levelButton.GetComponent<LevelButton>().RegisterLevelSelector(this);levelButtons.Add(levelButton);}UpdateButtonPositions();if (nextLevelButton != null){nextLevelButton.onClick.AddListener(OnNextLevelButtonClicked);}if (previousLevelButton != null){previousLevelButton.onClick.AddListener(OnPreviousLevelButtonClicked); // 添加上一關按鈕的監聽器}}void UpdateButtonPositions(){for (int i = 0; i < levelButtons.Count; i++){float angle = (360f / levelButtons.Count) * i;float x = Mathf.Sin(angle * Mathf.Deg2Rad) * radius;float z = Mathf.Cos(angle * Mathf.Deg2Rad) * radius;// 獲取計算后的Y軸偏移float yOffset = yOffsets[i];// 設置按鈕位置RectTransform rectTransform = levelButtons[i].GetComponent<RectTransform>();rectTransform.anchoredPosition3D = new Vector3(x, yOffset, z);// 設置Canvas的sortingOrderCanvas canvas = levelButtons[i].GetComponent<Canvas>();canvas.sortingOrder = sortOrders[i];// 設置透明度和縮放值SetButtonAppearance(levelButtons[i], sortOrders[i]);}// 打印最上層和最下層按鈕的名稱PrintTopButtonName();PrintBottomButtonName();}void OnNextLevelButtonClicked(){RotateButtons(-1);}void OnPreviousLevelButtonClicked(){RotateButtons(1);}Coroutine moveCoroutine;public  void MoveLevelToBottom(int index){int bottomIndex = sortOrders.IndexOf(sortOrders.Count/2);int currentIndex =int.Parse(levelButtons[bottomIndex].name);bool isCounterclockwise = true;Debug.Log("當前顯示 "+currentIndex);int movesRequired =index - currentIndex;if (movesRequired < 0){isCounterclockwise=false;movesRequired = -movesRequired;}Debug.Log("需要偏移"+movesRequired);if (moveCoroutine != null){return;}moveCoroutine = StartCoroutine(MoveButtonCoroutine(movesRequired, isCounterclockwise));}IEnumerator MoveButtonCoroutine(int movesRequired ,bool isCounterclockwise){int t = 0;int diction = isCounterclockwise ? -1 : 1;while (movesRequired>t){RotateButtons(diction);Debug.Log("移動一次");yield return new WaitForSeconds(moveDuration);t++;}moveCoroutine = null;}void RotateButtons(int direction){nextLevelButton.interactable = false;previousLevelButton.interactable = false;List<Vector3> targetPositions = new List<Vector3>();List<float> targetYOffsets = new List<float>();List<int> newSortOrders = new List<int>();// 計算目標位置、Y軸偏移和順序for (int i = 0; i < levelButtons.Count; i++){int targetIndex = (i + direction + levelCount) % levelCount;float angle = currentAngle + angleStep * targetIndex;float x = Mathf.Sin(angle * Mathf.Deg2Rad) * radius;float z = Mathf.Cos(angle * Mathf.Deg2Rad) * radius;float yOffset = yOffsets[targetIndex];targetPositions.Add(new Vector3(x, yOffset, z));targetYOffsets.Add(yOffset);newSortOrders.Add(sortOrders[targetIndex]);}// 更新排序順序sortOrders = newSortOrders;for (int i = 0; i < levelButtons.Count; i++){Canvas canvas = levelButtons[i].GetComponent<Canvas>();canvas.sortingOrder = sortOrders[i];// 更新透明度和縮放值SetButtonAppearance(levelButtons[i], sortOrders[i]);}// 平滑移動并更新Y軸偏移和排序順序for (int i = 0; i < levelButtons.Count; i++){RectTransform rectTransform = levelButtons[i].GetComponent<RectTransform>();int index = i;// 平滑移動位置rectTransform.DOAnchorPos3D(targetPositions[i], moveDuration).OnComplete(() =>{// 更新Y軸偏移if (index < yOffsets.Count){yOffsets[index] = targetYOffsets[index];}if (index == levelButtons.Count - 1){Debug.Log("完成移動");// 重新啟用按鈕nextLevelButton.interactable = true;previousLevelButton.interactable = true;// 打印最上層和最下層按鈕的名稱PrintTopButtonName();PrintBottomButtonName();}});}// 更新角度currentAngle += angleStep * direction;}void PrintTopButtonName(){int topIndex = sortOrders.IndexOf(0); // 假設排序順序0是最上層if (topIndex >= 0 && topIndex < levelButtons.Count){string topButtonName = levelButtons[topIndex].name;Debug.Log("最上層按鈕的名稱: " + topButtonName);}}void PrintBottomButtonName(){int bottomIndex = sortOrders.IndexOf(sortOrders.Count/2);string bottomButtonName = levelButtons[bottomIndex].name;Debug.Log("最下層按鈕的名稱: " + bottomButtonName);}List<float> CalculateSymmetricYOffsets(int count){List<float> offsets = new List<float>();float step = yOffsetStep;int half = count / 2;float y = 0;for (int i = 0; i < count; i++){if (i != 0){y = i * step;if (i > half){y = (count - i) * step;}}offsets.Add(y);}return offsets;}List<int> CalculateRenderingOrder(int count){List<int> order = new List<int>();int middle = count / 2;int number = 0;for (int i = 0; i < count; i++){if (i <= middle){number = middle - i;}else{number = order[count - i];}order.Add(number);}return order;}void SetButtonAppearance(GameObject button, int sortOrder){float alpha = Mathf.Lerp(0.3f, 1f, (float)sortOrder / (levelCount / 2));float scale = Mathf.Lerp(0.8f, 1f, (float)sortOrder / (levelCount / 2));// 設置透明度CanvasGroup canvasGroup = button.GetComponent<CanvasGroup>();if (canvasGroup != null){canvasGroup.alpha = alpha;}// 設置縮放值RectTransform rectTransform = button.GetComponent<RectTransform>();if (rectTransform != null){rectTransform.localScale = new Vector3(scale, scale, scale);}}
}

關卡按鈕代碼

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class LevelButton : MonoBehaviour
{private LevelSelector levelSelector;[SerializeField]  private Button levelButton;public void RegisterLevelSelector(LevelSelector levelSelector){this.levelSelector = levelSelector;levelButton.onClick.AddListener(() =>{levelSelector.MoveLevelToBottom(int.Parse(gameObject.name));});}}

配置

如果關卡按鈕被背景遮住

給添加canvas組件,Overrider Sorting 打開 sort order 為-1

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/45187.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/45187.shtml
英文地址,請注明出處:http://en.pswp.cn/web/45187.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Elasticsearch:介紹 retrievers - 搜索一切事物

作者&#xff1a;來自 Elastic Jeff Vestal, Jack Conradson 在 8.14 中&#xff0c;Elastic 在 Elasticsearch 中引入了一項名為 “retrievers - 檢索器” 的新搜索功能。繼續閱讀以了解它們的簡單性和效率&#xff0c;以及它們如何增強你的搜索操作。 檢索器是 Elasticsearc…

Linux:解決vim打開文件默認為replace模式

現象 Ubuntu打開 vim 默認為 replace 模式 原因 終端的編碼設置與目標機器的編碼設置不同。 解決方案 修改 vim 配置文件( /etc/vim/vimrc或者~/.vimrc)&#xff0c;添加&#xff1a; set termencodingutf-8 set fileformatsunix set encodingprcP.S. vimrc 中注釋使用英…

知識圖譜與LLMs:實時圖分析(通過其關系的上下文理解數據點)

大型語言模型 (LLM) 極大地改變了普通人獲取數據的方式。不到一年前&#xff0c;訪問公司數據需要具備技術技能&#xff0c;包括熟練掌握各種儀表板工具&#xff0c;甚至深入研究數據庫查詢語言的復雜性。然而&#xff0c;隨著 ChatGPT 等 LLM 的興起&#xff0c;隨著所謂的檢索…

Ubuntu系統安裝mysql之后進行遠程連接

1.首先要配置數據庫允許進行遠程連接 1.1 打開MySQL配置文件 /etc/mysql/mysql.conf.d/mysqld.cnf sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf1.2 修改 bind-address 行 #按i進入插入模式 bind-address 0.0.0.0 #按 Esc 鍵退出插入模式。 #輸入:wq 然后按 Enter 保存并退…

React學習筆記02-----

一、React簡介 想實現頁面的局部刷新&#xff0c;而不是整個網頁的刷新。AJAXDOM可以實現局部刷新 1.特點 &#xff08;1&#xff09;虛擬DOM 開發者通過React來操作原生DOM&#xff0c;從而構建頁面。 React通過虛擬DOM來實現&#xff0c;可以解決DOM的兼容性問題&#x…

Window10下安裝WSL-Ubuntu20.04

1.開啟并更新WSL 1.1開啟WSL 首先先來看一下電腦是否能夠開啟WSL:待補充... 然后再來看一下如何開啟WSL:win->設置->應用->應用和功能->程序和功能&#xff0c;如下所示&#xff1a; 最后選擇啟用或關閉Windows功能&#xff0c;開啟兩個選項&#xff1a;1.Hyper-V…

工具推薦|語音輕松記筆記,AI幫你識別和潤色

# 你日常有沒有遇到這樣的場景&#xff1f; 偶爾有一些奇思妙想想要記錄下來&#xff0c;但沒有一個輕量的工具&#xff0c;往往會想著想著就把這個想法拋之腦后。特別是搞短視頻的&#xff0c;你也許希望把當時的想法錄下來&#xff0c;稍微剪輯下就能出一條不錯的口播視頻。…

springboot的JWT令牌

生成JWT令牌 依賴 <!--jwt令牌--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>javax.xml.bind<…

【LeetCode】最小棧

目錄 一、題目二、解法完整代碼 一、題目 設計一個支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常數時間內檢索到最小元素的棧。 實現 MinStack 類: MinStack() 初始化堆棧對象。 void push(int val) 將元素val推入堆棧。 void pop() 刪除堆棧頂部的元…

ACE之ACE_Handle_Set

簡介 ACE_Handle_Set是對select io復用中fd_set的封裝 結構 #mermaid-svg-dwnlrGqy52ds6ctC {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dwnlrGqy52ds6ctC .error-icon{fill:#552222;}#mermaid-svg-dwnlrGqy52…

微信小程序開發基礎知識6----使用npm包

一、小程序對npm的支持與限制 目前&#xff0c;小程序中已經支持使用 npm 安裝第三方包&#xff0c;從而來提高小程序的開發效率。但是&#xff0c;在小程序中使用npm 包有如下3個限制: ① 不支持依賴于 Node.js 內置庫的包 ② 不支持依賴于瀏覽器內置對象的包 ③ 不支持依賴于…

Java算法-力扣leetcode-209. 長度最小的子數組

209. 長度最小的子數組 給定一個含有 n ****個正整數的數組和一個正整數 target 。 找出該數組中滿足其總和大于等于 ****target ****的長度最小的 **** 子數組 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其長度 。 如果不存在符合條件的子數組&#xff0c;…

pico+unity預設配置

picosdk中有很多預設的配置、使用預設配置的方法有 1、創建 XR Origin、展開 XR Origin > Camera Offset&#xff0c;選中 LeftHand Controller。點擊 XR Controller (Action-Based) 面板右上角的 預設 按鈕 2、打開Assets\Samples\XR Interaction Toolkit\2.5.2\Starter A…

Linux--YUM倉庫部署及NFS共享存儲

目錄 一、YUM倉庫服務 1.1 YUM介紹 1.2 yum 常用的命令 1.3 YUM 源的提供方式 1.3.1 配置本地 yum 源倉庫 1.3.2 配置 ftp 源 1.3.3 配置http服務源 二、NFS 共享存儲 2.1 NFS基本概述 2.2 為什么使用 NFS 共享存儲 2.3 NFS 應用場景 2.4 NFS 實現原理 2.5 NFS文件…

配置提交節點

方法一&#xff1a;配置lsf.cluster.<clustername> 到$LSF_TOP/conf目錄&#xff0c;編輯lsf.cluster.<clustername>文件。將下面配置中的server列設置成0&#xff0c;此節點就會作為Login節點。此方法通過bhosts不可以查看到這個節點。 # cd $LSF_ENVDIR# vim l…

gitlab 搭建使用

1. 硬件要求 ##CPU 4 核心500用戶 8 核心1000用戶 ##內存 4 G內存500用戶 8 G內存1000用戶 2. 下載 鏈接 3. 安裝依賴 yum -y install curl openssh-server postfix wget 4. 安裝gitlab組件 yum -y localinstall gitlab-ce-15.9.3-ce.0.el7.x86_64.rpm 5. 修改配置文…

Qt Quick qml自定義控件:qml實現電池控件

qml入門進階專欄地址:https://blog.csdn.net/yao_hou/category_9951228.html?spm=1001.2014.3001.5482 本篇博客介紹如何使用qml來實現電池控件,效果圖如下: 下面給出實現代碼 Battery.qml /*電池組件*/import QtQuick 2.15 import QtQuick.Controls 2.15Rectangle {id: b…

實驗05 單元測試

知識點 單元測試的定義 單元測試&#xff08;Unit Testing&#xff09;是一種軟件開發的驗證過程&#xff0c;旨在隔離并檢測軟件組件&#xff08;通常是函數、方法或類&#xff09;的單個單元的功能是否按照預期執行。每個測試用例驗證特定的條件或功能&#xff0c;確保代碼的…

Apache Kylin: 大數據時代的分析引擎

在大數據時代&#xff0c;企業面臨著數據量激增的挑戰&#xff0c;傳統的數據分析方法已經無法滿足快速、高效的處理需求。Apache Kylin作為開源的分布式分析引擎&#xff0c;為超大規模數據集提供了快速的洞察能力。本文將介紹Kylin的基本概念、架構、特性以及如何部署和使用K…

音視頻開發—使用FFmpeg將YUV文件編碼成H264裸流文件 C語言實現

文章目錄 1.準備工作2.壓縮編碼工作流程3.詳細步驟1. 初始化日志和參數檢查2. 輸入/輸出文件的打開3. 查找和初始化編碼器4. 打開編碼器5. 幀內存的分配和初始化6. 設置轉換上下文&#xff08;SWS&#xff09;7. 讀取和轉換數據8. 編碼過程9. 資源清理 4.完整示例代碼 1.準備工…