Ink and Lines #3: Clamping UI elements within custom shapes


Here we go again. I've been hard at work with the goal of getting the first full day of the game playable, which I reached a few nights ago. There's a new cutscene system and a main menu, and a working demerit system that triggers game over if you make too many mistakes. 

Here's what the main game screen looks like:


Placeholder art, everything is subject to change. obviously.

The fax machine in the top left is where incoming documents are printed for you to censor. Censored documents are then passed into the fax machine on the right. The dark space in between the fax machines is the desk drawer, which is a space where documents can be dragged for safe keeping out of the way. 

Getting the documents draggable with the mouse was a simple task, but it was fairly easy to lose documents off the edges of the screen. Adding some clamp logic to keep the documents within the screen space was another simple task. Using this function you can keep any target RectTransform within a RectTransform bounds, passing a desired targetPosition where you are attempting to put the target. 


I set the targetWidth and targetHeight differently, according to how my document transforms have their pivot set. (0.5, 1) if you are curious. And this may only work in the case of UI Screen space.

But this is not enough for my case. I want the documents to collide with the fax machines, which as you can see from the screenshot above means I cant use a simple RectTransform to define the bounds where my documents can go. I need to be able to handle a shape of more vertexes, preferably arbitrary, so that I can easily adjust them as needed if I decide to redesign the main game screen. 

At first I thought this meant I would have to do some major geometry refreshing to handle an arbitrary shape of any number of points, but then I came up with a much simpler solution that works for my purposes just as well. The logic for keeping a document within a rect was quite simple, and I realized that I could define the shape I wanted as two separate rectangles. Here is a visualization of the two bounds, in yellow and blue:


By clamping the document within both of those rects, and then only picking the one that is closest, I can make the space my documents are bound to much more complex. All I need is a simple wrapper method calling the method I wrote above to make it work! 


This is fairly hardcoded to my specific case. I only need the two rects, but this could easily be extended to handle any number of bounds. And you could make the checks more efficient by following the logic that if the position remains the same after being clamped to a bounds, then no further bounds need to be checked. Not that this sort of math is going to be a resource hog. 

I went ahead and wrote what that method would look like:


Now I'm pretty happy with the simplicity of this, but it could end up being too limited as well. This only really handles the case of rectangular documents in rectangular bounds, all aligned to the same angle. If I end up needing angled boundaries for some reason then this code will be pretty much useless. But I don't think I'm going to be forced into that corner. 

Anyways, I've been proceeding with filling out content for Day 2 of the game. Once I get to Day 3 there will be a new mechanic for me to add, which I suspect will be the focus of the next devlog. See you then! 

Get Ink and Lines

Leave a comment

Log in with itch.io to leave a comment.