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

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

  • 通过屏幕点击精确来控制对应的武器光标的位置;
  • 得到较为精确且平滑的用户在屏幕移动时的拖尾效果;

以及其他应用等。直接的实现也比较简单,通过捕获Input.touch上的touch点并记录对应的位置,然后将屏幕位置序列转换为目标的信息即可。

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

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

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

所以这里边就涉及到一个对速度的考量,即通过速度来确定需要过滤掉的信号的尺度,而对速度与位置的平滑则直接使用指数平滑(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 alphaX = 1 / (1 + tauX / dt);
    float alphaY = 1 / (1 + tauY / dt);
    alphaX = Mathf.Clamp(alphaX, 0, 1);
    alphaY = Mathf.Clamp(alphaY, 0, 1);
    return new Vector2(alphaX, alphaY);
}

Vector2 FilterKernel(Vector2 current, Vector2 previous, Vector2 alpha)
{
    float x = alpha.x * current.x + (1 - alpha.x) * previous.x;
    float y = alpha.y * current.y + (1 - alpha.y) * previous.y;
    return new Vector2(x, y);
}

运行效果动态截图如下(其中的jagReduction和lagReduction分别设置为1):

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

时间: 2024-08-27 08:19:17

Unity Notes之屏幕触点轨迹的平滑的相关文章

一个伟大的发现,装X一下。笔记本win7系统64位机器执行unity 时,屏幕模糊解决的方法

笔者笔记本win7系统64位机器执行unity 时.往往切换时unity界面屏幕模糊,后来发现此时须要下载DirectXRuntimes201006x64,安装就可以.

Unity GUI自适应屏幕分辨率(一)布局自适应

这里我们先谈第一个问题坐标矩阵变化实现布局自适应. 选取基准尺寸 通常你需要选择一个基准的屏幕尺寸,象现在开发的应用也需要跨平台在iOS(iPhone/iPad)/Android都可以运行,我这边选取的是iphone4的屏幕尺寸: 480 * 320. 设计师设计的GUI的素材时就是按照这个尺寸来设计.但是紧接着的问题是如何保证它在其他不同尺寸/分辨率的平台上运行时不会出现各种诡异的位置大小错乱了. 举一个实际的例子来更好描述这个问题,比如我们的游戏是水平方向的, 然后游戏进行中间的暂停界面中,

关于Unity中的屏幕适配

Game视图的屏幕分辨率可以先自定义添加,供以后选择,以下是手游经常用到的分辨率: 1.1136X640,iPhone5 2.1920X1080,横屏 3.1080X1920,竖屏 4.960X640,横屏iPhone4 5.640X960,竖屏iPhone 6.768X1024,ipad 7.800X480 8.480X800 创建一个Canvas节点 Render Mode选择为Screen Space(Overlay)

Unity Notes调制粒子系统的颗粒的最大数目

Unity该粒子系统是很容易使用.这样的问题是在实际的过程中遇到的:以控制的粒子系统组件的动态需要可产生颗粒的最大数目. 看doc他说,有maxParticles控制.却没有这个开放的參数.仅仅能通过其他的方式来实现. 这里能够通过手动产生粒子的方式来实现.也即ParticleSystem中的Emit方法,详细代码例如以下: public class ParticleSystemComp : MonoBehaviour { ParticleSystem mParticleSystem = nul

【Unity】关于屏幕自适应的思路

关于NGUI的屏幕自适应,大体思路可以这样做: 比如要实现在屏幕的左侧做一个长条背景: 可以看出这部分图片是和屏幕高度一致的.那么只要得到“制作时的屏幕高度”以及“当前运行屏幕高度”,求两个值的比值,然后当前UI的大小乘上这个比值即可得到UI适应后的大小.先完成这一步: 1.新建一个widget.因为此UI要一直靠在屏幕左边,所以它的pivot设置为左边.Size设置成当前(制作时)的屏幕大小,比如1280X800. 2.新建Sprite且为widget的子物体.摆好位置. 3.建立自适应脚本并

unity,实现屏幕后处理的两种方法

方法一: Main Camera的Target Texture保持为None.挂一个Blit脚本,在其中的OnRenderImage中调用Graphics.Blit(sourceTexture,destTexture,myMaterial). 需要注意的是myMaterial中的shader一定要用ZWrite Off.ZTest Always的shader. 方法二: 为Main Camera的Target Texture指定一个RT,直接渲染到RT,同时将RT赋给一个quad并用一个正交相机

【Unity Shader编程】之十五 屏幕高斯模糊(Gaussian Blur)后期特效的实现

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/51871531 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 本文工程使用的Unity3D版本: 5.2.1  本篇文章将分析如何在Unity中基于Shader实现高斯模糊屏幕后期特效. 首先放出最终的实现效果.如下几幅图,是在Unity中使用本文所实现的Shader得到的高斯模糊屏幕

【浅墨Unity3D Shader编程】之九 深入理解Unity5中的Standard Shader (一)&屏幕水幕特效的实现

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/49556461 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 本文工程使用的Unity3D版本: 5.2.1 概要:本文主要介绍了Unity5中的标准着色器,并且也涉及到了基于物理的着色.延迟渲染等高级着色技术,而在文章后半部分,也对屏幕水幕特效的实现方法进行了讲解与分析. 依然是附上

Unity 学习笔记01

简单的先说说Unity中的比较常用的英语单词,不需要背诵,至少看到能大概想起中文意思即可. 常用英语 . Scripts---存放脚本的目录 scene---存放场景的目录 Horizontal---水平 Vertical---垂直  position---位置 Rotation---旋转Destroy---销毁 Collision---碰撞  Collider---触发  virtual---子类可修改 Load Selection  载入选择    Save Selection  存储选择