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

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

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

```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);
}```