Unity低版本Button点击边缘抽搐的问题

Selectable的状态切换

状态类型

??Selectable一共有Normal、Highlighted、Pressed、Disabled四个状态。

??新版本加入了Selected状态,老版本的Unity其实也对Selected状态进行了处理,当该Selectable是全局Selected对象时,将状态设置为Highlighted。

状态切换的触发时机

  1. OnEnable。初始化按钮状态。
  2. 设置interactable时。维护m_Interactable变量,记录当前是否可交互。
  3. OnPointerDown、OnPointerUp。维护isPointerDown变量,记录当前是否是按下状态。
  4. OnPointerEnter、OnPointerExit。维护isPointerInside变量,记录当前鼠标是否在该对象区域。

抽搐的原因

??老版本对Pressed状态的判定是要同时满足isPointerDown和isPointerInside时才时Pressed状态。当点击边缘时,如果有一个缩小的动画,会导致触发OnPointerExit,使isPointerInside为false,导致Pressed判定失败、Highlighted判定也失败、所以状态变为了Normal。这个时候按钮又变回了原来的大小,又会触发OnPointerEnter,使isPointerInside为true。Pressed判定成功。在这两个状态间不停循环,造成抽搐的表现。

判定代码

老版本(2018.3.0f2)

protected bool IsPressed()
{
    if (!IsActive())
        return false;

    return isPointerInside && isPointerDown
}

新版本(2018.4.3f1)

??移除了对Pressed状态的单独判定,整合在了currentSelectionState里,且移除了isPointerInside的限制。

protected SelectionState currentSelectionState
{
    get
    {
        if (!IsInteractable())
            return SelectionState.Disabled;
        if (isPointerDown)
            return SelectionState.Pressed;
        if (hasSelection)
            return SelectionState.Selected;
        if (isPointerInside)
            return SelectionState.Normal;
    }
}

Tips

??没看具体是哪个版本修复的,就贴了两个我看到有改变的版本。

修复方案

1.升级Unity版本

??最简单的方案。

2.如果不方便升级的话,重写Button

代码

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

//对状态切换的修复
//也可以加入一些长按逻辑、点击音效等功能,成为一个更完善的按钮类
public class BetterButton : Button
{
    private bool isPointerDown = false;

    public override void OnPointerDown(PointerEventData eventData)
    {
        isPointerDown = true;
        base.OnPointerDown(eventData);
    }

    public override void OnPointerUp(PointerEventData eventData)
    {
        isPointerDown = false;
        base.OnPointerUp(eventData);
        GameObject currentOverGo = eventData.pointerCurrentRaycast.gameObject;
        //如果pointerUp时所指向的press对象和按下时不一样,则需要主动调一下PointerExit去纠正isPointerInside
        GameObject curPress = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
        if (eventData.pointerPress != curPress)
        {
            OnPointerExit(eventData);
        }
    }

    public override void OnPointerExit(PointerEventData eventData)
    {
        if (isPointerDown == false)
        {
            base.OnPointerExit(eventData);
        }
    }
}

为什么这么改

??因为看过代码后我们可以确定在老版本中,OnPointerExit只负责isPointerInside和按钮状态的维护,没有其他逻辑。所以我们通过修改这部分代码区控制它的调用是一种比较安全的行为。

??我们强制让PointerExit在Selectable按下时不生效,在Selectable抬起时再尝试调用OnPointerExit纠正状态即可。

其他

??如果升版本的话要及时把这些Trick代码删掉,因为我们在没有看新版的代码之前,不能确定是否会产生其他意料外的结果。

原文地址:https://www.cnblogs.com/blueberryzzz/p/12682502.html

时间: 2024-10-24 01:47:39

Unity低版本Button点击边缘抽搐的问题的相关文章

