2D Using C# moving game object back and forth and random stop in between - all in x-axis

Hi all,

I’m currently learning on how to use C# script to randomly spawn enemy objects that always spawn from right side of the screen in x-axis. After spawn, it will move towards left side of x-axis until it reach a coordinate specified in my C# script, it will turn around and move different direction.
This is working fine but, I would like to have the random spawned enemy objects to pause/stop in between the x-axis after 5 seconds before it continue to move on…

Any advise?

Current code implementation:

public class EnemyA : MonoBehaviour {
	private Vector3 MovingDirection = Vector3.left;	//initial movement direction

	// Use this for initialization
	void Start () {
	}
	
	// Update is called once per frame
	void Update () {	
		UpdateMovement ();
	}

	void UpdateMovement(){
		if (this.transform.position.x > 2.4f) {
			MovingDirection = Vector3.left;
			gameObject.GetComponent<SpriteRenderer> ().flipX = true;

		} else if (this.transform.position.x < -2f) { 
			MovingDirection = Vector3.right;
			gameObject.GetComponent<SpriteRenderer> ().flipX = false;

		} 
		this.transform.Translate (MovingDirection * Time.smoothDeltaTime);
	}
}

FYI, the animator of the said game object representing the enemy AI is having the default as walking (instead of idle). Hence, the code above contains flipX changes.

In the Start method, keep a float value that you initialize to 0.
In the Update method, add Time.deltaTime to this float value and then check if the value is grearter than 5. If it is, do not call UpdateMovement, else call UpdateMovement.

As for the animations, add a boolean parameter “IsMoving” in your animator. Add a transition from Idle to Moving states when the parameter is set to true. Add a transition from Moving to Idle states when the parameter is set to false. Set the moving state as default.

In Update method, in the condition you added, set the parameter to true or false as wanted.

Ok, here is the concept and then follow by sample codes of that works well - allowing objects to move from point A to point B and at the same time stop in between …but this code have a fix waiting time for each stops.

Let say you want to have 2 stop points along x-axis (exclude spawning/starting point), create 2 empty game objects. Name it accordingly, such as point1 and point2. If you want more stopping points, create more. For this example, let say you just need 2.

Create another empty game object. Lets say we call this Enemy1Stuff. The previous game character/enemy character, just drag it to be subset/under this new empty game object. Do the same for the 2 points (point1 and point2).

This will looks like this in your Hierarchy:
Enemy1Stuff
->Enemy
->point1
->point2

Set the coordinates for point1 and point2 accordingly …let say point 1 is the 1st stopping point (0,0,0) and 2nd stopping point (-3,0,0).

Add/Change the Enemy script to following:

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {
	private const int ANIM_STATE_IDLE = 0;
	private const int ANIM_STATE_WALKING = 1;
	private const int ANIM_STATE_ATTACK = 2;
	public Transform[] patrolPoints; 
	public float speed;
	public float distance;
	int currentPoint;
	Animator anim;
	SpriteRenderer sprite;

	// Use this for initialization
	void Start () {
		anim = GetComponent<Animator> ();
		sprite = GetComponent<SpriteRenderer> ();
		anim.SetInteger ("state",ANIM_STATE_WALKING);	//to force initial animation to walking
		StartCoroutine ("Patrol");
	}
	
	// Update is called once per frame
	void Update () {
		RaycastHit2D hit = Physics2D.Raycast (transform.position, transform.localScale.x * Vector3.left, distance);//needed to check in front of him got any object

		if (hit.collider != null && hit.collider.tag == "Player") {
			//GetComponent<Rigidbody2D> ().AddForce (Vector3.up * 100);
			anim.SetInteger ("state", ANIM_STATE_ATTACK);
			StopCoroutine ("Patrol");
		}
	}

	IEnumerator Patrol(){
		while (true) {	//this is to make sure this method is infinite loop
			if (this.transform.position.x == patrolPoints [currentPoint].position.x) {
				currentPoint++;

				anim.SetInteger ("state", ANIM_STATE_IDLE);
				yield return new WaitForSeconds (2);	//once it rech the point, stop for a while 1st
				anim.SetInteger ("state",ANIM_STATE_WALKING);

			}

			if (currentPoint >= patrolPoints.Length) {

				currentPoint = 0;	//reset it to zero
			}

			this.transform.position = Vector2.MoveTowards (this.transform.position, new Vector2 (patrolPoints [currentPoint].position.x, transform.position.y),speed);

			if (transform.position.x > patrolPoints [currentPoint].position.x) {
				sprite.flipX = true;
				//transform.localScale = new Vector3 (1,1,1);	//either 1 of this method will change the rotation of the object

			} else if (transform.position.x < patrolPoints [currentPoint].position.x) {
				sprite.flipX = false;
				//transform.localScale = new Vector3 (-1,1,1);

			}

			yield return null;	//this will tells this method to execute the above code again once next frame started
		}
	}

	void OnTriggerEnter2D(Collider2D coll){
		

	}

	void OnDrawGizmos(){
		Gizmos.color = Color.red;	//for visual debugging purpose
		Gizmos.DrawLine(transform.position,transform.position + transform.localScale.x * Vector3.left * distance);
	}
}

You can ignore the RayCast and Rigidbody as those are optional for this…just part of the incomplete code I want to share it here.

Back to Unity editor, drag the point1 and point2 to the Enemy Script in Inspector. Hope this helps …for those need it for future reference.