RealWorldTerrainObjectPlacerWindow.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* INFINITY CODE */
  2. /* https://infinity-code.com */
  3. using UnityEditor;
  4. using UnityEngine;
  5. namespace InfinityCode.RealWorldTerrain.Tools
  6. {
  7. public class RealWorldTerrainObjectPlacerWindow : EditorWindow
  8. {
  9. private static string[] gridLabels = { "Place New Object", "Update Position" };
  10. private static RealWorldTerrainObjectPlacerWindow wnd;
  11. private int isNewGameobject = 0;
  12. private GameObject obj;
  13. private double lat;
  14. private double lng;
  15. private double altitude;
  16. private RealWorldTerrainContainer container;
  17. private bool selectGameObject = true;
  18. private bool hasCoordinates = false;
  19. private bool useAltitude = false;
  20. private double cursorLongitude;
  21. private double cursorLatitude;
  22. private double cursorAltitude;
  23. private void OnCoordinatesGUI()
  24. {
  25. lat = EditorGUILayout.DoubleField("Latitude", lat);
  26. lng = EditorGUILayout.DoubleField("Longitude", lng);
  27. EditorGUILayout.BeginHorizontal();
  28. useAltitude = GUILayout.Toggle(useAltitude, GUIContent.none, GUILayout.Width(16));
  29. EditorGUI.BeginDisabledGroup(!useAltitude);
  30. altitude = EditorGUILayout.DoubleField("Altitude", altitude);
  31. EditorGUI.EndDisabledGroup();
  32. EditorGUILayout.EndHorizontal();
  33. }
  34. private void OnDestroy()
  35. {
  36. EditorApplication.update -= OnUpdate;
  37. #if UNITY_2019_1_OR_NEWER
  38. SceneView.duringSceneGui -= OnSceneGUI;
  39. #else
  40. SceneView.onSceneGUIDelegate -= OnSceneGUI;
  41. #endif
  42. wnd = null;
  43. }
  44. private void OnEnable()
  45. {
  46. OnDestroy();
  47. wnd = this;
  48. EditorApplication.update += OnUpdate;
  49. #if UNITY_2019_1_OR_NEWER
  50. SceneView.duringSceneGui += OnSceneGUI;
  51. #else
  52. SceneView.onSceneGUIDelegate += OnSceneGUI;
  53. #endif
  54. }
  55. private void OnGUI()
  56. {
  57. EditorGUI.BeginChangeCheck();
  58. isNewGameobject = GUILayout.SelectionGrid(isNewGameobject, gridLabels, 2);
  59. if (EditorGUI.EndChangeCheck()) obj = null;
  60. container = EditorGUILayout.ObjectField("Container", container, typeof(RealWorldTerrainContainer), true) as RealWorldTerrainContainer;
  61. if (isNewGameobject == 0) OnNewGUI();
  62. else OnUpdateGUI();
  63. if (hasCoordinates)
  64. {
  65. EditorGUILayout.LabelField("Cursor Coordinates:");
  66. EditorGUILayout.LabelField("Latitude: ", cursorLatitude.ToString());
  67. EditorGUILayout.LabelField("Longitude: ", cursorLongitude.ToString());
  68. EditorGUILayout.LabelField("Altitude: ", cursorAltitude.ToString("F2") + " meters");
  69. EditorGUILayout.LabelField("Use CTRL+SHIFT to insert the coordinates.");
  70. if (Event.current.control && Event.current.shift)
  71. {
  72. lat = cursorLatitude;
  73. lng = cursorLongitude;
  74. altitude = cursorAltitude;
  75. }
  76. }
  77. }
  78. private void OnNewGUI()
  79. {
  80. obj = EditorGUILayout.ObjectField("Prefab: ", obj, typeof(GameObject), true) as GameObject;
  81. OnCoordinatesGUI();
  82. selectGameObject = EditorGUILayout.Toggle("Select Gameobject?", selectGameObject);
  83. if (GUILayout.Button("Place") && ValidateFields())
  84. {
  85. GameObject go = Instantiate(obj) as GameObject;
  86. UpdateGameObjectPosition(go);
  87. }
  88. }
  89. private void OnSceneGUI(SceneView view)
  90. {
  91. if (container == null) return;
  92. Vector2 mp = Event.current.mousePosition;
  93. mp.y = view.camera.pixelHeight - mp.y;
  94. Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
  95. RaycastHit hit;
  96. hasCoordinates = Physics.Raycast(ray, out hit);
  97. if (hasCoordinates) container.GetCoordinatesByWorldPosition(hit.point, out cursorLongitude, out cursorLatitude, out cursorAltitude);
  98. }
  99. private void OnUpdate()
  100. {
  101. Repaint();
  102. }
  103. private void OnUpdateGUI()
  104. {
  105. obj = EditorGUILayout.ObjectField("GameObject: ", obj, typeof(GameObject), true) as GameObject;
  106. OnCoordinatesGUI();
  107. selectGameObject = EditorGUILayout.Toggle("Select Gameobject?", selectGameObject);
  108. if (GUILayout.Button("Update") && ValidateFields())
  109. {
  110. UpdateGameObjectPosition(obj);
  111. }
  112. }
  113. [MenuItem("Window/Infinity Code/Real World Terrain/Tools/Object Placer")]
  114. public static void OpenWindow()
  115. {
  116. OpenWindow(null);
  117. }
  118. public static void OpenWindow(RealWorldTerrainContainer container)
  119. {
  120. if (wnd != null) wnd.Close();
  121. wnd = GetWindow<RealWorldTerrainObjectPlacerWindow>(false, "Object Placer", true);
  122. if (container == null) wnd.container = FindObjectOfType<RealWorldTerrainContainer>();
  123. else wnd.container = container;
  124. }
  125. public static void OpenWindow(RealWorldTerrainContainer container, double lng, double lat)
  126. {
  127. OpenWindow(container);
  128. wnd.lat = lat;
  129. wnd.lng = lng;
  130. }
  131. private void SelectGameObject(GameObject go)
  132. {
  133. if (!selectGameObject) return;
  134. Selection.activeGameObject = go;
  135. EditorGUIUtility.PingObject(go);
  136. }
  137. private static void ShowError(string message)
  138. {
  139. EditorUtility.DisplayDialog("Error", message, "OK");
  140. }
  141. private void UpdateGameObjectPosition(GameObject go)
  142. {
  143. Vector3 worldPosition;
  144. bool status = false;
  145. if (useAltitude) status = container.GetWorldPosition(lng, lat, altitude, out worldPosition);
  146. else status = container.GetWorldPosition(lng, lat, out worldPosition);
  147. if (status)
  148. {
  149. go.transform.position = worldPosition;
  150. SelectGameObject(go);
  151. }
  152. }
  153. private bool ValidateFields()
  154. {
  155. if (container == null)
  156. {
  157. ShowError("Please select Real World Terrain Container.");
  158. return false;
  159. }
  160. if (obj == null)
  161. {
  162. ShowError(string.Format("Please select {0}.", isNewGameobject == 0 ? "Prefab" : "GameObject"));
  163. return false;
  164. }
  165. if (!container.Contains(lng, lat))
  166. {
  167. ShowError("These the coordinates outside terrain.");
  168. return false;
  169. }
  170. return true;
  171. }
  172. }
  173. }