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.mzph.cn/web/45187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

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

作者&#xff1a;来自 Elastic Jeff Vestal, Jack Conradson 在 8.14 中&#xff0c;Elastic 在 Elasticsearch 中引入了一项名为 “retrievers - 检索器” 的新搜索功能。继续阅读以了解它们的简单性和效率&#xff0c;以及它们如何增强你的搜索操作。 检索器是 Elasticsearc…

知识图谱与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<…

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文件…

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…

音视频开发—使用FFmpeg将YUV文件编码成H264裸流文件 C语言实现

文章目录 1.准备工作2.压缩编码工作流程3.详细步骤1. 初始化日志和参数检查2. 输入/输出文件的打开3. 查找和初始化编码器4. 打开编码器5. 帧内存的分配和初始化6. 设置转换上下文&#xff08;SWS&#xff09;7. 读取和转换数据8. 编码过程9. 资源清理 4.完整示例代码 1.准备工…

熊海CMS漏洞练习平台的一次xss、sql注入、越权黑盒思路分析

简介 熊海CMS是由熊海开发的一款功能丰富的网站综合管理系统&#xff0c;广泛应用于个人博客、个人网站以及企业网站&#xff0c;本文章用于黑盒测试&#xff0c;如果需要「源码审计」后台回复【「CMS」】获取即可&#xff0c;精心准备了40多个cms源码漏洞平台&#xff0c;供宝…

在浏览器控制台中输出js对象,为什么颜色不同,有深有浅

打开console&#xff0c;输入自定义的javascript对象的时候&#xff0c;打开看发现对象的属性是深紫色&#xff0c;后面有一些对象是浅紫色的&#xff0c;比如Array对象和一堆SVG,HTML,CSS开头的对象&#xff0c;常用的prototype和__proto__也是浅紫色的。 请问这里深紫和浅紫…

什么是Maven以及如何配置Maven

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 文章目录 1.Maven1.1什么是Maven1.2Maven的好处1.3使用idea创建一个Maven项目1.4Maven的核心功能1.4.1项目构建 1.5Maven仓库1.5.2 中央仓库1.5.3 私有服务器(私服) 1.6Maven设置国内源 1.Mave…

[pytorch]常用函数(自用)

一、公共部分 1、torch.linespace 返回一维张量&#xff0c;在start和end之间&#xff08;包括start也包括end&#xff09;的均匀间隔的steps个点&#xff0c;长度为steps。 print(torch.linspace(1,10,3)) #输出tensor([ 1.0000, 5.5000, 10.0000]) print(torch.linspace…

文本分类--NLP-AI(八)

文本分类任务 任务简介1.字符数值化方式1方式2 2.池化&#xff08;pooling&#xff09;3.全连接层4.归一化函数&#xff08;Sigmoid&#xff09;5.总结 从任务抽象新的技术点Embedding层池化层 任务简介 任务介绍&#xff1a; 字符串分类&#xff0c;根据一句话的含妈量&#…

伊利25届校招24年社招网申入职北森测评题库全攻略!一文通!

伊利校招社招网申测评全攻略&#x1f680; 亲爱的求职小伙伴们&#xff0c;今天我要分享一份伊利校招社招网申测评的全攻略&#xff0c;希望能助你们一臂之力&#xff01; 测评概览 伊利的网申测评分为六个部分&#xff0c;总共约60分钟的答题时间&#xff0c;涵盖了言语逻辑、…

【微信小程序开发】如何定义公共的js函数,其它页面可以调用

在微信小程序开发中&#xff0c;可以通过以下步骤定义和使用公共的 JS 函数&#xff0c;使得其它页面可以调用&#xff1a; 1. 创建一个公共的 JS 文件&#xff1a;在项目的 utils 目录下创建一个 JS 文件&#xff0c;例如 utils/util.js。 2. 定义公共函数&#xff1a;在 uti…

在word中删除endnote参考文献之间的空行

如图&#xff0c;在References中&#xff0c;每个文献之间都有空行。不建议手动删除。打开Endnote。 打开style manager 删除layout中的换行符。保存&#xff0c;在word中更新参考文献即可。