Unity中关于ScrollRect组件完整解决方案(ScrollRect中元素自动排版+ScrollRect中元素自动定位到Viewport可见范围内)

这个教程可以实现点击我这个视频中所示的效果

一、元素自动排版功能

1、首先要往我们的unity项目中导入两个脚本文件,脚本文件名称分别是UIScrollEventListener和CZScrollRect,这两个脚本文件代码如下所示。

1-1、介绍UIScrollEventListener脚本写法。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class UIScrollEventListener : MonoBehaviour, IBeginDragHandler, IEndDragHandler , IPointerUpHandler, IPointerDownHandler , IDragHandler
{
   
    public delegate void VoidDelegate(PointerEventData pdata);
    public VoidDelegate onBeginDrag;
    public VoidDelegate onEndDrag;
    public VoidDelegate onUp;
    public VoidDelegate onDown;
    public VoidDelegate onDrag;
    bool isDrag = false;
    List<Image> registers = new List<Image>();

    public static UIScrollEventListener Get(GameObject go)
    {
   
        UIScrollEventListener listener = go.GetComponent<UIScrollEventListener>();
        if (listener == null) listener = go.AddComponent<UIScrollEventListener>();
        return listener;
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
   
        isDrag = true;
        if (onBeginDrag != null) onBeginDrag(eventData);
    }

    public void OnEndDrag(PointerEventData eventData)
    {
   
        isDrag = false;
        if (onEndDrag != null) onEndDrag(eventData);
    }

    public void OnPointerUp(PointerEventData eventData)
    {
   
        if (!isDrag) {
   

            SetRegisterEvent(true);
            PraseObject(eventData);
            SetRegisterEvent(false);
        }
        if (onUp != null) onUp(eventData);
    }

    public void OnPointerDown(PointerEventData eventData)
    {
   
        if (onDown != null) onDown(eventData);
    }

    public void OnDrag(PointerEventData eventData) {
   

        if (onDrag != null) onDrag(eventData);
    }

    public void RegisterButton(GameObject go)
    {
   
        Image img = go.GetComponent<Image>();
        if (img != null)
        {
   
            img.raycastTarget = false;
            registers.Add(img);
        }
    }

    void SetRegisterEvent(bool b) {
   

        if (registers.Count > 0)
        {
   
            for (int i = 0; i < registers.Count; ++i)
            {
   
                registers[i].raycastTarget = b;
            }
        }
    }

    void PraseObject(PointerEventData eventData) {
   

        if (registers.Count > 0)
        {
   
            for (int i = 0; i < registers.Count; ++i)
            {
   
                if (EventSystem.current != null)
                {
   
                    List<RaycastResult> result = new List<RaycastResult>();
                    EventSystem.current.RaycastAll(eventData, result);
                    foreach (RaycastResult r in result)
                    {
   
                        //Debug.Log(r.gameObject.name);
                        foreach (Image img in registers)
                        {
   

                            if (img.gameObject.Equals(r.gameObject))
                            {
   

                                InputField inputfield = img.gameObject.GetComponent<InputField>();
                                if (inputfield != null) inputfield.ActivateInputField();
                            }

                        }
                    }
                }
            }
        }
    }

}
1-2、介绍CZScrollRect脚本写法。
using System;
using UnityEngine;
using UnityEngine.UI;

public class ScrollObj
{
   
    public GameObject obj;
    public int dex;
}

public class CZScrollRect
{
   

    public enum TipType
    {
   
        UNDO_REFRESH = 0,
        PULL_REFRESH = 1,
        UNDO_APPEND = 2,
        PULL_AAPEND = 3,
        NODATA = 4,
        NONE = 5
    }

    const int OPEAT_HEIGHT = 100;//高度差判断操作类型
    const int INIT_NUM_LIMIT = 8;//列表实例化个数

    public delegate void OperatDelegate();
    public delegate void OperatObjDelegate(GameObject obj , int index);
    public delegate void OperatTextObjDelegate(GameObject obj, TipType t);
    public OperatDelegate onRefresh;//下拉刷新时回调
    public OperatDelegate onAppend;//需要加载更多时回调
    public OperatObjDelegate onScrollObj;//需刷新时回调
    public OperatTextObjDelegate onUpdateTextObj;//需刷新文本状态时回调

    public ScrollRect scrollRect;//ScrollRect
    private RectTransform scrollRectContent;//RectTransform
    public GameObject prefab;//实例化的对象
    public GameObject text_up;//下拉刷新文本
    public GameObject text_down;//上拉加载更多文本

    TipType textup_status;

    int opeartLen = 0;//记录总长度
    public int layoutwidth = 1242;//填写item的长度
    public int limitNum = 8;//列表实例化个数
    public float interval = 200;//每个item的高度
    public float spacing = 5;//每个tiem的间隔

    ScrollObj[] list;//用于管理生成的对象
    int opeartType;
    int pageindex;//页码
    bool bHasMore;//是否能加载更多
    int halfWidth;

    //
    public GameObject batchContent;

    public CZScrollRect()
    {
   
        opeartType = -1;
        hasMore = false;
    }

    /// 
    /// 用于控制scrollrect是否能够滑动
    /// (用于等待网络请求等业务)
    /// 
    public bool vertical
    {
   
        get{
   
            return scrollRect.vertical;
        }set{
   
            scrollRect.vertical = value;
        }
    }

    /// 
    /// 是否存在更多
    /// 
    public bool hasMore
    {
   
        get{
   
            return bHasMore;
        }set{
   
            bHasMore = value;
        }
    }

    /// 
    /// 获取对象所在的索引
    /// 
    /// 
    /// 
    public int GetObjIndex(GameObject obj) {
   

        for(int i = 0; i < list.Length; ++i)
        {
   
            if (obj.Equals(list[i].obj))
            

你可能感兴趣的:(Unity,unity,游戏引擎,前端,游戏,ScrollRect)