做了一个简单的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の大学技术交流群一起探讨。