Creating Sine Waves in Unity

For today’s article, I’ll be going over how I created the double helix shot using 2 sine waves. To see the code of my game, please visit: https://github.com/hlimbo/Space-Shooter-Tutorial

What is a Sine Wave?

A sine wave is a trigonometric function used to model a wave-like pattern. In mathematics, the equation is normally expressed as y = sin(x). The full equation according to Desmos calculator looks like:

  • a = Amplitude which defines the highest point on the sine graph as well as the lowest point. In the graph above, the highest point is at x = PI / 2 and the lowest point is at x = 3 * PI / 2. When this number is negative, the graph will look like the following below:
  • b = controls the frequency of the wave. The closer this number is to 0, the more waves you see on the graph. The further away it is from 0, the less frequent you see the waves on the graph.
  • k = controls the vertical offset of the sine wave. In the graph above k = 0 which means the graph’s points are offset to y = 0. Increasing or decreasing this number will shift the graph up or down respectively.
  • x = angles in radians that help define where its corresponding y position is. For example, when x = 3 * PI / 2, y becomes -1.

To play with the different properties to manipulate the sine function such as stretching the graph vertically, or shifting it vertically or horizontally, please this link to view the Sine Wave above.

Approaching the Problem

In order to create the double helix shot, I approached creating the components using a bottom up approach where I created the Sine Wave Motion Component called SinLaser.cs followed by the Double Helix Shot Component called DoubleHelixShot.cs . The DoubleHelixShot.cs Component is responsible for spawning a bunch of game objects that follow the Sine Wave Motion and the SinLaser.cs is responsible for determining where the bullet moves along the game world at each frame using the Sine Function.

Creating the Sine Wave Motion

To recreate the sine wave in Unity, I need to determine the next x position based on the starting theta (angle in radians) value of the ship. I calculate for the next x position instead of calculating for y like in the sine function formula above because the motion moves vertically along the y-axis and not along the x-axis.

Applying the mathematics behind the Sine Wave above, I was able to come up with the following variables that can be configured to change how the way the sine wave would look when shooting the double helix shot:

Next, I write a few lines of code in the Update() function to determine where the bullet’s x position should be positioned at in a given frame using theta variable:

The code float newXPos = waveDirection * amplitude * Mathf.Sin(theta * waveFrequency) + xOffset is equivalent to the sine function shown above where:

  • waveDirection: controls if the curve should move to the left or right initially.
  • amplitude: controls how wide the sine wave gets along the x-axis.
  • theta: is an angle measured in radians that controls where the next x position should be for the bullet. Angles in radians use PI where the sine wave typically ranges from 0 to 2 * PI and degrees range from 0 to 360 degrees. I don’t check if theta exceeds 2 * PI because the sine wave follows the same up and down pattern in multiples of 2 * PI. So sin(2* PI) = sin(4 * PI) = 0 and sin(PI / 2) = sin(5 * PI / 2) = 1 when the amplitude is equal to 1.
  • waveFrequency: controls how frequent a sine wave cycle starts and finishes.
  • xOffset: controls where the sine wave is initially positioned along the x-axis.

For reference, I attached the SinLaser.cs component onto a game object and created it as a prefab with the following values set:

Double Helix Shot!

In DoubleHelixShot.cs , projectilePairCount controls the number of SinLaser components that get spawned and when this component’s game object gets spawned when the player presses the fire button and has this power-up activated, this component will start a coroutine that will spawn a series of game objects that contain the SinLaser component. Once each SinLaser component leaves the screen’s bounds, its game-object will get destroyed.

I won’t be showing how the player spawns the Double Helix Shot here as it is similar to how the normal and triple shots work. To see how it is spawn through the player, please visit: https://github.com/hlimbo/Space-Shooter-Tutorial/blob/main/Assets/Scripts/Player.cs

Thanks for reading! :)

Software Engineer