Hello everyone!
I have a Scene with the Main Camera that looks at a Mesh. The Mesh texture is a RenderTexture from a second “portal” Camera (nothing fancy here, it’s the usual setup for minimaps or portals).
I need to be able to touch the elements inside the RenderTexture, so I have written this code here:
if (Mouse.current.leftButton.wasPressedThisFrame)
{
Ray ray;
RaycastHit hit;
ray = mainCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
if (Physics.Raycast(ray, out hit) && hit.collider == portalMeshCollider)
{
ray = portalCamera.ViewportPointToRay(hit.textureCoord);
if (Physics.Raycast(ray, out hit))
{
Debug.Log("something inside the render texture was hit " + hit);
}
}
}
and it works, but in order to make it work I first have to turn on/off the convexity of the MeshCollider like this first:
portalMeshCollider.convex = true;
portalMeshCollider.convex = false;
I don’t understand why this is the case and especially I don’t understand if this is a reliable workaround or if there might be problems.
Thanks for your help!
When you instruct a MeshCollider to be convex, Unity generates a new collision shell around the Mesh.
Because of this, it’s no longer a 1:1 representation of that Mesh. If you hit the collider, there’s no longer a correlation between where on the collider you hit and the exact location on the UV coordinate space that you hit.
What it essentially boils down to is:
Is it absolutely necessary to use the UV coordinates to determine where on the Mesh/Collider the Raycast hit?
If the surface is simply a flat plane anyway (or any shape, technically, depending on how much work it will involve), there are other ways you can resolve the relative point of impact of the Raycast.
For an example using a 1x1 quad surface, the point of impact would be something like:
Vector3 localHitPoint = portalMeshCollider.transform.InverseTransformPoint(hit.point);
// If I'm not mistaken, this should be necessary to
// offset into the right local coordinate for Unity's
// "Quad" object, where its pivot point is at its center
Vector3 halfOffset = new Vector3(0.5f, 0.5f, 0.0f);
ray = portalCamera.ViewportPointToRay(localHitPoint + halfOffset);
Thanks for your reply!
The surface I am casting against resembles a flat plane but it’s not 100% flat, as it’s a little curved and can be animated over time. Think of it as a page in a book that can flip left or right or be curved etc. This is the main reason why I was going for the uv approach.
I will later try your approach, but I also wanted to ask if in your opinion having the convex turned on and off could cause issues?
In the end I think I got what was going on: I had disabled “Auto Simulation” and “Auto Sync Transforms” from the Physics tab in the Project Settings so colliders were not updating when I moved or animate them. “Auto Sync Transforms” seems to be enough if physics is not needed.