- Home /
Touch Input positions are different on iOS and Android?
I'm using touch input to drag the camera around on the x-y plane. For some reason, the camera's movement is much slower on Android than it is on iOS. I get similar results on iPhone, iPad, and the Unity Editor, but the panning is slow on Android. I'm simply using pixel measurements and dividing by the screen height, so screen size should not matter (and does not matter on iOS). I'm using Easy Touch for input.
gesture.deltaPosition is a Vector2 in pixels that stores the change in position since the last frame. On_TouchDown is called every frame that the player is touching the screen.
Here's the code:
void On_TouchDown(Gesture gesture)
{
if (gesture.deltaPosition.magnitude > 0)
{
Vector2 deltaPosition = -1f * panSpeed * (gesture.deltaPosition / (float)Screen.height);
transform.position = new Vector3(
transform.position.x + deltaPosition.x,
transform.position.y + deltaPosition.y,
transform.position.z);
}
}
Answer by JoaquinRD · Aug 22, 2013 at 08:21 PM
It looks like this was an Android-specific bug in the Easy Touch plugin (version 2.5). Instead of using their deltaPosition, I calculated my own by using their touch position and comparing it to the previous touch position.
Here's the working code:
Vector2 previousTouchPosition = Vector2.zero;
//called once when the touch starts
void On_TouchStart(Gesture gesture)
{
previousTouchPosition = gesture.position;
}
//called every frame while touching
void On_TouchDown(Gesture gesture)
{
if (gesture.deltaPosition.magnitude > 0)
{
Vector2 deltaPosition = -1f * panSpeed * ((gesture.position - previousTouchPosition) / (float)Screen.height);
previousTouchPosition = gesture.position;
transform.position = new Vector3(
transform.position.x + deltaPosition.x,
transform.position.y + deltaPosition.y,
transform.position.z);
}
}
Answer by robertbu · Aug 21, 2013 at 12:37 AM
Of course they are different. The same stroke across the same percentage of screen will return very different number of pixels, and you code moves things based on pixels. You need to standardize. You can base it on Screen.dpi, or you could use the ratio of some base vertical height to the height of the device. Given my guess at how you are using this code, the best solution would be to base it on world units traveled at the distance the object is from the camera.
I understand that each screen will have a different dpi, but shouldn't dividing the deltaPosition (Vector 2 in pixels) by Screen.height (pixels) solve this problem? It seems like this would convert the Vector2 from pixel space to normalized screen space based on the height.
I missed that you were dividing by the height originally. While that mitigates your issue somewhat, it does not solve it because of the aspect ratio. Imagine a single stroke horizontally across the screen. Imagine the game can be played both horizontally and vertically. I think you can see how the calculation will fail. Even if you don't allow portrait/landscape for your app, the aspect ratio between devices will cause this to happen.
You might get closer by dividing the x by Screen.Width and the y by Screen.height independently. But even there, you will have potential issues. Given two different devices with different aspect ratios, one will see more of the world horizontally than the other. An left edge to right edge strokes will move the object the same amount on both devices, but the amount of the world units traveled by that finger will be different. BTW: Vertically it will be the same.
Typically I see this type of calculating for drag and drop. If that is what you are doing here, I suggest the best solutions is to work in world units rather than screen units.
The difference in screen widths doesn't really bother me. I will try working in world units ins$$anonymous$$d to see if that makes any difference.
I was just closing some tabs and took a second look here. I assume you are using some sort of package for touch management based on your 'On_TouchDown()' What meaning does 'gesture.deltaPosition' have for a touch down? I would expect it to be 0 or undefined.