Unity实现滑动更换界面效果

在做2048这个游戏时,因为菜单页面还能查看游戏规则,而这些规则又不在同一个页上,所以需要滑动页面实现页面切换,但是仅仅使用unity提供的组件做出的效果仅有一个切换的意思,交互感很差,所以在组件的基础上又写了一个控制页面切换的类。而界面切换就是实现一个滚动的视图。

在unity编辑器中实现滚动视图的基本操作:需要用Scroll Rect组件

首先可以看看官方用户手册中关于Scroll Rect组件的讲解,说的很明白。最精辟的描述就是用于使子 RectTransform 滚动的组件。

滚动视图中的重要元素包括视口、滚动内容以及可选的一个或两个滚动条。

ScrollView是滚动视图,Viewport是视口,Content是滚动内容的集合(在其他地方可能就是一张大图),这些都是panel。Viewport会显示Content的一部分内容。

注意ScrollView、Viewport的大小都是和画布一样的,而Content大小应该是其下所有内容大小的和,如下图。
下面是Content中对应的内容。看到图也应该知道实现滑动更换界面功能的原理了,正是把该显示的放在视口下。

Scroll Rect组件的配置:

为ScrollView添加Scroll Rect组件,并把Viewport拖给Scroll Rect组件的Viewport属性,再把Content拖给Scroll Rect组件的Content属性,滚动条看需要加吧,我加了一个水平滚动条,滚动条并不用加以过多的控制,unity已经把滚动条和Scroll Rect的组合使用做的很好了。其他属性的配置在官方手册中讲的很清楚。

有一个节省Content性能的组件——Mask

因为我们只能看到视口下的内容,由于Content可能有很多界面组成,所以我们可以采取遮罩的方式来不渲染我们看不到的东西,也就是只渲染视口,来提高效率,unity给我们提供了这样一个组件帮助我们实现这个功能:

这个组件当然要给到视口上,可以看到除了一开始在视口上的菜单界面,其余规则界面都没有渲染。

这个组件在全屏的切换时确实只能节省性能,但是在某一部分实现滑动更换界面时却可以遮住Content中不应该显示的部分,很方便,也很必要。

到此,unity中可以帮我们的最大限度就到这了,现在运行会发现确实可以移动,但是到达边界是会出现瑕疵、卡动,并且滑到一半不滑了也不会自动弹回,所以我们仍需要自己编写脚本给与更好的控制。

用代码控制灵敏度、弹回速度。。。:

需要了解的:

当然少不了用到Scroll Rect组件对应的API:ScrollRect,此外,因为要自己写代码控制滑动界面,必须要用到Event事件的实现接口,这里我用的是拖拽类的IBeginDragHandler, IEndDragHandler。

基本的原理:

就是记录每一次开始拖拽到结束拖拽的距离,求出现在的位置,和每个界面的位置比较,显示最近的界面即可。虽然这看起来很简单,但是将交互的效果提升了1000000000000000000000000个档次。
值得注意的是,尽管在代码中注释了很多次,但是还是提一下,就是在ScrollRect中有horizontalNormalizedPosition属性,用来记录水平滚动位置,以 0 到 1 之间的值表示,0 表示位于左侧。所以我们在记录每个界面的位置时,应当记录每个界面的临界比例,且在0-1之间,比如一共有四页,那么第一页和第二页之间的临界应在0.333333.

代码实现:

代码中用到的API均可在ScrollRect找到,不难理解。并且基本所有地方都加了注释。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using System;

