After spending the last week tearing my hair out trying to make a spiral that matched the image I had in my mind, I feel like I’m starting to identify with some of the characters from that old Junji Ito body-horror comic.
I started working on the layout for the character screen, and realized that I really didn’t have a plan for portraying skill points and stats. In the game, they’re represented by dice just like in Mini Six, the tabletop system I created the (current iteration of the) story in. However, I don’t want it to feel like the digital version of a tabletop game- I want it to just be a story-driven game. Nothing against Baldur’s Gate, or anything else that integrates mechanics from roleplaying games into their stats, but I think that sort of thing narrows the audience down a little bit.
So I needed a way of representing the values of skills and stats. In this system, each skill is associated with a stat, and the points you put into that skill are additive with the base state when it comes time to “roll a check.” For example, the character might have 3D+1 (three six-sided dice plus one pip) in Might, and then they’ve added an additional 1D+1 into their Brawling skill. The next time they try to punch someone, they get to roll four dice and then add 2 to the result (since Brawling relies on Might). Initially, I thought about just showing some large symbol as a dice, and then fractions of that symbol to represent pips (three pips equal one dice, since the average roll on a six-sided dice is going to be about 3), but that just didn’t feel unique enough- it reminded me of health and pieces-of-heart from the Zelda games.
Next I considered just a single bar, with all the dice converted into pips for a single number. The “stat” pips could be shown in one color, and then the skill pips would get added to the end of the bar in a different color. I felt like this was a closer representation of the actual value, but even less unique as far as roleplaying and stat-based characters go.
Eventually I settled on cross between the two- each pip could be represented by a symbol that linked to itself, and they’d spiral around an icon that represented that particular stat. When the character earned pips, (for “leveling up”) I could just show it as whatever symbol I ended up using to represent the pip in the dialogue box. Now I just had to find some symbol that would tesselate into a spiral like that. I was picturing something like a hexagon, but smushed so that its “inner” sides were smaller than its “outer” sides. I spent hours looking for something that would work, with the constraint that I didn’t want the symbols on the outer radii to be significantly larger than the inner ones- that would imply that the skill points you earn at higher levels might be “worth more” than skill points at lower levels, and that’s not what I wanted to convey.
There just doesn’t seem to be any such shape- I’m sure it’s some sort of mathematical constraint, but it felt weird to be able to sort-of picture it in my mind but not be able to get it down on a piece of paper or find anything similar in Google Images. I finally settled on using just a regular spiral, but with segments of equal arc-lengths and thickness. I could still color them differently to indicate stat vs. skill, though I’d lose out on showing that symbol when the characters earn skill points (probably not that big of a deal in the long run). Something like this is what I was picturing now, and it felt much more reasonable:
Apparently, though, I completely underestimated how difficult it would be to reproduce this in Unity. First, I ended up having to use the LineRenderer object to get anything like this at all (unless I wanted to have a million different sprites to piece together every time I wanted to create a spiral). Unfortunately, it looks like the LineRenderer isn’t really intended for UI objects, and doesn’t work on canvases that are shown as an overlay (which took a while to realize), so I ended up having to create a new Canvas in camera space instead to draw everything on.
Drawing the actual spiral is actually very simple- I wanted an Archimedes spiral, where the distance between the coils doesn’t change as the spiral gets larger and larger. That’s a simple formula in polar coordinates, and converting polar to cartesian is no big deal. The tricky part, it turned out, was getting segments of equal arc-lengths. The formula for calculating the arc length of a portion of an archimedes spiral is… daunting:
It’s complicated because it involves integrals of trigonometric functions and exponents- this isn’t something I wanted to attempt in Unity. I found someone who came up with an estimate based on radius by assuming a circle instead of a spiral, but it didn’t work out very well for me. In the end, I finally just cobbled my own equation together based on trial and error- it’s definitely not a mathematically-accurate formula for calculating anything useful, but on the scale I was working in, it gave me a visual approximation of equal-ish arc-lengths:
Now it was just a matter of prettying it up. It was no trouble at all telling it to draw the different segments in different colors/materials based on whether that segment was part of the base stat or part of the skill points. I generated another spiral behind the whole assembly that was just black in color, and sized so that it would look like an outline for the segments. Then, in front, I placed a round image with an icon representing the base stat. Easy-peasy, right?
Except I started getting caught up in how Unity draws LineRenderer objects again. That second Canvas object I made to hold the spiral worked great up until I added the stat icon- for whatever reason, that icon seemed to completely ignore the “sorting order” I created for the UI components, and rendered behind the spiral instead of in front of it. I spent days modifying layers, render priorities in materials, sorting orders, adding/removing/modifying canvases and camera settings- something about the LineRenderer object just threw everything off, and nothing was acting quite the way I expected it to (after checking out Unity forums, it looks like I wasn’t the only one disappointed in how hard it was to work with LineRenderers).
I did eventually get everything working, though I had to go back and redo all my calculations for “is the mouse cursor hovering over this object or piece of text” because I had to drag all my UI objects out of the “overlay” mode and into “camera space” instead. And so I finally have a spiral that renders the way I wanted it to, after an entire week of messing around with it. Time well-budgeted? Probably not. But it’s a good-looking result:
This spiral would represent an Agility-based skill. 9 total pips in the Agility stat (which is 3D of dice) and an additional 4 pips in the skill itself, for a total roll of 4D+1 whenever the skill is used.
I guess it’s a good thing I’m not under any sort of deadlines.