- Home /
.NET System ticks on Android - what am I doing wrong?
What I'm doing
am working on simple enough game for Android. Right now I'm debugging my swipe detection logic (pasted below). I have two swipe patterns that I want to detect: 1) short, quick swipes which result in a single "direction pulse" and 2) long swipes which generate multiple "direction pulses." The method DetectSwipeDirection is evaluated by the camera on update.
The bug
ong presses will wait a second before the first pulse as expected. Then a new pulse is generated every frame after that. A long swipe should instead provide single pulses once every second (according to the static values at the top).
My own efforts to solve this
wish that I could figure out how to plug my phone into the computer and just press the "Build and Run" button. But I have never been able to make it work - all my tests are done by building, putting the APK onto Google Drive, downloading onto my phone, and running from there. What I have been able to do is write unit tests around all my methods. When I run my tests, it shows that all my math is correct and there should be no reason to get my burst of direction pulses.
My questions
hat am I doing below which might be causing this bug? Maybe using decimal in my SecondsSince method causes problems on the ARM architecture?
The code
using System;
using UnityEngine;
public class SwipeDetector
{
/// <summary>
/// Minimum swipe distance to register an intent to move.
/// </summary>
private static readonly float MinimumSwipeDistance = 0.75f;
/// <summary>
/// Time in seconds from touch to first move.
/// </summary>
private static readonly float SecondsToFirstMove = 1f;
/// <summary>
/// Time in seconds from one move to another.
/// </summary>
private static readonly float SecondsToSequentialMove = 1f;
/// <summary>
/// Position at which player started touching screen.
/// </summary>
private Vector2 fingerDownPosition;
/// <summary>
/// Position at which player is currently touching screen.
/// </summary>
private Vector2 fingerPosition;
/// <summary>
/// Screen resolution divisor.
/// </summary>
private float screenResolutionDivisor;
/// <summary>
/// Whether screen resolution has been gathered yet.
/// </summary>
private bool screenResolutionGathered = false;
/// <summary>
/// Whether swipe has been started.
/// </summary>
private bool swipeStarted = false;
/// <summary>
/// Whether first move was made during current swipe.
/// </summary>
private bool firstMoveMade = false;
/// <summary>
/// Whether swipe was long enough during the last test.
/// </summary>
private bool wasLongEnoughLastTest = false;
/// <summary>
/// Ticks when swipe became long enough.
/// </summary>
private long whenSwipeBecameLongEnough;
/// <summary>
/// Ticks of last move on current swipe.
/// </summary>
private long lastMoveOnCurrentSwipe;
/// <summary>
/// Gets resolution divisor.
/// </summary>
private float ResolutionMDivisor
{
get
{
if (!this.screenResolutionGathered)
{
this.screenResolutionDivisor = Math.Max(Screen.width, Screen.height);
this.screenResolutionGathered = true;
}
return this.screenResolutionDivisor;
}
}
/// <summary>
/// Performs input detection.
/// </summary>
/// <returns>Direction of swipe.</returns>
public MovementDirection DetectSwipeDirection()
{
foreach (var touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
this.fingerDownPosition = touch.position;
}
if (touch.phase == TouchPhase.Moved)
{
this.fingerPosition = touch.position;
}
if (touch.phase == TouchPhase.Ended)
{
if (!this.firstMoveMade && this.IsSwipeLongEnough())
{
return this.CalculateSwipeDirection();
}
}
return this.TestLongSwipe();
}
return MovementDirection.None;
}
/// <summary>
/// Tests long swipe.
/// </summary>
/// <returns>Movement direction.</returns>
private MovementDirection TestLongSwipe()
{
if (this.IsSwipeLongEnough())
{
if (!this.wasLongEnoughLastTest)
{
this.whenSwipeBecameLongEnough = DateTime.Now.Ticks;
this.lastMoveOnCurrentSwipe = this.whenSwipeBecameLongEnough;
}
if (this.firstMoveMade)
{
if (this.SecondsSince(this.lastMoveOnCurrentSwipe) >= SecondsToSequentialMove)
{
this.lastMoveOnCurrentSwipe = DateTime.Now.Ticks;
return this.CalculateSwipeDirection();
}
}
else
{
if (this.SecondsSince(this.whenSwipeBecameLongEnough) >= SecondsToFirstMove)
{
this.lastMoveOnCurrentSwipe = DateTime.Now.Ticks;
return this.CalculateSwipeDirection();
}
}
this.wasLongEnoughLastTest = true;
}
else
{
this.wasLongEnoughLastTest = false;
this.firstMoveMade = false;
}
return MovementDirection.None;
}
/// <summary>
/// Calculates seconds since given time in ticks.
/// </summary>
/// <param name="other">Time to test against in ticks.</param>
/// <returns>Seconds since given time.</returns>
private float SecondsSince(long other)
{
return (float)((decimal)(DateTime.Now.Ticks - other) / TimeSpan.TicksPerSecond);
}
/// <summary>
/// Performs swipe calculation to gather swipe direction.
/// </summary>
/// <returns>Swipe direction.</returns>
private MovementDirection CalculateSwipeDirection()
{
this.fingerPosition.RotateAround(this.fingerDownPosition, -CameraControl.SkewAngle);
var movement = this.fingerPosition - this.fingerDownPosition;
if (Math.Abs(movement.x) > Math.Abs(movement.y))
{
if (movement.x > 0)
{
return MovementDirection.East;
}
else
{
return MovementDirection.West;
}
}
else
{
if (movement.y > 0)
{
return MovementDirection.North;
}
else
{
return MovementDirection.South;
}
}
}
/// <summary>
/// Determines whether swipe distance is currently long enough to perform another step.
/// </summary>
/// <returns>Whether swipe is long enough for another step.</returns>
private bool IsSwipeLongEnough()
{
return this.fingerPosition.DistanceTo(this.fingerDownPosition) / this.ResolutionMDivisor >= MinimumSwipeDistance;
}
}
Your answer

Follow this Question
Related Questions
multi touch / swipe issues 5 Answers
Android Drag By Steps 0 Answers
Camera swipe AND gameObject touch (Android) 1 Answer
Frame Drop on Touching or Swiping Screen 0 Answers
any one now about the touch events of android swipe events on the android 1 Answer