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:

[25495-new+doc_1+(16).jpg|25495]

Any idea on how to make a C# script for this movement?

Thanks in advance,

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:

25497-sin.png

Linear movement is as easy as:

public class LinearMovement : BaseMovement
{
	protected override float GetY()
	{
		return velocity.y;
	}
}

For a circular movement, check this out.

Thank you it is very helpfull, but the Trail Trapped me :stuck_out_tongue: my Unity Is now bugging X_X.

Thanks A lot , it work like a champ.