Icosahedral Dice Value Mechanic

I was playing with an icosahedral dice roll mechanic and then came time to read the value facing upwards. I could do a read by decomposing the mesh collider into 20 triangles and read the face value once it collided with the surface it rested on, subtract it from 21 and that would be the dice’s readout value. However that does not seem like an elegant setup. It seems it can’t be derived from the euler rotations as the same face up can have multiple rotation values per axis. Conversely another method would be to use 20 child null situated at the center of each face and when the dice has come to rest, read the topmost transform position to derive the value. Anybody got anything better/more elegant/single component for this?

Since it is a euclidean solid, you can locate colliding face mathematically.

Basically, the dumb and simple way would be to precompute NORMALS for all faces (in object space, obviously), store them in array, then convert vector towards the ground into object space, and find the face with highest dot product value. It can be a linq one-liner with bunch of allocations, or an old fashioned loop with no allocations. Doesn’t matter. It will also work with ANY convex solid. But you’ll need to precompute face normals.

Obviously that would need to be accompanied with a DrawGizmo overload to make sure the faces match geometry.

Off the top of my head, I can’t think of a more elegant way to do it, although you can probably try to optimize search function with something like a BSP (It is probably not worth it)

6904760--808535--upload_2021-3-5_18-18-11.png

4 Likes

Also instead of “vector towards ground” you can use ground normal, but in this case, since direction is reversed, you’ll need to find a face with the lowest dot product value (closest to -1). The principle is the same.

2 Likes