protected float ScreenToValue (Vector2 screenPos)
{
// Create a plane
Transform trans = cachedTransform;
Plane plane = new Plane(trans.rotation * Vector3.back, trans.position);
// If the ray doesn't hit the plane, do nothing
float dist;
Ray ray = cachedCamera.ScreenPointToRay(screenPos);
if (!plane.Raycast(ray, out dist)) return value;
// Transform the point from world space to local space
return LocalToValue(trans.InverseTransformPoint(ray.GetPoint(dist)));
}