SelectionObject.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. public class SelectionObject : MonoBehaviour
  6. {
  7. // Start is called before the first frame update
  8. void Start()
  9. {
  10. }
  11. bool isSelecting = false;
  12. Vector3 mousePosition1;
  13. void Update()
  14. {
  15. // Если нажимаем на левую кнопку мыши, то
  16. // сохраняем координаты курсора мыши и начинаем выбор
  17. if (Input.GetMouseButtonDown(0))
  18. {
  19. isSelecting = true;
  20. mousePosition1 = Input.mousePosition;
  21. }
  22. // Если мы отпускаем левую кнопку мыши - конец выбора
  23. if (Input.GetMouseButtonUp(0))
  24. isSelecting = false;
  25. }
  26. /// <summary>
  27. /// Рисуем область выделения
  28. /// </summary>
  29. public static class Utils
  30. {
  31. static Texture2D _whiteTexture;
  32. public static Texture2D WhiteTexture
  33. {
  34. get
  35. {
  36. if (_whiteTexture == null)
  37. {
  38. _whiteTexture = new Texture2D(1, 1);
  39. _whiteTexture.SetPixel(0, 0, Color.white);
  40. _whiteTexture.Apply();
  41. }
  42. return _whiteTexture;
  43. }
  44. }
  45. public static void DrawScreenRect(Rect rect, Color color)
  46. {
  47. GUI.color = color;
  48. GUI.DrawTexture(rect, WhiteTexture);
  49. GUI.color = Color.white;
  50. }
  51. /// <summary>
  52. /// Отображение границ прямоугольника
  53. /// </summary>
  54. /// <param name="rect"></param>
  55. /// <param name="thickness"></param>
  56. /// <param name="color"></param>
  57. public static void DrawScreenRectBorder(Rect rect, float thickness, Color color)
  58. {
  59. // верх
  60. Utils.DrawScreenRect(new Rect(rect.xMin, rect.yMin, rect.width, thickness), color);
  61. // лево
  62. Utils.DrawScreenRect(new Rect(rect.xMin, rect.yMin, thickness, rect.height), color);
  63. // право
  64. Utils.DrawScreenRect(new Rect(rect.xMax - thickness, rect.yMin, thickness, rect.height), color);
  65. // низ
  66. Utils.DrawScreenRect(new Rect(rect.xMin, rect.yMax - thickness, rect.width, thickness), color);
  67. }
  68. /// <summary>
  69. /// Рисуем мышью прямоугольную область выбора
  70. /// </summary>
  71. public static Rect GetScreenRect(Vector3 screenPosition1, Vector3 screenPosition2)
  72. {
  73. // Перемещение координат из левого нижнего в левый верхний угол
  74. screenPosition1.y = Screen.height - screenPosition1.y;
  75. screenPosition2.y = Screen.height - screenPosition2.y;
  76. // Рассчитать углы
  77. var topLeft = Vector3.Min(screenPosition1, screenPosition2);
  78. var bottomRight = Vector3.Max(screenPosition1, screenPosition2);
  79. // Создать прямоугольник
  80. return Rect.MinMaxRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
  81. }
  82. /// <summary>
  83. /// Выбор юнитов в Unity
  84. /// </summary>
  85. /// <param name="camera"></param>
  86. /// <param name="screenPosition1"></param>
  87. /// <param name="screenPosition2"></param>
  88. /// <returns></returns>
  89. public static Bounds GetViewportBounds(Camera camera, Vector3 screenPosition1, Vector3 screenPosition2)
  90. {
  91. var v1 = Camera.main.ScreenToViewportPoint(screenPosition1);
  92. var v2 = Camera.main.ScreenToViewportPoint(screenPosition2);
  93. var min = Vector3.Min(v1, v2);
  94. var max = Vector3.Max(v1, v2);
  95. min.z = camera.nearClipPlane;
  96. max.z = camera.farClipPlane;
  97. var bounds = new Bounds();
  98. bounds.SetMinMax(min, max);
  99. return bounds;
  100. }
  101. }
  102. void OnGUI()
  103. {
  104. if (isSelecting)
  105. {
  106. // Создаем прямоугольник на основе начальных и конечных координат курсора
  107. var rect = Utils.GetScreenRect(mousePosition1, Input.mousePosition);
  108. Utils.DrawScreenRect(rect, new Color(0.8f, 0.8f, 0.95f, 0.25f));
  109. Utils.DrawScreenRectBorder(rect, 2, new Color(0.8f, 0.8f, 0.95f));
  110. }
  111. }
  112. public bool IsWithinSelectionBounds(GameObject gameObject)
  113. {
  114. if (!isSelecting)
  115. return false;
  116. var camera = Camera.main;
  117. var viewportBounds =
  118. Utils.GetViewportBounds(camera, mousePosition1, Input.mousePosition);
  119. return viewportBounds.Contains(
  120. camera.WorldToViewportPoint(gameObject.transform.position));
  121. }
  122. }