# Rotating a texture to face the camera with RaycastHit.textureCoord, but it returns Vector2.Zero

Hey folks, I have a scene where I’m rolling a 6-sided die in 3D until it comes to rest in a small cage. The walls all have box colliders + rigidbodies, and the die has a rigidbody + meshCollider. Each face of the die has a texture, and these textures can have a definite “right-side-up”.

What I’d like to do after the die finishes rolling is to rotate the die along the camera’s look vector (Y minus) until the texture on the top of the die is face up. My plan for doing this was to use Physics.RaycastAll() onto the top face of the die at its center and another slightly offset from it in worldspace towards the top of this image, compare the texture coordinates of the two hits, and using the vector between these coordinates I could find the difference in angle between that and the up vector in UV space which should be the same angle I have to rotate to get the texture right-side-up, since all textures are right-side-up in UV space.

However, I can’t seem to get any UV information from my raycasthits onto the die. They are hitting the die object, and the die has a convex MeshCollider (the lack of) which seems to be the common trip-up, however I still get the zero vector for the texture coordinates on each of the raycast hits. The mesh collider also seems to clearly not match the geometry of the mesh, which feels concerning.

Is there any other common reason that RaycastHit would fail to return UV coordinates in an otherwise valid hit? Is there another obvious approach to this that I’m missing? I plan to use this also for 8 and 10 sided dice once I have a generic solution.

“textureCoord” only work with non convex mesh colliders. A convex mesh collider (usually) doesn’t match the actual mesh as it’s a constructed convex hull of the original mesh. Convex mesh colliders specifically are there for the phyiscs system. So the “faces” are actual mathematical bounding planes of a convex volume and have no direct relationship with the visual mesh.

You would need to use a non-convex mesh collider to do the raycasting.

Though I think that this approach is a bit of an overkill just to orient the cube so the face is right side up relative to the camera. It would be way simpler to define 6 local space direction vectors to define the “up” direction for that face. That way you can simply use TransformDirection to get this direction in worldspace when needed and use FromToRotation to rotate the cube the way you want. For a 6-sided die this would be trivial. For higher valued dice it would be more complicated. Some time ago I made a script for multi-sided die and a little editor helper to setup the faces / normals of each face. It doesn’t have the face orientation at the moment, but it could be specified in a similar way. Of course you could make a script to define the up direction for each face based on the UV coordinates. However not every face of such an die necessarily is aligned with the UV axis, especially when we talk about D12, D4, D20 dice. though even D6 does not necessarily arrange each face with the right side up in texture space. Of course you could do that for your own meshes, but that would limit your script to only work with such specific meshes. Manually aligning the up vectors for each face is trival for a D6 but get more difficult for higher dice and pretty much impossible for D4 / tetrahedron.

2 Likes

I also once made a little dice script that you can find over here .

1 Like

Thanks for the input folks. Sounds like I should take a different approach. Looking at Zulo3d’s link, I think I’ll do something similar to what the OP posted and have some invisible objects per face that have the forward vector I need in local space.
Cheers!