public class PageView : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
    //   1)Smooting表示停止滑动后,当前页码归正的速率
    //   2)sensitivity 滑动的敏感度,如果数值过大会导致翻多页
    //   3)OnPageChanged 当前页码改变时回调
    //   4)方法pageTo 直接跳转到某一页
    //注意点:ScrollView下的Content的长度是每页的宽度* 页数,每页的宽度与ScrollView的宽度相同

    private ScrollRect rect;    //滑动组件
    private float targethorizontal = 0;     //滑动的起始坐标
    private bool isDrag = false;                 //是否拖拽结束
    private List<float> posList = new List<float>();     //求出每页的临界值(0-1)
    //private int currentPageIndex = -1;  //记录当前是第几页,页索引从0开始 ,这里不需要显示,有需求可以自己显示
    //public Action<int> OnPageChanged;

    private bool stopMove = true;   //是否停止移动
    public float smooting = 4;      //滑动速度
    public float sensitivity = 0;   //灵敏度
    private float startTime;        //从开始拖动到结束的时间

    private float startDragHorizontal;//记录当前开始滑动的位置(0-1)

    void Awake()
    {
        rect = transform.GetComponent<ScrollRect>();
        //Content水平宽度的大小减去视口大小
        float horizontalLength = rect.content.rect.width - GetComponent<RectTransform>().rect.width;
        //print(horizontalLength);
        posList.Add(0);
        for (int i = 1; i < rect.content.transform.childCount - 1; i++)
        {//求出每页的临界值(0-1)
            posList.Add(GetComponent<RectTransform>().rect.width * i / horizontalLength);
            //print(GetComponent<RectTransform>().rect.width * i / horizontalLength);
        }
        posList.Add(1);
    }

    void Update()
    {
        if (!isDrag && !stopMove)//如果拖动没有结束并且界面还没停止移动就继续移动
        {
            startTime += Time.deltaTime;
            float t = startTime * smooting;
            //水平滚动位置,以 0 到 1 之间的值表示,0 表示位于左侧。用lerp可以实现平缓过渡
            rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, targethorizontal, t);
            if (t >= 1)
                stopMove = true;
        }
    }
    /// <summary>
    /// 移动到第几页,如果需要可在界面进行交互
    /// </summary>
    /// <param name="index"></param>
    //public void pageTo(int index)
    //{
    //    if (index >= 0 && index < posList.Count)
    //    {
    //        rect.horizontalNormalizedPosition = posList[index];
    //        SetPageIndex(index);
    //    }
    //    else
    //    {
    //        Debug.LogWarning("页码不存在");
    //    }
    }
    //private void SetPageIndex(int index)
    //{
    //    if (currentPageIndex != index)
    //    {
    //        currentPageIndex = index;
    //        if (OnPageChanged != null)
    //            OnPageChanged(index);
    //    }
    //}

    //下面就是拖拽事件,eventData存拖拽的信息
    public void OnBeginDrag(PointerEventData eventData)
    {
        isDrag = true;
        startDragHorizontal = rect.horizontalNormalizedPosition;//开始滑动位置(0-1)
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        float posX = rect.horizontalNormalizedPosition;//结束拖拽的位置(0-1)
        posX += ((posX - startDragHorizontal) * sensitivity);//拖拽距离乘以灵敏度
        posX = posX < 1 ? posX : 1;
        posX = posX > 0 ? posX : 0;
        //计算当前拖拽到的位置到哪个界面最近就显示哪个界面
        int index = 0;
        float offset = Mathf.Abs(posList[index] - posX);
        for (int i = 1; i < posList.Count; i++)
        {
            float temp = Mathf.Abs(posList[i] - posX);
            if (temp < offset)
            {
                index = i;
                offset = temp;
            }
        }
        //SetPageIndex(index);
        targethorizontal = posList[index]; //设置当前坐标,更新函数进行插值
        isDrag = false;
        startTime = 0;
        stopMove = false;
    }
}

