Hello everyone. Basically, I want to do something like this:
I know it’s already been asked, specifically in this question:
But the answer (which is “use an animation”) is not what I want to do. I want to do this using Mathematics.
I can easily move an object in a normal sine wave, and a quick “hack” for me to move it in a rotated sine wave was to put the object inside another parent object which was already rotated and then just move its localPosition.
However, I don’t want to do that.
Basically, I have the angle of rotation (and the aiming vector), I’m assuming there’s got to be a way to modify the normal formula for moving the position along a sine wave based on one of these two parameters?
If someone can help me out, I’d really appreciate it!
I'm on my phone, can't type out a full solution, but the straight forward approach is to use the sin(timerate) which will produce a value between -1 to +1 over time. Just translate your object over the Y axis by this value (add in a multiplier to make it move higher and lower). Translate the X value by a constant speed, like time.deltaTimespeed. Translate along the forward vector.
Hmm… this shouldn’t be too bad, really. Have the projectiles take note of where they’re created and their intended direction, then your sine wave can come from the distance the projectile has traveled in that direction, or the time it’s existed.
For a quick idea:
// C#
// Assuming this is a 2D presentation, like the example gif file...
public Vector2 startPosition;
public Vector2 direction;
public float speed;
private float time; // and/or direction
private Vector2 crossDirection; // More important for a 3D approach, but still a good point of reference
void Start()
{
time = 0.0f;
direction = direction.normalized;
crossDirection = new Vector2(direction.y, -direction.x); // A quick right angle for 2D
startPosition = transform.position;
}
void Update()
{
transform.position = startPosition + (direction * speed * time) + (crossDirection * Mathf.Sin(time));
time += Time.deltaTime;
}
That should cover pretty much all the basic concepts. There are many ways to handle it, but the most uniform approaches need the most structure for consistent results.
Edit: Most importantly, I suppose, the key element is your defined direction and it’s crossing direction. Separate those elements out and you can have your distance traveled on a straight line while the perpendicular one defines your sine wave.
Thank you very much! This is what I needed. Just one more thing (sorry to bother you). Where would I add a sine wave amplitude in this formula? What about wave frequency? I'm assuming it's in the section: (crossDirection*Mathf.Sin(time)) But I may be wrong
Yep. I kinda threw in a fairly bare minimum, but you can modify the amplitude of the sine waves and their frequency like this: ... (crossDirection * Mathf.Sin(time * frequency) * amplitude) CrossDirection would be a normalized vector by this implementation, so the width would effectively be doubled, since sine waves range from -1 to 1 (i.e. a range of 2). If you want the width to be literal, you can just halve it in the formula or halve crossDirection at the start instead, if it wouldn't do any harm elsewhere.
I'm on my phone, can't type out a full solution, but the straight forward approach is to use the sin(timerate) which will produce a value between -1 to +1 over time. Just translate your object over the Y axis by this value (add in a multiplier to make it move higher and lower). Translate the X value by a constant speed, like time.deltaTimespeed. Translate along the forward vector.
– supernat