Unity Notes之屏幕触点轨迹的平滑

原创 2016年03月07日 14:09:30

最近在做一个移动设备上的触控系统需求,基本的要求点是,通过手指在屏幕上指定区域内的滑动点击来控制一个对象在空间或屏幕上的位置移动。具体的应用场合:

  • 通过屏幕点击来精确控制对应的武器光标的位置;
  • 得到较为精确且平滑的、用户在屏幕拖拽移动时的拖尾效果;
以及其他应用等。直接的实现也比较简单,通过捕获Input.touch上的touch点并记录对应的位置,然后将屏幕位置序列转换为目标位置信息即可。

但是这里边会遇到一个问题,移动设备直接得到的Input中的touch信息其实是有噪声的,这些噪声一方面来自于硬件touch感应设备,另外一些来自于用户自己的操作,而噪声在使用中的表现就是转换后的信号会有较大的jitter现象。比如用来控制一个屏幕上的光标,那么这个光标的位置可能就会一直在抖动。因而如果对信息的平滑度要求过高的话必须得对这些原始的输入信号进行滤波才可以,即在输入的触点信号上施加一个低通滤波器,以便过滤掉其中的高频信息保留较为稳定的低频信息。

为了良好的用户体验,这里对使用的一个较合理的低通滤波器的设计要求如下:

  1. 低速移动下的误差不能太大,否则用户不能实现精确控制;
  2. 高速移动下的迟滞不能太大,否则用户感觉系统反应迟钝;

单纯的不考虑速度的低通滤波器(如Unity doc中关于multi touch所提供的低通滤波方法)虽然可以得到平滑的目的,但是却会带来较大的迟滞;所以这里边就涉及到一个对速度的考量,即通过速度来确定需要过滤掉的信号的尺度,而对速度与位置的平滑则直接使用指数平滑(Exponential smoothing)。加上速度判断后,可以针对不同的速度,对滤波的尺度进行不同的设定,从而在快慢速移动时都得到比较优化的效果。结合上述考虑最终实现了一下,得到的效果还是比较理想的(应用实例参考死亡之屋手游版中的武器控制手感)。对应的代码如下:

void LowPassFilter(Vector2 currentPosition, Vector2 currentVelocity, float dt)
{
    if (Mathf.Approximately((currentVelocity - mFilteredVelocity).sqrMagnitude, 0))
    {
        mFilteredVelocity = currentVelocity;
    }
    else
    {
        mFilteredVelocity = FilterKernel(currentVelocity, mFilteredVelocity, Alpha(Vector2.one, dt));
    }

    if (Mathf.Approximately((currentPosition - mFilteredPosition).sqrMagnitude, 0))
    {
        mFilteredPosition = currentPosition;
    }
    else
    {
        Vector2 cutoffFrequency;
        cutoffFrequency.x = mJitterReduction + 0.01f * mLagReduction * Mathf.Abs(mFilteredVelocity.x);
        cutoffFrequency.y = mJitterReduction + 0.01f * mLagReduction * Mathf.Abs(mFilteredVelocity.y);
        mFilteredPosition = FilterKernel(currentPosition, mFilteredPosition, ComputeExpSmoothingFactor(cutoffFrequency, dt));
    }
}

Vector2 ComputeExpSmoothingFactor(Vector2 cutoff, float dt)
{
    float tauX = 1 / (2 * Mathf.PI * cutoff.x);
    float tauY = 1 / (2 * Mathf.PI * cutoff.y);
    float fX = 1 / (1 + tauX / dt);
    float fY = 1 / (1 + tauY / dt);
    fX = Mathf.Clamp(fX, 0, 1);
    fY = Mathf.Clamp(fY, 0, 1);
    return new Vector2(fX, fY);
}