一开始还在自己用移动函数和SetActive去控制界面的切换,但把自己搞蒙了,搜了半天才知道还有这么好用的组件,搞了两个小时终于搞明白了,多看手册积累经验很重要!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Unity实现ScrollView滑动吸附功能

    本文实例为大家分享了Unity实现ScrollView滑动吸附的具体代码,供大家参考,具体内容如下 最近在做一个展示模块的时候遇到了一个需要实现滑动窗口并且能固定吸附距离的需求,借助UGUI的ScrollView的API以及Dotween实现了这个功能.主要核心逻辑就是检测Content节点的RectTransform的localPosX的移动距离然后继承实现OnDrag几个接口来完成拖动再松开自动吸附到具体的位置.具体效果如下 另外说一下有几个ScrollView自带的API需要设置一下,一个

  • Unity实现颜色渐变滑动条

    本文实例为大家分享了Unity实现颜色渐变滑动条的具体代码,供大家参考,具体内容如下 效果展示 代码 直接挂在UGUI Slider上即可 using UnityEngine; using UnityEngine.UI; public class ColorFade : MonoBehaviour { Color[] colors = new Color[]{ new Color(1, 0, 0), new Color(1, 1, 0), new Color(0, 1, 0), new Colo

  • Unity ScrollView实现无限滑动效果

    本文实例为大家分享了Unity ScrollView实现无限滑动效果的具体代码,供大家参考,具体内容如下 一.效果演示 二.前言 当邮件中有1000封邮件,商店列表中有1000个物体,如果直接实例化1000条数据显示则会大大增加DrawCall,而大量不可见的数据被Mask组件排除在可视范围之外,但他们依然存在,这时就需要考虑通过一个无限滑动的ScrollView来优化渲染性能 三.实现思路 通过头下标和尾下标记录当前实例化数据的最大最小索引,之后用Content的锚点位置与当头下标的锚点位置进

  • Unity UGUI实现滑动翻页效果

    本文实例为大家分享了Unity UGUI实现滑动翻页效果的具体代码,供大家参考,具体内容如下 这个问题真的是老生常谈的事情了,不过在这里还是要说一下,以便以后之需 首先看一下效果图 最后在Content下面是一些Image using UnityEngine; using System.Collections; using UnityEngine.UI; using System.Collections.Generic; using UnityEngine.EventSystems; using

  • Unity UGUI实现滑动翻页直接跳转页数

    本文实例为大家分享了Unity UGUI实现滑动翻页,直接跳转页数的具体代码,供大家参考,具体内容如下 首先看一下最终效果 其实这个功能基本上是老生常谈了,所以代码还是很简单 using UnityEngine; using System.Collections; using UnityEngine.UI; using System.Collections.Generic; using UnityEngine.EventSystems; using System; public class Pa

  • Unity工具类ScrollView实现拖拽滑动翻页

    简介: 在进行UI设计的时候,经常会使用Unity中UI提供的ScrollView,类似Android中的ScrollView,在进行图片预览,多个翻页的时候,能实现很好的效果. 该类中根据Unity的EventSystems中拖拽事件,实现对页码的滑动监听,在使用的时候,新建UI--->ScrollView,把该类组件添加到ScrollView上,把对应的content加入该脚本中的content,调整ScrollView和Content,设置单个滑动页的宽度,拖拽的阈值,即可监听到拖拽,如果

  • Unity实现滑动更换界面效果

    在做2048这个游戏时,因为菜单页面还能查看游戏规则,而这些规则又不在同一个页上,所以需要滑动页面实现页面切换,但是仅仅使用unity提供的组件做出的效果仅有一个切换的意思,交互感很差,所以在组件的基础上又写了一个控制页面切换的类.而界面切换就是实现一个滚动的视图. 在unity编辑器中实现滚动视图的基本操作:需要用Scroll Rect组件 首先可以看看官方用户手册中关于Scroll Rect组件的讲解,说的很明白.最精辟的描述就是用于使子 RectTransform 滚动的组件. 滚动视图中

  • Unity ScrollView实现无限循环效果

    本文实例为大家分享了Unity ScrollView实现无限循环效果的具体代码,供大家参考,具体内容如下 在Unity引擎中ScrollView组件是一个使用率比较高的组件,该组件能上下或者左右拖动的UI列表,背包.展示多个按钮等情况的时候会用到,在做排行榜类似界面时,item非常多,可能有几百个,一次创建这么多GameObject是非常卡的.为此,使用只创建可视区一共显示的个数,加上后置准备个数. 由于ScrollView有两种滚动方式,水平滚动或者垂直滚动,所以我创建了ScrollBase基

  • Ionic2创建App启动页左右滑动欢迎界面

    摘要: 每个有逼格的App在第一次启动时都有一个欢迎界面,通常是几个单页面或者带动画的单页面滑动到最后一页有个启动的按钮,本文将使用Ionic2来创建,So easy! 效果如下 本文例子和上图稍有不同,主要功能如下: 每滑动一下展示一张全屏图片: 滑动到最后一页才出现启动按钮: 欢迎界面只在第一次安装启动时出现. 下面就让我们一步一步实现这个功能: 1.创建应用: 使用Ionic2创建应用非常简单,只需在V1的命令后跟上--v2即可,如下: ionic start ionic2-welcome

  • iOS滑动解锁、滑动获取验证码效果的实现代码

    最近短信服务商要求公司的app在获取短信验证码时加上校验码,目前比较流行的是采用类似滑动解锁的方式,我们公司采取的就是这种方式,设计图如下所示: 这里校验内部的处理逻辑不作介绍,主要分享一下界面效果的实现, 下面贴出代码: 先子类化UISlider #import <UIKit/UIKit.h> #define SliderWidth 240 #define SliderHeight 40 #define SliderLabelTextColor [UIColor colorWithRed:1

  • Android中Activity滑动关闭的效果

    最近感觉有一个Activity关闭的效果挺不错的,就是手势滑动就可以关闭当前Activity,于是就想写一篇博客和大家一起分享下!废话不多说,老规矩,还先上效果图,更直观! 项目地址:https://github.com/xinyitiandi/SlidingFinishDemo 上代码: 1.第一个Activity: package com.ekeguan.slidingfinishdemo; import android.content.Intent; import android.os.B

  • 使用jQueryMobile实现滑动翻页效果的方法

    本文实例讲述了使用jQueryMobile实现滑动翻页效果的方法.分享给大家供大家参考.具体分析如下: 滑动手势在移动设备是很流行的,在移动设备中滑动翻页中很常见 虽然这个功能可以在jQueryMobile中实现,但是个人与之前一篇[jQuery手机浏览器中拖拽动作的艰难性分析]中的观点一致,由于这是在手机浏览器中浏览,而不是安卓的一个独立APP,所以不要经常除点击以外的移动设备手势,以免跟手机浏览器与手机系统本身的手势发生冲突. 那么,使用jQueryMobile实现滑动翻页的效果到底怎么做呢

  • Android使用ViewDragHelper实现QQ6.X最新版本侧滑界面效果实例代码

    (一).前言: 这两天QQ进行了重大更新(6.X)尤其在UI风格上面由之前的蓝色换成了白色居多了,侧滑效果也发生了一些变化,那我们今天来模仿实现一个QQ6.X版本的侧滑界面效果.今天我们还是采用神器ViewDragHelper来实现. 本次实例具体代码已经上传到下面的项目中,欢迎各位去star和fork一下. https://github.com/jiangqqlmj/DragHelper4QQ FastDev4Android框架项目地址:https://github.com/jiangqqlm

  • android ViewPager实现滑动翻页效果实例代码

    实现ViewPager的滑动翻页效果可以使用ViewPager的setPageTransformer方法,如下: import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.View; public class ReadViewPager extends ViewPager { public ReadV

  • 如何在Android中实现左右滑动的指引效果

    本文的目的是要实现左右滑动的指引效果.那么什么是指引效果呢?现在的应用为了有更好的用户体验,一般会在应用开始显示一些指引帮助页面,使用户能更好的理解应用的功能,甚至是一些新闻阅读器会把一些头条新闻以指引效果的形式显示.说个最基本的,就是我们的手机主屏幕就是这种效果. 下面我们就开始实现我们的左右滑动指引效果.为了大家更好的理解,我们先看下实现效果,如下图所示:     在这里,我们需要用到google提到的一个包--android-support-v4.jar,这个包包含了一些非常有用的类,其中

随机推荐