首先贴效果:

1.动态设置gridLayout的大小
核心组件为rectTransform,核心属性一个为rectTransform.anchoredPosition,用来设置和锚点的距离,否则只设置宽高会导致grid只以锚点(一般为居中)为中心扩展。第二个核心属性为rectTransform.sizeDelta,用于设置控件的宽度和高度。实现起来很简单,只要获得放进去的图片的宽高然后乘以总数就能得到滑动框的总宽高。

boardBtns.GetComponent<RectTransform>().anchoredPosition = new Vector2(posX*(num-1),0);
boardBtns.GetComponent<RectTransform>().sizeDelta = new Vector2(width*num, boardBtns.GetComponent<RectTransform>().rect.height);

boardBtns为含有gridLayout组件的控件,即所有公告的父物体。

2.定时滑动公告板的实现
实现这个核心组件为scrollrect,核心属性scrollrect.horizontalNormalizedPosition
这个值返回一个0-1的浮点数,实验一下就知道这个能用来控制滑动框划到哪里,值越小越接近起点。
以及需要继承Unity事件的拖动接口,分别为IBeginDragHandler和IEndDragHandler(IDragHandler用于拖动时监测事件,不过感觉它没什么用就没有实现)
同时需要设置一个核心变量,表示现在滑动到第几页,我取名为currIndex,滑动到currIndex页(从0开始)时上述scrollrect.horizontalNormalizedPosition的值为currIndex * ((float)1 / (num - 1)))

 public void OnBeginDrag(PointerEventData eventData)//记录起始位置{lastX = sr.horizontalNormalizedPosition;}public void OnEndDrag(PointerEventData eventData)//滑动结束,根据判断的方向设置index的加减然后根据index的值朝某个方向滑动{if (Mathf.Abs(lastX- sr.horizontalNormalizedPosition)>=0.01f){if (lastX < sr.horizontalNormalizedPosition)//向左划{if (currIndex<num-1){currIndex++;StopAllCoroutines();//一定要停止协程!!否则会导致协程重复执行,滑动框会乱划StartCoroutine(MoveTo(currIndex * ((float)1 / (num - 1))));}}else if (lastX > sr.horizontalNormalizedPosition)//向右划{if (currIndex >0){currIndex--;StopAllCoroutines();StartCoroutine(MoveTo(currIndex * ((float)1 / (num - 1))));}}}}

接下来实现利用协程平滑移动公告板的功能,主要使用Mathf.Lerp插值函数。

