What is indicated by Touch.radius?

What exactly does the value returned by Touch.radius indicate? There’s oddly little information about this topic, and not just in relation to Unity.

Using a Samsung Galaxy S7 as an example, a minimal touch gives me a value of approximately ~1.7, while a large thumbprint will give just over 9.0. With this in mind, it has clearly not reflected pixel count (as that would easily be 50+ pixels in minimum radius on a thumbprint).

Furthermore, does Touch radius vary depending on the device and, if so, to what degree would it vary?

// Simple testing script to output touch radius on a compatible device:
using UnityEngine;

public class TouchRadiusTest : MonoBehaviour
{
	Touch testTouch;
	public GUIStyle guiStyle;

	void Start()
	{
		// Set font size to LARGE for convenience on small,
		// high resolution screens
		if(guiStyle.fontSize == 0)
		{
			guiStyle.fontSize = 50;
		}
	}

	void Update()
    {
		// Get immediate touch data when available
		if(Input.touchCount > 0)
		{
			testTouch = Input.GetTouch(0);
		}
	}

	void OnGUI()
	{
		// Display simple data on-screen (top-left corner)
		GUI.Label(new Rect(50f, 50f, 500, 500), string.Format("Touch {0} radius: {1}", testTouch.fingerId, testTouch.radius), guiStyle);
	}
}

Well, after a bit more experimenting, it does seem like “physical size” (whatever THAT means in computer science…) does seem like it’s probably the right approach, but it also makes me wonder exactly what the deal is.

I may convert this to an answer if a better explanation doesn’t happen to be offered, but my current theory is that Touch.radius is based around millimeters, despite Screen.dpi being, well, inches. Based on this theory, here are the key elements in my test case:

// According to a quick Google search...
private const float MM_TO_INCH = 0.0393701f;

void Start()
{
	Camera mainCam = Camera.main;
	float cameraPosition = FrustumSize(mainCam, 1.0f);
	transform.SetParent(mainCam.transform, false);
	transform.localRotation = Quaternion.identity;
	transform.localPosition = new Vector3(-cameraPosition.x * 0.5f, -cameraPosition.y * 0.5f, 1f);

	float pixelScale = Mathf.Min(cameraPosition.x, cameraPosition.y) / Mathf.Min(Screen.width * mainCam.rect.width, Screen.height * mainCam.rect.height);
	transform.localScale = Vector3.one * pixelScale;
}

void Update()
{
	// Simplified touch example:
	float touchPixelRadius = Input.GetTouch(0).radius * Screen.dpi * MM_TO_INCH;
}

public static Vector2 FrustumSize(Camera camera, float distance)
{
	Vector2 frustumSize;
	frustumSize.y = 2.0f * distance * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
	frustumSize.x = frustumSize.y * camera.aspect;
	return frustumSize;
}

This includes basic setup (Start() and FrustumSize(Camera, float)) and the starting point for utilization (Update()).


In trying this approach, the resulting radius of the touch seems to be within reasonable margin of error (where further corrections should/could be within [Touch.radiusVariance][1], where necessary or even applicable).

It’s hard to say for certain whether it being a measurement in millimeters &#42IS&#42 the key detail (or a factually accurate one), but it’s definitely clear that it’s the closest I’ve gotten so far.

I know it has been a long time, but I also have been wondering about the same thing. And after some testing, I don’t think it is measurement in millimeters, but in pixels, at least on iOS devices.

Here’s how I tested it: I tested on my iPhone 11 and iPad 2017. iPhone 11 has PPI (pixel per inches) of 326, and iPad 2017 has PPI of 264. On iPhone 11, Touch.radius returns 25.77148, and On iPad 2017, it returns 20.89063. This is the first evidence: if Touch.radius had been millimeters, it should return the same number on both devices, since my finger doesn’t change in size.

Then, to confirm that Touch.radius does return pixel, I converted the (assumed) pixel counts back to inch. To convert pixel back to inch, we need to multiply it by the inverse of PPI, which is Pixel per Inch.

Thus:

iPhone 11: 25.77148 * 1 / 326 = 0.07913 inches ~= 0.2cm

iPad 12017: 20.89065 * 1 / 264 = 0.07905 inches ~= 0.2cm

I think the results are close enough to be explain by margin of errors, and the numbers does match the size of my finger.

(I replied to this not because I want to call you out or anything. Just because this is the only place that I see this discussion on Touch.radius. Thank you for the post! It reminds me I should have looked in PPI of the devices.)