Reputation: 148
I have a plane with scale (64,1,36) and rotation is (90,-180,0) and need the local coordinate of a raycast hit in the 2d coordinates format:
(0,0)-------(64,0)
| |
| |
| |
(0,36)------(64,36)
with my current code:
RaycastHit hit;
Vector3 coords = new Vector3();
if (Physics.Raycast(GazeOriginCombinedLocal, GazeDirectionCombined, out hit, Mathf.Infinity))
{
if (!hit.transform.Equals("Cube"))
{
Pointer.transform.position = hit.point; //Green cube for visualization of hit in worldspace
// coords = RectTransformUtility.ScreenPointToLocalPointInRectangle(Plane, hit.point, Camera.main, out coords);// no result at all
}
}
Trying this:
hit.transform.InverseTransformPoint(hit.point)
gives me this
(5,-5)---(-5,-5)
| |
| (0,0) |
| |
(5,5)----(-5,5)
Does some have an idea to get the needed format?
Thats how my plane which is a child of the main camera and my hierarchy looks like: Thanks in advance
Upvotes: 3
Views: 1950
Reputation: 90639
I think you could use the Transform.InverseTransformPoint
which
Transforms position from world space to local space.
And then since this also is affected by the scale multiple it again by the scale of the plane using Vector3.Scale
.
So your coords should probably be something like
coords = hit.transform.localScale / 2f + Vector3.Scale(hit.transform.InverseTransformPoint(hit.point), hit.transform.localScale);
can't test it right now though since typing on smartphone. You might e.g. need to invert the y/z component according to your needs and depending how the plane is rotated etc. But I hope this gives you an idea
In order to debug what's wrong you should probably print out the values step by step
var scale = hit.transform.localScale; // 64, 1, 36
var halfScale = scale / 2f; // 32, 0.5, 18
var localHitPoint = hit.transform.InverseTransformPoint(hit.point);
Debug.Log($"{nameof(localHitPoint)}:{localHitPoint:0.000}");
So what I had expected originally here would be values like
(-0.5, 0.5, 0)----(0.5, 0.5, 0)
| |
| (0, 0, 0) |
| |
(-0.5, -0.5, 0)---(0.5, -0.5, 0)
BUT as you now added: Your plane is rotated!
The 90° on X actually makes that Y and Z switch places. So in order to get the desired Y coordinate you would rather read the localHitPoint.z
.
Then the 180° on Y basically inverts both X and Z.
So I would now expect the values to look like
(0.5, 0, -0.5)----(-0.5, 0, -0.5)
| |
| (0, 0, 0) |
| |
(0.5, 0, 0.5)---(-0.5, 0, 0.5)
Which looks pretty much like the values you describe you are getting. Not sure though why you have a factor of 10 and why you didn't need to switch Y and Z.
However since you actually want the 0,0 to be in the top-left corner you only need to flip the X axis and use Z instead of Y so
fixedLocalHitPoint = new Vector2(-localHitPoint.x, localHitPoint.z);
Debug.Log($"{nameof(fixedLocalHitPoint)}:{fixedLocalHitPoint:0.000}");
Which should now give you values like
(-0.5, -0.5)----(0.5, -0.5)
| |
| (0, 0) |
| |
(-0.5, 0.5)----(0.5, 0.5)
And still you need to scale it up again
var scaledHitPoint = Vector2.Scale(fixedLocalHitPoint, new Vector2 (scale.x, scale.z));
Debug.Log($"{nameof(scaledHitPoint)}:{scaledHitPoint:0.000}");
Which should now give values like
(-32, -18)----(32, -18)
| |
| (0, 0) |
| |
(-32, 18)-----(32, 18)
That's why you need to add the center point as a reference
coords = new Vector2(halfScale.x, halfScale.z) + scaledHitPoint;
Debug.Log($"{nameof(coords)}:{coords:0.000}");
Which now should be
(0, 0)------(64, 0)
| |
| (32, 18) |
| |
(0, 36)-----(64, 36)
I hope this brings a bit more light into where these "strange" values come from.
Since your camera is scaled 1,1,1
and there is nothing else involved I have a hard time finding where the factor of 10 would have sneaked its way into the calculation to be honest.
Upvotes: 2
Reputation: 20249
If you want to convert this:
hit.transform.InverseTransformPoint(hit.point)
which gives this:
(5,-5)---(-5,-5)
| |
| (0,0) |
| |
(5,5)----(-5,5)
to this:
(0,0)-------(64,0)
| |
| |
| |
(0,36)------(64,36)
Why not do this:
Vector2.Scale(
hit.transform.InverseTransformPoint(hit.point) - new Vector2(5,-5),
new Vector2(-6.4, 3.6)
);
This answer hardcodes the (5,-5)
and (-6.4, 3.6)
terms because the question doesn't include enough information to use variables instead.
Assuming the scale of the parent of the plane (Main Camera) is (10,10), then this should suffice:
Vector3 planeScale = hit.transform.localScale;
Vector3 cameraScale = hit.transform.parent.localScale;
result = Vector2.Scale(
hit.transform.InverseTransformPoint(hit.point)
- new Vector2(cameraScale * 0.5f ,-cameraScale * 0.5f),
new Vector2(-planeScale.x * 0.5f/cameraScale.x, planeScale.y * 0.5f / cameraScale.y)
);
Upvotes: 2