GroupController.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using Pathfinding.RVO;
  4. using Pathfinding.RVO.Sampled;
  5. namespace Pathfinding.Examples {
  6. /// <summary>
  7. /// RVO Example Scene Unit Controller.
  8. /// Controls AIs and camera in the RVO example scene.
  9. /// </summary>
  10. [HelpURL("http://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_examples_1_1_group_controller.php")]
  11. public class GroupController : MonoBehaviour {
  12. public GUIStyle selectionBox;
  13. public bool adjustCamera = true;
  14. Vector2 start, end;
  15. bool wasDown = false;
  16. List<RVOExampleAgent> selection = new List<RVOExampleAgent>();
  17. Simulator sim;
  18. Camera cam;
  19. public void Start () {
  20. cam = Camera.main;
  21. var simu = RVOSimulator.active;
  22. if (simu == null) {
  23. this.enabled = false;
  24. throw new System.Exception("No RVOSimulator in the scene. Please add one");
  25. }
  26. sim = simu.GetSimulator();
  27. }
  28. public void Update () {
  29. if (adjustCamera) {
  30. //Adjust camera
  31. List<Agent> agents = sim.GetAgents();
  32. float max = 0;
  33. for (int i = 0; i < agents.Count; i++) {
  34. float d = Mathf.Max(Mathf.Abs(agents[i].Position.x), Mathf.Abs(agents[i].Position.y));
  35. if (d > max) {
  36. max = d;
  37. }
  38. }
  39. float hh = max / Mathf.Tan((cam.fieldOfView*Mathf.Deg2Rad/2.0f));
  40. float hv = max / Mathf.Tan(Mathf.Atan(Mathf.Tan(cam.fieldOfView*Mathf.Deg2Rad/2.0f)*cam.aspect));
  41. var yCoord = Mathf.Max(hh, hv)*1.1f;
  42. yCoord = Mathf.Max(yCoord, 20);
  43. yCoord = Mathf.Min(yCoord, cam.farClipPlane - 1f);
  44. cam.transform.position = Vector3.Lerp(cam.transform.position, new Vector3(0, yCoord, 0), Time.smoothDeltaTime*2);
  45. }
  46. if (Input.GetKey(KeyCode.A) && Input.GetKeyDown(KeyCode.Mouse0)) {
  47. Order();
  48. }
  49. }
  50. // Update is called once per frame
  51. void OnGUI () {
  52. if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && !Input.GetKey(KeyCode.A)) {
  53. Select(start, end);
  54. wasDown = false;
  55. }
  56. if (Event.current.type == EventType.MouseDrag && Event.current.button == 0) {
  57. end = Event.current.mousePosition;
  58. if (!wasDown) { start = end; wasDown = true; }
  59. }
  60. if (Input.GetKey(KeyCode.A)) wasDown = false;
  61. if (wasDown) {
  62. 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));
  63. if (r.width > 4 && r.height > 4)
  64. GUI.Box(r, "", selectionBox);
  65. }
  66. }
  67. public void Order () {
  68. Ray ray = cam.ScreenPointToRay(Input.mousePosition);
  69. RaycastHit hit;
  70. if (Physics.Raycast(ray, out hit)) {
  71. float radsum = 0;
  72. for (int i = 0; i < selection.Count; i++) radsum += selection[i].GetComponent<RVOController>().radius;
  73. float radius = radsum / (Mathf.PI);
  74. radius *= 2f;
  75. for (int i = 0; i < selection.Count; i++) {
  76. float deg = 2*Mathf.PI*i/selection.Count;
  77. Vector3 p = hit.point + new Vector3(Mathf.Cos(deg), 0, Mathf.Sin(deg))*radius;
  78. //Debug.DrawRay (p,Vector3.up*4,Color.cyan);
  79. //Debug.Break();
  80. selection[i].SetTarget(p);
  81. selection[i].SetColor(GetColor(deg));
  82. selection[i].RecalculatePath();
  83. }
  84. }
  85. }
  86. public void Select (Vector2 _start, Vector2 _end) {
  87. _start.y = Screen.height - _start.y;
  88. _end.y = Screen.height - _end.y;
  89. Vector2 start = Vector2.Min(_start, _end);
  90. Vector2 end = Vector2.Max(_start, _end);
  91. if ((end-start).sqrMagnitude < 4*4) return;
  92. selection.Clear();
  93. RVOExampleAgent[] rvo = FindObjectsOfType(typeof(RVOExampleAgent)) as RVOExampleAgent[];
  94. for (int i = 0; i < rvo.Length; i++) {
  95. Vector2 sp = cam.WorldToScreenPoint(rvo[i].transform.position);
  96. if (sp.x > start.x && sp.y > start.y && sp.x < end.x && sp.y < end.y) {
  97. selection.Add(rvo[i]);
  98. }
  99. }
  100. }
  101. /// <summary>Radians to degrees constant</summary>
  102. const float rad2Deg = 360.0f/ ((float)System.Math.PI*2);
  103. /// <summary>Color from an angle</summary>
  104. public Color GetColor (float angle) {
  105. return AstarMath.HSVToRGB(angle * rad2Deg, 0.8f, 0.6f);
  106. }
  107. }
  108. }