Unity ScrollView动效

发布于 2021-07-28  269 次阅读


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

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

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の大学技术交流群一起探讨。


"You got to put the past behind you before you can move on. "