IEnumerator MoveTo(float targetX){while (true){if (Mathf.Abs(sr.horizontalNormalizedPosition - targetX) >= 0.01f)//未到时滑动{sr.horizontalNormalizedPosition = Mathf.Lerp(sr.horizontalNormalizedPosition, targetX,Time.deltaTime * (Mathf.Abs(currIndex - lastIndex)*10));}else//停止{sr.horizontalNormalizedPosition = targetX;lastIndex = currIndex;toggles[currIndex].isOn = true;timer = 0;canSlide = true;break;}yield return null;}}

接下来实现点击toggle跳转到对应的页面,场景中公告板上需要添加toggleGroup组件然后设置每个toggle的group为这个toggleGroup,然后为toggle的值改变事件添加监听事件,主要改变currIndex的值,和toggle数组的i一一对应。

bt.onValueChanged.AddListener((bool isOn)=> { OnboardToggleClick(isOn,bt); });
void OnboardToggleClick(bool isOn,Toggle t){for (int i = 0; i < toggles.Length; i++){if (toggles[i].isOn) { currIndex = i; break; }}StopAllCoroutines();StartCoroutine(MoveTo(currIndex * ((float)1 / (num - 1))));}

最后实现定时的功能,其实也就是设置一个定时器定时使currIndex循环增加,然后开启移动协程。

void Update () {timer += Time.deltaTime;if (timer>=6 && canSlide)//6s滑动一次{canSlide = false;if (currIndex < num-1) currIndex++;else currIndex = 0;StopAllCoroutines();StartCoroutine(MoveTo(currIndex * ((float)1 / (num-1))));}}

最后贴上整个脚本的代码,我写了两个场景,可复用。别的操作大多是给Image和Text赋值还有给Button添加监听事件,这个可以自由发挥。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;public class OnBoard : MonoBehaviour,IBeginDragHandler,IEndDragHandler{float posX;//board偏移量float width;//board宽度float height;//board高度Transform boardBtns;ScrollRect sr;Transform boardToggles;int num;//the count of boardsToggle[] toggles;string[] boardTexts;Sprite[] boardImages;int lastIndex;//上次索引(toggle)int currIndex;//现在索引float lastX;//上次sr位置float timer;bool canSlide = true;//timer to auto slide// Use this for initializationvoid Start () {switch (SceneManager.GetActiveScene().name){case "Main":num = 4;boardImages = new Sprite[num];boardImages = Resources.LoadAll<Sprite>("Background");boardTexts = new string[]{ "Battle", "Heroes", "Room", "Summon" };break;case "Summon":num = 3;boardImages = new Sprite[num];boardImages = Resources.LoadAll<Sprite>("Summon");boardTexts = new string[num];break;default:break;}toggles = new Toggle[num];boardBtns = transform.Find("boardBtns");sr = GetComponent<ScrollRect>();boardToggles = transform.Find("boardToggles");width = boardBtns.GetComponent<RectTransform>().sizeDelta.x;height= boardBtns.GetComponent<RectTransform>().sizeDelta.y;posX = width / 2;boardBtns.GetComponent<RectTransform>().anchoredPosition = new Vector2(posX*(num-1),0);boardBtns.GetComponent<RectTransform>().sizeDelta = new Vector2(width*num, boardBtns.GetComponent<RectTransform>().rect.height);//instantiate btns and togglesfor (int i = 0; i < num; i++){//btnsGameObject boardBtn = Instantiate((GameObject)GameFuncs.GetResource("Prefabs/boardBtn"));boardBtn.GetComponent<RectTransform>().sizeDelta = new Vector2(width, height);boardBtn.transform.SetParent(boardBtns);boardBtn.GetComponent<Image>().sprite = boardImages[i];boardBtn.GetComponentInChildren<Text>().text = boardTexts[i];boardBtn.GetComponent<Button>().onClick.AddListener(()=> { OnboardBtnClick(boardBtn.GetComponentInChildren<Text>().text); });//togglesGameObject boardToggle = Instantiate((GameObject)GameFuncs.GetResource("Prefabs/boardToggle"));boardToggle.transform.SetParent(boardToggles);Toggle bt = boardToggle.GetComponent<Toggle>();bt.group = boardToggles.GetComponent<ToggleGroup>();if (i == 0) bt.isOn = true;bt.onValueChanged.AddListener((bool isOn)=> { OnboardToggleClick(isOn,bt); });toggles[i] = bt;}}// 定时滚动void Update () {timer += Time.deltaTime;if (timer>=6 && canSlide)//6s滑动一次{canSlide = false;if (currIndex < num-1) currIndex++;else currIndex = 0;StopAllCoroutines();StartCoroutine(MoveTo(currIndex * ((float)1 / (num-1))));}}void OnboardBtnClick(string boardStr){switch (SceneManager.GetActiveScene().name){case "Main":GameFuncs.GoToSceneAsync(boardStr);break;case "Summon":break;default:break;} }void OnboardToggleClick(bool isOn,Toggle t){for (int i = 0; i < toggles.Length; i++){if (toggles[i].isOn) { currIndex = i; break; }}StopAllCoroutines();StartCoroutine(MoveTo(currIndex * ((float)1 / (num - 1))));}public void OnBeginDrag(PointerEventData eventData){lastX = sr.horizontalNormalizedPosition;}public void OnEndDrag(PointerEventData eventData)//toggle change ison{if (Mathf.Abs(lastX- sr.horizontalNormalizedPosition)>=0.01f){if (lastX < sr.horizontalNormalizedPosition)//向左划{if (currIndex<num-1){currIndex++;StopAllCoroutines();StartCoroutine(MoveTo(currIndex * ((float)1 / (num - 1))));}}else if (lastX > sr.horizontalNormalizedPosition)//向右划{if (currIndex >0){currIndex--;StopAllCoroutines();StartCoroutine(MoveTo(currIndex * ((float)1 / (num - 1))));}}}}IEnumerator MoveTo(float targetX){while (true){if (Mathf.Abs(sr.horizontalNormalizedPosition - targetX) >= 0.01f){sr.horizontalNormalizedPosition = Mathf.Lerp(sr.horizontalNormalizedPosition, targetX,Time.deltaTime * (Mathf.Abs(currIndex - lastIndex)*10));}else{sr.horizontalNormalizedPosition = targetX;lastIndex = currIndex;toggles[currIndex].isOn = true;timer = 0;canSlide = true;break;}yield return null;}}
}

unity中定时滑动公告板的实现及动态设置gridLayout的大小相关推荐

  1. WPF中GDI+图形图像的绘制:(一)绘制文本——动态设置字体、大小、颜色

    GDI+(Graphics Device Interface Plus图形设备接口加)是.NET框架的重要组成部分,负责在屏幕和打印机上绘制图形图像和显示信息.GDI+不但在功能上比GDI 要强大很多 ...

  2. unity中手指滑动事件

    using UnityEngine; using System.Collections;public class jarodInputController : MonoBehaviour {priva ...

  3. echarts画布_vue中动态设置echarts画布大小

    Yii2 使用Composer composer 是 PHP 用来管理依赖(dependency)关系的工具.你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer 会帮你 ...

  4. java中的布局文件改成,Android 动态设置布局文件的exception

    错误信息: java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to andro ...

  5. Quartz在Spring中动态设置cronExpression

    什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定). 这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文 ...

  6. Quartz在Spring中动态设置cronExpression (spring设置动态定时任务)

    2019独角兽企业重金招聘Python工程师标准>>> 什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定). 这样总不能修改 ...

  7. Unity中常用的单例模式、对象池的脚本模板,连按退出和滑动翻页或放大缩小的功能实现,以及属性在代码中的灵活使用

    1.单例模式的脚本模板: Unity中针对一些常用的manager可以使用单例模式,用于统一的功能管理: //普通单例,不需要继承MonoBehavior,不用挂载在GameObject上 publi ...

  8. 【Unity3D日常开发】Unity中的资源加载与文件路径

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  9. Unity中单点和多点触控

    Input.touchCount获取当前的触摸点数目,若为1则是单点触控,大于1则是多点触控 点击事件用:Input.GetTouch(num).phase== TouchPhase.Began这样的 ...

最新文章

  1. 阿里工作流引擎_免费开源,一款快速开发模块化脚手架,含工作流引擎
  2. 互联网金融风控面试算法知识(三)
  3. Maven远程仓库:pom依赖以及jar包下载
  4. java界面 文件选择器_掌握java技术 必备java工具应用知识
  5. 双机热备_什么是高可用双机热备?双机热备概念原理详解
  6. java hasnextdouble_scanner.nextInt()与scanner.nextDouble
  7. FoundationDB 开源文档数据库模型 Document Layer​​​​​​​
  8. Spring.NET学习笔记16——事务管理(应用篇) Level 200
  9. Eclipse Class Decompiler——Java反编译插件
  10. U盘无法格式化,变成8M,RAW格式,0字节的U盘修复教程
  11. 国家企业信用信息公示系统爬取
  12. 数据恢复工具(minitool power data recovery 8) v8.8(含64位32位)
  13. 友链导航源码php,2020优化版导航源码自动收录秘趣导航批量检查友链有效性导航源码...
  14. 情侣天气推送升级简单版 项目上传github实现定时自动推送教程
  15. idea修改主题和更换背景
  16. 主干开发(Trunk-based development)
  17. 2.19 serenity
  18. 蓝牙耳机蓝牙音箱出口加拿大亚马逊ICID认证周期费用
  19. 【微软算法面试高频题】可怜的小猪
  20. 【IJCAI 2016】Modularity Based Community Detection with Deep Learning 阅读小记

热门文章

  1. mmdetection训练报错
  2. windows之 访问控制模型
  3. Windows病毒源码
  4. 利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解
  5. 武汉出租车集体罢工 是打车软件的错?
  6. MapReduce之FileInputFormat切片机制
  7. CSMA/CD与CSMA/CA比较
  8. 服务没有及时响应启动或控制请求
  9. dalek-cryptography/zkp——基于merlin的Schnorr零知识证明
  10. WPF Textbox自动换行