Patrolling GameObjects
When you want a certain GameObject to follow a path constantly, you first need to create Waypoints: which meas that you need to create Empty GameObjects and make them Prefabs.
At first they will not be visible, but by adding the following code you will be able to see them in your scene Waypoint:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Waypoint : MonoBehaviour { public Waypoint[] neighbors; //el waypoint se hace un Prefab, porque todos necesitan el mismo //comportameinto (son iguales) public List<Waypoint> history; //how did we get here, who was before me, for each one public float f, g; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } //GIZMOS void OnDrawGizmos(){ //visable thru the editor Gizmos.color = Color.blue; Gizmos.DrawSphere (transform.position,.5f); Gizmos.color = Color.yellow; for(int i=0; i < neighbors.Length; i++){ Gizmos.DrawLine (transform.position, neighbors [i].transform.position); } } void OnDrawGizmosSelected(){ Gizmos.color = Color.red; Gizmos.DrawSphere (transform.position,.5f); } }
Now you will need to add Neighbors to each one of the Waypoints in to know who are they connected to:
You will need to create a GameObject that will be the one to follow that path and Add the next script.
Usual Script:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Patrol : MonoBehaviour { public Waypoint[] path; public float threshold; private int current; //--------- // Use this for initialization void Start () { current = 0; } // Update is called once per frame void Update () { transform.LookAt (path [current].transform); transform.Translate (transform.forward * Time.deltaTime * 3, Space.World); float distance = Vector3.Distance (transform.position, path[current].transform.position); if (distance < threshold) { current++; //asi con este solo hace una vuelta. current %= path.Length; } } }
-Special CASES
For objects that come out of another GameObject (Base) you'll need to attach this script to the GameObject that will follow the path. It also contains an Object Selector that changes color of the object once it's been selected.
Special Script (Patrol):
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Patrol : MonoBehaviour { public Waypoint[] path; public float threshold; private int current; //--------- // Use this for initialization void Start () { current = 0; } // Update is called once per frame void Update () { transform.LookAt (path [current].transform); transform.Translate (transform.forward * Time.deltaTime * 3, Space.World); float distance = Vector3.Distance (transform.position, path[current].transform.position); if (distance < threshold) { current++; //asi con este solo hace una vuelta. current %= path.Length; } if (Input.GetMouseButtonDown(0)) { var selected = false; var ray = Camera.main.ScreenPointToRay(Input.mousePosition); if(Input.GetMouseButtonDown(0)) { if(Physics.Raycast(ray, 100)) { Debug.Log("Selected"); gameObject.GetComponent<Renderer> ().material.color = Color.green; print (gameObject.name); } }else{ Debug.Log("Unselected"); } } } void Camino(Waypoint[] w){ this.path = w; } }
You will need to make this GameObject a prefab and you won't need to add the Waypoints to this object.
Now you'll need to create a Base that when you click on it, it will generate you're GameObject that will follow the path that you have established with your Waypoints.
Add the following script Base.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Base : MonoBehaviour { public GameObject original; public Waypoint[] caminito; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (Input.GetMouseButtonUp(0)) { // Ray from the mouse Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { if (hit.transform.gameObject.CompareTag("Base")) { GameObject clone = Instantiate(original, transform.position*(2), transform.rotation) as GameObject; clone.SendMessage ("Camino", this.caminito); Rigidbody rb2 = clone.GetComponent<Rigidbody>(); } print(hit.transform.name + " " + hit.point); } } } } Now that you have a GameObject as your Base, you will need to add it a tag called Base.
And for Now you're pretty much done!.
Next...
You will need to create a GameObject that becomes you're enemy and add the following Enemy script to it.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class enemy : MonoBehaviour { private AState current; private ASymbol p,a; private MonoBehaviour currentBehaviour; double distancia; public GameObject original; public Waypoint[] area; public Vector3 vector = new Vector3(0f, 0f, -16f); // Use this for initialization void Start () { AState patrullando= new AState("patrullando", typeof(Patrol2)); AState atacando = new AState("parado", typeof(Atacando)); //Patrol patrol = GetComponent<Patrol>(); //patrol.SendMessage("Camino",area); p = new ASymbol("patrulla"); a = new ASymbol("ataca"); patrullando.AddTransition(a, atacando); atacando.AddTransition(p,patrullando ); current = patrullando; currentBehaviour = gameObject.AddComponent(current.Behaviour) as MonoBehaviour; } // Update is called once per frame void Update () { /*0distancia = Vector3.Distance(this.tranform.position,); if () { }*/ } public Waypoint[] Area{ get{ return area; } } }
And also the scripts AState, ASymbol y Atacando, Patrol2 (not to the enemy, just create them):
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class AState : MonoBehaviour { private Type behaviour; private string name; public Animator animador; //each of the states needs to know where to go Dictionary<ASymbol, AState> transition; //property //-equivalen to get/set methods public string Name { get{ return name; } } public Type Behaviour { get { return behaviour; } } public AState(string name,Type behaviour){ this.name = name; this.behaviour = behaviour; transition = new Dictionary<ASymbol, AState>(); } public void AddTransition(ASymbol key, AState value) { transition.Add(key, value); } public AState ApplySymbol(ASymbol key) { if (transition.ContainsKey(key)) { return transition[key]; } return this; } }
ASymbol:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ASymbol : MonoBehaviour { private string name; public string Name{ get { return name; } } public ASymbol(string name) { this.name = name; } }
Atacando:
this script doesn't have nothing, just create it :)
Patrol 2:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class Patrol2 : MonoBehaviour { public Waypoint[] path; public Transform [] WaypointObjects; public float threshold; //other; private int current; private GameObject other; // Use this for initialization void Start() { current = 0; threshold = 0.5f; WaypointObjects= new Transform[2]; WaypointObjects[0] = GameObject.Find("GameObject (5)").transform; WaypointObjects[1] = GameObject.Find("GameObject (6)").transform; } // Update is called once per frame void Update() { transform.LookAt(WaypointObjects[current]); transform.Translate(transform.forward * Time.deltaTime * 10, Space.World); float distance = Vector3.Distance(transform.position, WaypointObjects[current].position); if (distance < threshold) { current++; current %= WaypointObjects.Length; } } void Camino(Waypoint[] w) { this.path = w; } }