VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > c#编程 >
  • Unity ScrollView实现自动吸附效果

这篇文章主要为大家详细介绍了Unity ScrollView实现自动吸附效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

 

本文实例为大家分享了Unity ScrollView实现自动吸附效果的具体代码,供大家参考,具体内容如下

一、效果演示

二、实现思路

通过使用UGUI的拖拽接口,在拖拽结束时比较当前滑动框的NormalizedPositon与每一页的NormalizedPositon值,找到距离当前拖拽结束位置最近的页并缓慢滑动过去

三、使用说明

——此功能脚本是对ScrollView的扩展,所以必须添加UGUI提供的基础Scroll View
——Content上必须添加GridLayoutGroup组件并添加所有列表中的项(不是动态添加),只是为了方便满足布局需求(我在代码中对startCorner、startAxis、childAlignment和constraintCount进行了限制,不需要对其设置)
——不能添加Content Size Fitter组件
——测试出适合的视为滑动一页的距离和视为滑动多页的距离数值并填入即可

四、完整代码

将AutoAdsorbScrollView脚本挂载到ScrollView上

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

using UnityEngine;

using UnityEngine.UI;

using UnityEngine.EventSystems;

 

/// <summary>

/// 自动吸附的滑动列表

/// </summary>

public class AutoAdsorbScrollView : MonoBehaviour, IBeginDragHandler, IEndDragHandler

{

    private ScrollRect scrollRect;//滑动框组件

    private RectTransform content;//滑动框的Content

    private GridLayoutGroup layout;//布局组件

 

    private int totalPage; //总页数

    private int curPage; //当前页的下标

    private float[] eachPageNUPos; //每页的NormalizedPositon的值

    private float targetNUPos; //目标页的NormalizedPositon的值

 

    private Vector2 beginMousePos; //鼠标开始按下的位置

    private Vector2 endMousePos; //鼠标结束按下的位置

    private bool isDrag; //是否在拖拽

 

    [Header("是否可以滑动多页")]

    public bool sliderMultPage;

 

    [Header("视为滑动一页的距离")]

    [Space(25)]

    public float sliderOnePageDis;

    [Header("视为滑动多页的距离")]

    public float sliderMultPageDis;

    [Header("缓动到目标页的持续时间")]

    public float duration;

 

    #region Init

 

    private void Awake()

    {

        scrollRect = GetComponent<ScrollRect>();

        content = scrollRect.content;

        layout = content.GetComponent<GridLayoutGroup>();

 

        Init();//初始化

    }

 

    /// <summary>

    /// 初始化

    /// </summary>

    private void Init()

    {

        totalPage = content.childCount;

 

        SetContentSize();//设置Content大小

 

        CalcEachPageNUPos();//计算每一页的NormalizedPositon值

 

        SetLayout();//设置布局

    }

 

    /// <summary>

    /// 设置Content大小

    /// </summary>

    private void SetContentSize()

    {

        content.sizeDelta = new Vector2

            (

                layout.padding.right + layout.padding.left + (totalPage - 1) * (layout.cellSize.x + layout.spacing.x) - layout.spacing.x,

                content.sizeDelta.y

            ); ;

    }

 

    /// <summary>

    /// 计算每一页的NormalizedPositon值

    /// </summary>

    private void CalcEachPageNUPos()

    {

        float tempNUPos = 0;

        eachPageNUPos = new float[totalPage];

        for (int i = 0; i < totalPage; i++)

        {

            eachPageNUPos[i] = tempNUPos;

            tempNUPos += 1f / (totalPage - 1);

        }

    }

 

    /// <summary>

    /// 设置布局

    /// </summary>

    private void SetLayout()

    {

        scrollRect.horizontal = true;

        scrollRect.vertical = false;

        layout.padding.right = layout.padding.left;

        layout.startCorner = GridLayoutGroup.Corner.UpperLeft;

        layout.childAlignment = TextAnchor.MiddleCenter;

        layout.constraintCount = 1;

    }

 

    #endregion

 

    #region Main

 

    /// <summary>

    /// 拖拽开始

    /// </summary>

    public void OnBeginDrag(PointerEventData eventData)

    {

        isDrag = true;

        beginMousePos = Input.mousePosition;

    }

 

    /// <summary>

    /// 拖拽结束

    /// </summary>

    /// <param name="eventData"></param>

    public void OnEndDrag(PointerEventData eventData)

    {

        isDrag = false;

        coe = 0;

 

        endMousePos = Input.mousePosition;

        Vector2 offset = endMousePos - beginMousePos;

        Debug.Log("滑动距离为:" + offset);

 

        if (sliderMultPage)

        {

            //单页滑动

            if (Mathf.Abs(offset.x) >= sliderOnePageDis && Mathf.Abs(offset.x) < sliderMultPageDis)

            {

                float tempHorizontalNUPos = scrollRect.horizontalNormalizedPosition;

                FindNearlyPage(tempHorizontalNUPos);

            }

            //多页滑动

            else if (Mathf.Abs(offset.x) >= sliderMultPageDis)

            {

                if (offset.x > 0)

                {

                    curPage = 0;

                }

                else if (offset.x < 0)

                {

                    curPage = totalPage - 1;

                }

            }

        }

        else

        {

            //单页滑动

            if (Mathf.Abs(offset.x) >= sliderOnePageDis)

            {

                float tempHorizontalNUPos = scrollRect.horizontalNormalizedPosition;

                FindNearlyPage(tempHorizontalNUPos);

            }

        }

 

        targetNUPos = eachPageNUPos[curPage];

    }

 

    private float coe;//比例系数

    private void Update()

    {

        if (isDrag)

        {

            return;

        }

        coe += Time.deltaTime / duration;

        scrollRect.horizontalNormalizedPosition = Mathf.Lerp(scrollRect.horizontalNormalizedPosition, targetNUPos, coe);

    }

 

    #endregion

 

    #region Tool

 

    /// <summary>

    /// 寻找距离当前NormalizedPositon最近的页

    /// </summary>

    private void FindNearlyPage(float tempHorizontalNUPos)

    {

        float minOffset = Mathf.Abs(eachPageNUPos[0] - tempHorizontalNUPos);

        for (int i = 0; i < totalPage; i++)

        {

            float tempHorizontalOffset = Mathf.Abs(eachPageNUPos[i] - tempHorizontalNUPos);

            if (tempHorizontalOffset <= minOffset)

            {

                minOffset = tempHorizontalOffset;

                curPage = i;

            }

        }

    }

 

    #endregion

}

以上就是本文的全部内容

原文链接:https://blog.csdn.net/LLLLL__/article/details/111291687

 


相关教程