- Home /
Bat sine movement 2d Game help
I have been trying to get one of the enemies in my 2d game to make a movement similar to the one described in the picture below:

Any idea on how to make a C# script for this movement?
Thanks in advance,
Answer by vexe · Apr 21, 2014 at 07:59 AM
Hi - So I wrote this movement script in one of our jams. It's object-oriented so you could easily create and plug-in other types of movements like Linear, Circular, etc.
Here's the base movement class, from which you could inherit, override GetY to get your custom movement behaviours:
using UnityEngine;
public abstract class BaseMovement : MonoBehaviour
{
public float minSpeed = 20f;
public float maxSpeed = 100f;
public float minInitialOrientation;
public float maxInitialOrientation;
protected float speed;
protected Vector3 velocity;
protected Vector3 direction;
protected Transform mTransform;
protected Transform cachedTransform { get { if (!mTransform) mTransform = transform; return mTransform; } }
protected virtual void Move()
{
velocity.y = GetY();
cachedTransform.localPosition += (velocity + direction) * Time.deltaTime * speed;
ReactToEdges();
}
protected virtual void ReactToEdges()
{
Vector3 viewPos = Camera.main.WorldToViewportPoint(cachedTransform.position);
// Ping pong between the edges of the screen. If we touched an edge, we reverse the movement direction
if (viewPos.x <= 0 || viewPos.x >= 1) // left/right edges, reverse the x coord for the direction vector
direction.x = -direction.x;
if (viewPos.y <= 0 || viewPos.y >= 1) // bottom/upper edges, reverse the y coord of the direction vector
direction.y = -direction.y;
cachedTransform.position = Camera.main.ViewportToWorldPoint(viewPos);
}
protected virtual void Start()
{
speed = Random.Range(minSpeed, maxSpeed);
InitDirection();
}
protected virtual void Update()
{
Move();
}
protected virtual void InitDirection()
{
// give random orientation
float randZ = Random.Range(minInitialOrientation, maxInitialOrientation);
direction = Quaternion.Euler(0, 0, randZ) * cachedTransform.right;
}
protected abstract float GetY();
}
In your case, you want sine movement, so (attach this to your bats):
using UnityEngine;
using System.Collections;
public class SineWaveMovement : BaseMovement
{
[SerializeField]
private GameObject trail; // just for fun
[SerializeField]
private float frequency = 1f;
[SerializeField]
private float wavelength = 1f;
protected override float GetY()
{
// try and mess with some of the values here to see what dif results you get...
return Mathf.Sin(2 * Mathf.PI * Time.time * frequency) * wavelength;
}
protected override void Move()
{
base.Move();
StartCoroutine(CreateTrail());
}
private IEnumerator CreateTrail()
{
if (trail != null)
{
var tObj = Instantiate(trail, cachedTransform.position, cachedTransform.rotation);
yield return new WaitForSeconds(3f);
Destroy(tObj);
}
}
}
Resulting movement:

Linear movement is as easy as:
public class LinearMovement : BaseMovement
{
protected override float GetY()
{
return velocity.y;
}
}
For a circular movement, check this out.
Hey thank you but how to control trail instantioation? please
Answer by Aziz1989 · Oct 18, 2015 at 09:05 AM
Thank you it is very helpfull, but the Trail Trapped me :p my Unity Is now bugging X_X.
Your answer