Vector2 FilterKernel(Vector2 current, Vector2 previous, Vector2 expFactor)
{
    float x = expFactor.x * current.x + (1 - expFactor.x) * previous.x;
    float y = expFactor.y * current.y + (1 - expFactor.y) * previous.y;
    return new Vector2(x, y);
}
运行效果动态截图如下(其中的jitterReduction和lagReduction分别设置为1):

其中的蓝色线条为过渡后的轨迹,黄色线条为原始点击的轨迹,圆圈为过滤后的光标位置。

Unity3d 触屏手机滑动事件(上下左右方向精确判断)

2017-07-05 更新 添加了一个滑动距离 不然手指刚刚触碰上去就开始判断了滑动 我个人默认距离是80 滑动距离超过80的时候才开始执行方法...
  • yzx5452830
  • yzx5452830
  • 2017年06月29日 22:17
  • 3611

Unity 移动端触摸屏操作

Unity 触屏操作 当将Unity游戏运行到IOS或Android设备上时,桌面系统的鼠标左键可以自动变为手机屏幕上的触屏操作,但如多点触屏等操作却是无法利用鼠标操作进行的。Unity的Input...
  • u014550279
  • u014550279
  • 2016年01月18日 16:48
  • 6306

Unity3D 鼠标以及触屏移动、缩放控制器(相机)

Unity3D 支持多平台的发布,但是平时在测试的过程中往往需要在各个平台之间进行切换,在平时开发中,对象的移动、舞台缩放使用鼠标控制比较方便,但是在安卓平台,鼠标就无法发挥作用了,只能使用触控操作,...
  • andyhebear
  • andyhebear
  • 2016年05月17日 10:02
  • 2080

屏幕触点

android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。 一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN...
  • catherine880619
  • catherine880619
  • 2012年07月03日 09:55
  • 1458

【技巧】安卓版按键精灵手机抓抓 取色取坐标 获取屏幕触点坐标

http://bbs.anjian.com/thread-519563-1-1.html 下载下了按键精灵安卓版。找了一圈也没找到我们可爱的抓抓工具(我没用电脑),录制也没有。点击屏幕,都不...
  • wanglha
  • wanglha
  • 2015年01月26日 17:53
  • 7669

Unity3D之与根据动态的两个轨迹点绘制面详解

转自:雨松MOMO 2012年05月06日 于 雨松MOMO程序研究院 发表 大家应该知道3D世界中任何的面都是由三角形绘制完成的,因为任何无规则的集合图形都可以由三角形来组成。比如四边形,无论...
  • u014086857
  • u014086857
  • 2016年08月01日 16:09
  • 1426

Unity3D研究院之与根据动态的两个轨迹点绘制面详解(二十)

原创文章如需转载请注明:转载自雨松MOMO程序研究院本文链接地址:Unity3D研究院之与根据动态的两个轨迹点绘制面详解(二十)        大家应该知道3D世界中任何的面都是由三角形绘制完成的,因...
  • xys289187120
  • xys289187120
  • 2012年08月09日 15:14
  • 7650

Unity3D研究之与根据动态的两个轨迹点绘制面详解

结合本文的标题大家仔细想想,如果需要绘制一个动态无规则面其实只需要得到动态的两个轨迹点即可,那么结合下面的图片大家仔细在想想。 暂时我们先忽略Z轴(这样在平面中看得更清楚),假设Z轴坐标...
  • pizi0475
  • pizi0475
  • 2015年07月15日 11:18
  • 933

记录鼠标点击次序并实现平滑画线,以线做轨迹进行移动

  • 2016年03月22日 13:08
  • 6KB
  • 下载

类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(无轨迹)

参考百度地图demo:轨迹运行demo展示,类名TrackShowDemo。百度TrackShowDemo类里只实现了一个完整的轨迹运行,并且是将所有的经纬点放在一个数组里,我觉得直接放在一个List...
  • qq_30651537
  • qq_30651537
  • 2016年11月21日 18:13
  • 1778
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unity Notes之屏幕触点轨迹的平滑
举报原因:
原因补充:

(最多只允许输入30个字)