升级内容主要是:
1、代码实现弹窗的打开与关闭
2、轮播图实现角度的变化
3、无限滚动图 边界外的添加与释放
实现代码如下:
1、基类脚本实现开关的调用继承
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ViveBase : MonoBehaviour { public virtual void Show() { gameObject.SetActive(true); } public virtual void Hide() { gameObject.SetActive(false ); } }
2、菜单脚本,添加触发的点击事件
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MenuPanel : ViveBase { public GonggaoPanel gonggaoPanel; public FriendsPanel friendsPanel; public TaskPanel taskPanel; public void OnBtnGonggaoClick() { gonggaoPanel.Show(); } public void OnBtnFriendsClick() { friendsPanel.Show(); } public void OnBtnTaskClick() { taskPanel.Show(); } }
3、其中一个界面挂载的脚本 继承与基类
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FriendsPanel : ViveBase { // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } }
4、轮播图 主要实现旋转角度
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RotationScaleScrollView : ScalePageScrollView { public float rotation; // 声明一个字段,旋转角度 protected override void Update() //用于监听角度 { base.Update(); ListenerItemRotation(); } public void ListenerItemRotation() { if (nextPage == lastPage) { return; } float percent = (rect.horizontalNormalizedPosition - pages[lastPage]) / (pages[nextPage] - pages[lastPage]); //5个好友 的旋转角度 if (nextPage > currentPage ) //判断是上一页还是下一页 { items[lastPage].transform.localRotation = Quaternion.Euler(-Vector3.Lerp(Vector3.zero, new Vector3(0, rotation, 0), percent)); //zero 到rotation 包装成一个角度,进行封装 ??? items[nextPage].transform.localRotation = Quaternion.Euler(Vector3.Lerp(Vector3.zero, new Vector3(0, rotation, 0), 1 - percent)); } else { items[lastPage].transform.localRotation = Quaternion.Euler(-Vector3.Lerp(Vector3.zero, new Vector3(0, rotation, 0), percent)); //zero 到rotation 包装成一个角度,进行封装 ??? items[nextPage].transform.localRotation = Quaternion.Euler(Vector3.Lerp(Vector3.zero, new Vector3(0, rotation, 0), 1 - percent)); } for (int i = 0; i < items.Length; i++) { if (i != lastPage && i != nextPage) { if (i < currentPage) //小于当前页 就说明是负的 { items[i].transform.localRotation = Quaternion.Euler(new Vector3(0, -rotation, 0)); } else if (i == currentPage) { //items[i].transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 0)); } else if (i > currentPage) { items[i].transform.localRotation = Quaternion.Euler(new Vector3(0, rotation, 0)); } } } } }
5、滚动图的边界以外任务条的添加与释放
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoopItem : MonoBehaviour { //通过一个方法,获取到边界的信息 private RectTransform rect; //rect 自己的显示区域 private RectTransform viewRect; //viewRect 是scrollview的显示区域 //声明四个边的坐标 private Vector3[] rectCorners; private Vector3[] viewCorners; #region 事件 public Action onAddHead; public Action onRemoveHead; public Action onAddLast; public Action onRemoveLast; #endregion //对两个变量初始化 private void Awake() { rect = transform.GetComponent<RectTransform>(); //通过transf.GetComponent 获取到自己的显示区域 viewRect = transform.GetComponentInParent<ScrollRect>().GetComponent<RectTransform>(); } void Update() { LinstenerCorners(); } //监听边界 public void LinstenerCorners() { //获取自身的边界 rect.GetWorldCorners(rectCorners); //获取显示区域的边界 viewRect.GetWorldCorners(viewCorners); if (IsFirst()) //如果是头 { if (rectCorners[0].y > viewCorners[1].y) { //把头节点给隐藏掉 if (onRemoveHead != null) { onRemoveHead(); } //如果它不为空,触发onRemoveHead } if (rectCorners[1].y < viewCorners[0].y) { //添加头节点 if (onAddHead != null) { onAddHead(); } } } if (IsLast()) //如果是尾 { //添加尾部 if (rectCorners[0].y > viewCorners[0].y) { if (onAddLast != null) { onAddLast(); } } //回收尾部 if (rectCorners[1].y < viewCorners[0].y) { if (onRemoveHead != null) { onRemoveHead(); } } } } //判断是不是第一个 public bool IsFirst() { for (int i = 0; i < transform.parent.childCount; i++) //计算子物体的数量,头部从0开始找 { if (transform.GetChild(i).gameObject.activeSelf) //依次获取子物体,并判断是否是显示状态 { if (transform.GetChild(i) == transform) //判断是不是它自己 { return true; } break; } } return false; } //是不是最后一个 public bool IsLast() { for (int i = transform.parent.childCount - 1; i >= 0; i--) //计算子物体的数量,尾部从后往前找 { if (transform.GetChild(i).gameObject.activeSelf) //依次获取子物体,并判断是否是显示状态 { if (transform.GetChild(i) == transform) //判断是不是它自己 { return true; } break; } } return false; } }
6、无限滚动 头和尾添加与释放的实现
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoopScrollView : MonoBehaviour { #region 字段 //这是一个预制体,通过对它(GameObject)实例化来创建它的子物体 public GameObject childItemPrefab; public GridLayoutGroup contentLayoutGroup; public ContentSizeFitter sizeFitter; public RectTransform content; #endregion #region Unity回调 //对字段进行初始化 private void Awake() { Init(); } private void Start() { //添加一个子节点 } #endregion #region 方法 //初始化 public void Init() { content = transform.Find("Viewport/Content").GetComponent<RectTransform>(); if (content == null) { throw new System.Exception(" content 初始化失败"); } contentLayoutGroup = content.GetComponent<GridLayoutGroup>(); if (contentLayoutGroup == null) { throw new System.Exception(" contentLayoutGroup 初始化失败"); } //判断是否获取到,若没有抛出异常 sizeFitter = content.GetComponent<ContentSizeFitter >(); if (sizeFitter == null) { throw new System.Exception(" sizeFitter 初始化失败"); } } //获取一个子节点 public GameObject GetChildItem() { //此原理为 对象池原理 //查找有没有 被回收 的子节点 (active 为 false 就是有被回收的子节点 ???) for (int i = 0; i < content.childCount ; i++) //for循环遍历出所有的子节点 { if (!content.GetChild(i).gameObject.activeSelf) { return content.GetChild(i).gameObject; } } //如果没有 创建一个 GameObject childItem = GameObject.Instantiate(childItemPrefab, content.transform); //实例化一个游戏物体 childItem.transform.localScale = Vector3.one; //简单设置数据 childItem.transform.localPosition = Vector3.zero; childItem.GetComponent<RectTransform>().anchorMin = new Vector2(0, 1); //设置锚点 childItem.GetComponent<RectTransform>().anchorMax = new Vector2(0, 1); childItem.GetComponent<RectTransform>().sizeDelta = contentLayoutGroup.cellSize; //子物体 设置宽高 LoopItem loopItem = childItem.AddComponent<LoopItem>(); loopItem.onAddHead += this.OnAddHead; loopItem.onRemoveHead += this.OnRemoveHead; loopItem.onAddLast += this.OnAddLast; loopItem.onRemoveLast += this.OnRemoveLast; return childItem ; } //在上面添加一个物体 public void OnAddHead() { } //移除当前最上面的物体 public void OnRemoveHead() { } //在最后加一个物体 public void OnAddLast() { } //移除最后一个物体 public void OnRemoveLast() { } #endregion }
暂时到这里 这个代码对于我这个初学者来说 着实是有点难了 每节课都要听两遍才差不多听懂,加油啊加油~
原文:https://www.cnblogs.com/gyjldlhiahia/p/14797243.html