using UnityEngine;
using System.Collections.Generic;
using Pathfinding.RVO;
using Pathfinding.RVO.Sampled;
namespace Pathfinding.Examples {
///
/// RVO Example Scene Unit Controller.
/// Controls AIs and camera in the RVO example scene.
///
[HelpURL("http://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_examples_1_1_group_controller.php")]
public class GroupController : MonoBehaviour {
public GUIStyle selectionBox;
public bool adjustCamera = true;
Vector2 start, end;
bool wasDown = false;
List selection = new List();
Simulator sim;
Camera cam;
public void Start () {
cam = Camera.main;
var simu = RVOSimulator.active;
if (simu == null) {
this.enabled = false;
throw new System.Exception("No RVOSimulator in the scene. Please add one");
}
sim = simu.GetSimulator();
}
public void Update () {
if (adjustCamera) {
//Adjust camera
List agents = sim.GetAgents();
float max = 0;
for (int i = 0; i < agents.Count; i++) {
float d = Mathf.Max(Mathf.Abs(agents[i].Position.x), Mathf.Abs(agents[i].Position.y));
if (d > max) {
max = d;
}
}
float hh = max / Mathf.Tan((cam.fieldOfView*Mathf.Deg2Rad/2.0f));
float hv = max / Mathf.Tan(Mathf.Atan(Mathf.Tan(cam.fieldOfView*Mathf.Deg2Rad/2.0f)*cam.aspect));
var yCoord = Mathf.Max(hh, hv)*1.1f;
yCoord = Mathf.Max(yCoord, 20);
yCoord = Mathf.Min(yCoord, cam.farClipPlane - 1f);
cam.transform.position = Vector3.Lerp(cam.transform.position, new Vector3(0, yCoord, 0), Time.smoothDeltaTime*2);
}
if (Input.GetKey(KeyCode.A) && Input.GetKeyDown(KeyCode.Mouse0)) {
Order();
}
}
// Update is called once per frame
void OnGUI () {
if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && !Input.GetKey(KeyCode.A)) {
Select(start, end);
wasDown = false;
}
if (Event.current.type == EventType.MouseDrag && Event.current.button == 0) {
end = Event.current.mousePosition;
if (!wasDown) { start = end; wasDown = true; }
}
if (Input.GetKey(KeyCode.A)) wasDown = false;
if (wasDown) {
Rect r = Rect.MinMaxRect(Mathf.Min(start.x, end.x), Mathf.Min(start.y, end.y), Mathf.Max(start.x, end.x), Mathf.Max(start.y, end.y));
if (r.width > 4 && r.height > 4)
GUI.Box(r, "", selectionBox);
}
}
public void Order () {
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
float radsum = 0;
for (int i = 0; i < selection.Count; i++) radsum += selection[i].GetComponent().radius;
float radius = radsum / (Mathf.PI);
radius *= 2f;
for (int i = 0; i < selection.Count; i++) {
float deg = 2*Mathf.PI*i/selection.Count;
Vector3 p = hit.point + new Vector3(Mathf.Cos(deg), 0, Mathf.Sin(deg))*radius;
//Debug.DrawRay (p,Vector3.up*4,Color.cyan);
//Debug.Break();
selection[i].SetTarget(p);
selection[i].SetColor(GetColor(deg));
selection[i].RecalculatePath();
}
}
}
public void Select (Vector2 _start, Vector2 _end) {
_start.y = Screen.height - _start.y;
_end.y = Screen.height - _end.y;
Vector2 start = Vector2.Min(_start, _end);
Vector2 end = Vector2.Max(_start, _end);
if ((end-start).sqrMagnitude < 4*4) return;
selection.Clear();
RVOExampleAgent[] rvo = FindObjectsOfType(typeof(RVOExampleAgent)) as RVOExampleAgent[];
for (int i = 0; i < rvo.Length; i++) {
Vector2 sp = cam.WorldToScreenPoint(rvo[i].transform.position);
if (sp.x > start.x && sp.y > start.y && sp.x < end.x && sp.y < end.y) {
selection.Add(rvo[i]);
}
}
}
/// Radians to degrees constant
const float rad2Deg = 360.0f/ ((float)System.Math.PI*2);
/// Color from an angle
public Color GetColor (float angle) {
return AstarMath.HSVToRGB(angle * rad2Deg, 0.8f, 0.6f);
}
}
}