Sine waves
A sine wave has three relevant properties:
Frequency - The inverse of the distance between two peaks of a sine wave.
Amplitude - Is the difference between the peak height of the wave valley.
Phase - It is the part of the sine wave in which an object moving through 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] there is no t
such that (x < t < y
and Mathf.Sin(t) = 1
) and
- [d] for all b
real -a <= Mathf.Sin(b) <= a
.
Therefore, the frequency would be given by 1 / (y - x)
. The amplitude is 2 * a
. The stage is given by t
for the expression f(t)
, where f
is its senoid function (not necessarily its function sin
, for f(x) = 2 * Mathf.Sin(x)
is also a senoid function).
By analyzing your code
You are using the following to set the position of your object:
x = Mathf.Sin (Time.time) * horizontalSpeed;
Its sinusoidal function in the case is f(x) = Mathf.Sin (Time.time) * horizontalSpeed
. The horizontalSpeed
is 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 cycles of 2π seconds and all will be synchronized as the phase of the wave.
The solution is to introduce something that causes them to deviate in phase and frequency.
Also, use FixedUpdate
instead of Update
. The FixedUpdate
has consistent time intervals and is useful to update the game’s logic, while the Update
has more purpose to prepare the 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 frequency
will be the number of times per second you want your object to run a full cycle on the wave (and cannot be zero). The value of the phaseOffset
defines the phase in which the object is when time is zero. These values, you can define a different one for each object or put some random number any, according to what you think best.
I don’t know if I understand this correctly, but if you use an Andom for the movement then each one will have a slightly different behavior. Dai is with you set where you will want to use the Random, whether in position, speed, direction etc....
– Wagner Soares