Skip to content

Instantly share code, notes, and snippets.

@alkemann
Last active February 14, 2016 15:01
Show Gist options
  • Save alkemann/3106c3172547204f9506 to your computer and use it in GitHub Desktop.
Save alkemann/3106c3172547204f9506 to your computer and use it in GitHub Desktop.
Worker AI picking jobs and moving to them using Coroutines without any Frame Update calls
using UnityEngine;
public class Job {
public GameObject site;
public float workload = 3f;
public Job (GameObject site, float workload) {
this.site = site;
this.workload = workload;
}
}
using UnityEngine;
using System.Collections;
public class Site : MonoBehaviour {
bool has_job = false;
void Start(){
StartCoroutine (causeTrouble ());
}
IEnumerator causeTrouble() {
while (true) {
// Start off waiting a random amount of time before first job needs to be done
float time_until_next_work_needs_to_be_done = UnityEngine.Random.Range(5f, 7f);
yield return new WaitForSeconds (time_until_next_work_needs_to_be_done);
// something needs to be done
this.CreateJob();
// wait until some other process has completed the job, then contineue
yield return new WaitUntil(() => {return has_job == false;});
// job is done when we come here
// start over at the top
}
}
void CreateJob () {
has_job = true;
GameObject indicator = transform.FindChild ("Indicator").gameObject;
indicator.SetActive (true);
GameObject.Find ("Worker").GetComponent<Worker> ().jobs.Push (new Job (gameObject, 1f));
}
public void completeJob() {
has_job = false;
GameObject indicator = transform.FindChild ("Indicator").gameObject;
indicator.SetActive (false);
}
}
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
public class Worker : MonoBehaviour {
public Stack<Job> jobs;
Job activeJob;
void Start () {
jobs = new Stack<Job> ();
StartCoroutine (ai ());
}
IEnumerator ai () {
while (true) { // continue for ever
// Wait until there is a job to find
yield return new WaitUntil (() => { return jobs.Count > 0; });
// Grab the top job
activeJob = jobs.Pop ();
// Are we near enough the job to do the work?
yield return new WaitWhile (() => {
Vector3 distance = activeJob.site.gameObject.transform.position - gameObject.transform.position;
if (distance.magnitude < 0.5f) {
return false;
}
Vector3 move = new Vector3 (distance.x * Time.deltaTime, 0, distance.z * Time.deltaTime);
gameObject.transform.Translate (move);
return true;
});
// Simulate working by "waiting"
yield return new WaitForSeconds (activeJob.workload); // spend workload amount of seconds working
// Tell the site that the job is completed
activeJob.site.GetComponent<Site> ().completeJob ();
// Throw away active job since it was completed
activeJob = null;
// To back to start
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment