Devlog #1 - You Spin Me Right Round


Intro

Since one of the central mechanics of the game is playing back audio recordings, I obviously needed to add tape reels to the UI.

Even though I doubt anyone will just sit there and stare at the widget, I still wanted the feature to work as realistically as possible. I probably could've gotten away with hardcoding some parameters, but I knew that it would annoy me down the line and it would probably have taken me ages to tweak the parameters to get the desired result.

I identified three problems that I needed to solve. Considering a specific point in the recording, I needed to know:

  1. How much tape is on each reel
  2. How fast should each wheel rotate
  3. How to draw the lines representing the tape itself

1) How much tape is on each reel

First of all, to draw one reel I use three sprites.


Then, to change how much tape is on the reel, I just scale the tape sprite. I have a minimum and maximum radii exposed in the editor, which dictate how much to scale the sprite when there is no tape on the reel and when the reel is full.


So far so good. Next thing to do is to normalize the recording playback time.

normalized_time = playback_time / recording_duration

Easy enough. We get a value from 0 to 1 which we can use for various interpolations.

Now, the question remains: how big should the sprite on each wheel be at a given moment in the recording?

Simplest thing to try is to use the normalized time to interpolate linearly between the minimum and maximum radii of the tape sprite.

For the right wheel I use the normalized_time directly, and for the left wheel I use 1 - normalized_time to invert the process.


That's not bad, but we can do better.

If you think about it, when the wheels spin, they transfer the tape from one to the other at a constant rate. Also, the total amount of tape on both reels remains unchanged.

Another way you can look at it is that the volume of tape stays the same. Except in out case, since this is just in 2D, we can simplify and swap volume with area.

So the solution is to interpolate between the min_area and max_area of the tape (calculated based on the minimum radius and maximum radius respectively). The current radius can then be calculated based on the interpolation result.


And this is what we get:


The change is subtle, but it makes a difference. The tape sprite grows more quickly when the spool is empty, and then eases out as it fills. It's more noticeable at slower speeds.

2) How fast should each wheel rotate

One obvious thing about reel-to-reel tape players is that the wheel which currently has less tape on it spins faster than the other one. Makes sense, since the same amount of tape needs to unwind from a smaller spool.

Again, I could emulate this using a curve and some other parameters, but that would've bugged me. So let's think about this a bit.

Consider the following:


The green outer circle is the maximum radius of the tape, the red is the radius at the current point in time in the recording, and cyan is the minimum radius.

The tape moves from one wheel to the other at a constant rate. Let's call tape_distance the amount of tape that moves from one reel to the other in one second . Also, let's consider the tape is full, which means its radius is max_radius. How much does the wheel rotate in one second?

We can use the formula for the arc length of a circle:


So if we translate this to our problem:

tape_distance = max_radius *  max_spin_amount

Alright, we're getting there! Now let's ask the same question for when the tape is at an arbitrary radius (the red circle). Let's call this current_radius. How much does it rotate in one second? We can start with the same formula.

tape_distance = current_radius * current_spin_amount

Let's rearrange it, since what we're trying to find is current_spin_amount.

current_spin_amount = tape_distance / current_radius

If we expose tape_distance in the editor, then job done! That's out formula. However, it would be difficult to tweak. Instead It would be easier to tweak how fast the wheel spins when it's full and let the math handle it from there.

We can replace tape_distance with its equivalent from the first formula, and what we get is:

current_spin_amount = max_spin_amount * max_radius / current_radius

max_spin_amount and max_radius are exposed in the editor, and current_radius is already calculated in step 1. 

Here's the result:


3) Line drawing

This is the final problem we need to solve and surprisingly this one requires the most math.

I'm not going to go into too much detail about the math since this article already covers it very well.

Needless to say, I took that and went a little overboard with it and made a custom tool that automatically calculates the tape path from wheel to wheel (because as you may notice, there are also smaller wheels along the way). My reasoning was that this way I can configure the smaller wheels however I want and it would all just work. In reality, I just enjoyed coding it.

Here's what the editor scene GUI look like:


Each one of those circles represents an anchor along the tape path, and it has a couple of configuration parameters:


I can set an anchor to be represented by a point (like the two to the left and right of the display). In this case the line will just be draw to/from the center of the anchor.

The winding direction dictates which type of tangent to use between and anchor and its neighbors (out of the 4 described in the linked article).

  • CW to CW: outer tangent 1
  • CW to CCW: inner tangent 1
  • CCW to CW: inner tangent 2
  • CCW to CCW: outer tangent 2

The math use to determine which outer/inner tangent to use is a bit more complex and I won't go into it in this devlog.

Each frame I set the radius of the first and last circles in the custom tool, and it automatically recalculates the tangents.

As for drawing the actual in-game lines themselves, I used Vectrosity since it offered support for drawing lines on Canvas layers, which the built-in Unity LineRenderer does not.

Conclusions

Well there you have it. If you ever needed to simulate a reel to reel tape player GUI, now you know how to do it. Or at least my approach to it.

How you found this insightful and stay tuned for more!

- Zouru

Get Brugvik Demo

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.