input[type=&#39;submit&#39;]input[type=&#39;button&#39;]button等按钮在低版本的IE下面,去掉黑色边框的问题

今天做一个tabs效果的时候,发现上面的button在低版本下会出现黑色的边框,很难看,于是我整理了下几个去掉黑色边框的办法: 1.在button的外层嵌套一个div,设置button的border:none; <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <st

让低版本的 Android 项目显示出 Material 风格的点击效果

欢迎各位关注我的新浪微博:http://weibo.com/kifile 转载请标明出处(http://blog.csdn.net/kifile) 每天都被不同的需求纠缠的生活是幸福而又不幸的,这不我们家亲爱的设计师们又让我们在低版本的 Android 平台上实现一下类似于 Material Design 的点击效果. 虽然大家都知道 MaterialDesign 的确好看很多,但是让我们为低版本适配也是一个苦逼的活儿. 不过还好,在使用了 nineoldandroids 这个开源库之后,总算是

低版本系统兼容的ActionBar(二)ActionProvider+分离式ActionBar+分离式的ActionMode

       这篇文章主要讲的是在低版本兼容的ActionBar中实现自定义的ActionProvider,ShareActionProvider的使用方法,如何实现分离式ActionBar,外加在分离式ActionBar上的ActionMode的效果. 一.自定义ActionProvider 建立一个类,继承android.support.v4.view.ActionProvider,然后复写里面的方法即可.主要就是初始化视图和相应点击事件. 范例一: SettingsActionProvid

jQ1.5中的事件系统(低版本的事件系统)

jQ的一个个版本事系统都在修正着bug和不断优化, 而且看了事件系统对事件的兼容更加熟悉, 更加了解jQ内部的事件机制. 因为jQ对事件系统引入了事件命名空间,事件的代理, 事件的手动触发,事件描述等等各种概念, 对事件的可操控性大大增加, 这个也是库存在的意义, 不是说只要处理addEventListener和attachEvent可以做到的:在大型的项目中事件系统也可以作为发布者和派发者,对整个系统进行充分的解耦, 这些做为自己的笔记,一步一步走, 只是大概看了看, 还有不懂的地方, 最好的

js实现抛物线运动 兼容IE低版本(转)

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="keywords" content="javascript, 动画, 抛物线" /> <title>抛物线运动</title> <style> body { margin: 0; font-size: 14px; font-

Android好奇宝宝_07_ViewPager切换动画(兼容低版本)

闲着无聊,写写Demo 想着写一个图片轮播,百度了一下基本都是用ViewPager实现的,那就用ViewPager来练手. 写完了再自定义切换效果,发现3.0以下不兼容,只好想办法. 先上效果图: 下面一步一步来: (1)写布局: <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <jjj.demo.viewpager

轮播图采用js、jquery实现无缝滚动和非无缝滚动的四种案例实现,兼容ie低版本浏览器

项目源代码下载地址:轮播图 以下为项目实现效果:(由于gif太大,所以只上传一张图片,但效果完全能实现,经测试,在ie各版本浏览器及chrome,firefox等浏览器中均能实现效果,可以实现点击切换图片,无缝滚动和非无缝滚动两种效果) 页面源代码:index.html(以下注释自行切换,为了项目清晰,所以用了四个js文件,分别实现不同的效果) <!DOCTYPE html> <html lang="zh-CN"> <head> <meta c

android中导入低版本project可能会遇到的编译问题(转自: [email&#160;protected])

使用高版本的SDK后再导入以前用低版本的project时,会遇到一些兼容性的问题. (1)Unable to resolve target 'android-5' 因为本机中现在使用的是2.2的SDK,API的版本是8:而导入的工程使用的是2.0开发的,其API版本是5. 需要将default.properties中的target=android-5改为target=android-8就好了. 但要注意,也要同步将AndroidManifest.xml中的<uses-sdk android:mi

转 - Android Studio 低版本Gradle升级到高版本时常见问题

来自: http://blog.csdn.net/feiniao8651/article/details/44652753 今天拿到一个用低版本Gradle的编译的Android工程,gradle对版本的向下兼容做的不太好,因此在高版本Gradle的电脑上会出很多问题. 1. Error:The project is using an unsupported version of the Android Gradle plug-in (0.12.2). The recommended versi