Sine waves
A sine wave has three relevant properties:
-
Frequency - This is the inverse of the distance between two peaks of a sine wave.
-
Amplitude - It is the difference between the peak height of the wave valley.
-
Phase - It is the part of the sine wave in which an object that moves by it is.
For example, let's assume that x
and y
are two consecutive wave peaks, so that:
- [a] x < y
,
- [b] Mathf.Sin(x) = Mathf.Sin(y) = p
,
- [c] does not exist t
such that ( x < t < y
and Mathf.Sin(t) = 1
) and
- [d] for all b
real -a <= Mathf.Sin(b) <= a
.
Thus, the frequency would be given by 1 / (y - x)
. The amplitude is 2 * a
. The phase is given by t
to the expression f(t)
, where f
is its senoid function (not necessarily the sin
function itself, since f(x) = 2 * Mathf.Sin(x)
is also a senoid function).
Analyzing your code
You are using the following to define the position of your object:
x = Mathf.Sin (Time.time) * horizontalSpeed;
Its sinusoidal function in this case is f(x) = Mathf.Sin (Time.time) * horizontalSpeed
. The horizontalSpeed
ends up being the amplitude. The phase is given by Time.time
and the frequency is 2π seconds . This means that your objects will have a position that always oscillates in 2π seconds cycles and all will be synchronized as the wave phase.
The solution is to introduce something that causes them to become out of sync with the phase and how often.
In addition, use FixedUpdate
instead of Update
. %% Of% has consistent time intervals and is useful for updating game logic, while FixedUpdate
is mostly intended to prepare rendering on the screen.
Resulting code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy4 : Nave {
public float horizontalSpeed;
public int yFactor;
public float frequency;
public float phaseOffset;
private float count = 3;
private Vector3 s;
private bool setPos = false;
private float x;
private float y;
void Start() {
x = 0;
y = 0;
s = transform.position;
side = Side.defside.ENEMY;
}
void FixedUpdate() {
y += yFactor * Time.deltaTime;
x = Mathf.Sin(Time.time * frequency / Mathf.PI + phaseOffset) * horizontalSpeed;
transform.position = s + new Vector3(x, y, 0);
}
}
The value of Update
will be the number of times per second that you want your object to cycle through a full cycle in the wave (and can not be zero). The value of frequency
defines the phase in which the object is when the time is zero. These values, you can set a different for each object or put some random number whatever, according to what you think best.