top of page

Making the shadows tangible

  • Shade Game
  • Mar 6, 2019
  • 3 min read

One of the hardest challenges in making Shade was to implement one of its most crucial mechanics: shadows that serve as platforms.


The first step of this process was to find the appropriate lighting for the scene. The default light is the directional one, which behaves like ambiant lighting in real life (ie: the sun, or a ceiling light), but it's also quite boring: no matter where you move an object in the scene, the size of its projection is always the same. A more fun one to play with is the spot light, which behaves exactly like a flashlight: objects' shadows grow or shrink as they get closer or further away from the source of light, and they get deformed when moving sideways. It allows for a more interesting design.


At this stage, the shadows are still only visual: they're as boring as in the real world. Our little shadow character will pass through them. So how do we give them a physical representation in the game? The answer might be simpler than you think! (Spoiler alert: it's not.)


What we'll do is basically cast raycasts from the source of light to the wall in the back, passing through each vertex of each object. Those raycasts will tell us where they hit the wall, which will correspond to the vertices on the shadow projections.



What we're aiming at


Before anything else, we need to get the positions of the vertices of a mesh. While looking online for a way to do it, I found a handy built-in Unity function that returns all the vertices of a mesh (it's simply Mesh.vertices). Cool! Something less to program ourselves...


...except that it doesn't work. Or rather, it doesn't work the way we need it to work for Shade. It returns way more vertices than needed. For instance, on a simple cube, it will identify 24 vertices, although it only makes sense to get 8 vertices (one for each corner of the cube). Why does it do that? Because in order to do the normals and UVs, Unity needs 4 vertices per side (4 vertices X 6 sides = 24 vertices). Honestly, I don't know why that is, but I'm just happy to know there is a reason and that it somewhat makes sense. As much as I would like to dig more this mystery, there is a game that needs to be done after all, and I prefer putting my energy in finding something that actually works.


Then if we cannot rely on what Unity provides us, we have to code the search of vertices ourselves. Turns out the algorithm for this is not too hard to figure out. Somewhat high-level explanation of it: starting from the center of our object (as given by transform.position), we go to half of its width (to the left or to the right), half of its height (upward or downward) and then half of its depth (forward or backward). If we do and store all 8 combinations, we have all our vertices. Of course, this works only for rectangular prisms, but this will work fine with the way we implement objects in our game (maybe more on that in a later blog post).


We test... and it works! It even works if we change the position of the object, or if we rescale it... but not if we rotate it. Bummer.



What a mess


What can we do then? Cry for help. I mean, ask our teacher for guidance. And with him on our side, we discover yet again a built-in Unity function, that is Mesh.GetVertices. Cool. And this one actually works the way we need it to, returning the right amount of vertices. Cooler! And it works with changing the position, the size or even the rotation. COOLEST!



This is what relief looks like


Now that we have our precious vertices, we are ready to move forward to the next (and most crucial) step: create meshes from them, as if we were extruding the shadows from the wall. And that, our beloved fans, is a fun and complicated process we'll keep for the next blog post.



It even works on a banana peel

 
 
 

Comments


Thanks for submitting!

© 2019 by SHADE

Sign Up for News, Events and Much More!

bottom of page