首页 > 其他 > 详细

模仿小demo 2.0

时间:2021-05-21 22:30:14      阅读:28      评论:0      收藏:0      [点我收藏+]

升级内容主要是:

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
}

 

 

暂时到这里    这个代码对于我这个初学者来说  着实是有点难了    每节课都要听两遍才差不多听懂,加油啊加油~

模仿小demo 2.0

原文:https://www.cnblogs.com/gyjldlhiahia/p/14797243.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!