Unity ScrollView动效

做了一个简单的ScrollView缩放的动效。效果如下图。

简单的说一下原理,获取屏幕的中心点,作为最大的点,计算子物体与中心点的距离作为分子,获取从第一个对象到最后一个对象之间的距离作为分母,这样,当对象滑动到屏幕中间的时候,距离为零,分子就是零,那么整个分数的值就是0,那么对象的scale就是1减去0。同理其他的对象也是一样。这样在滑动的时候,就有滑动到中间变大,划出中间区域变小的效果了。

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ScrollItemControll : MonoBehaviour
{

// 按照下标0-X从上到下存放obj
public List<Transform> Item;

public Vector3 screenCenterPosToWorldPos = Vector3.zero;
//最长距离
public float maxDis = 0;

private bool openUpdate = false;

private float[] dis;
IEnumerator Start()
{
yield return null;
//第一个Item到最后一个之间的距离
maxDis = Item[0].position.y - Item[Item.Count - 1].position.y;
//取屏幕中心点作为最大块位置
Vector3 screenCenterPos = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f);
//将屏幕中心点转为世界坐标
screenCenterPosToWorldPos = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width * 0.5f, Screen.height*0.5f));
screenCenterPosToWorldPos.z = 0;
//定义一个Item距离的数组,用来判断每个item位置是否发生改变
dis = new float[Item.Count];
//因为是从第二帧才开始移动,所以初始化之后才会开始
openUpdate = true;
}


// Update is called once per frame
void Update()
{
if (openUpdate)
{
for (int i = 0; i < Item.Count; i++)
{
//计算每个item到屏幕中点的y的差值
float itemDis = Mathf.Abs(Item[i].position.y - screenCenterPosToWorldPos.y);
//如果对象位置没有发生变化就不需要更新位置和大小
if (itemDis != dis[i])
{
//存储每个item到屏幕中点的差值
dis[i] = itemDis;
//Debug.LogError(string.Format("dis = {0} !!! item 2 Pos = {1} !!! screenCenterPosToWorldPos = {2}",itemDis,Item[2].position,screenCenterPosToWorldPos));
//这里是一个公式,1减去(每个item占总长度的比例)取到的值就是一个0-1之间的数。
float threshold = Mathf.Abs(1 - dis[i] / (maxDis*0.5f)) *1.3f;
//Debug.LogError(threshold);
//设置每个Item的scale
Item[i].localScale = new Vector3(threshold,threshold,1);
}
}
}

}
}

项目下载:提取码【uoh7】

https://pan.baidu.com/s/1IsBJYeujLNJ5m6kvq1i20g

好了,今天的分享就到这里了,如果有什么问题或者有什么建议,欢迎在文章下方留言或者进Unityの大学技术交流群一起探讨。