SceneDragAndDrop.cs 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. Copyright (c) 2020 Omar Duarte
  3. Unauthorized copying of this file, via any medium is strictly prohibited.
  4. Writen by Omar Duarte, 2020.
  5. This class demonstrates the code discussed in this forum:
  6. https://forum.unity.com/threads/is-drag-and-drop-from-custom-editor-window-into-scene-not-possible.658810/
  7. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  8. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  9. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  10. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  11. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  12. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  13. THE SOFTWARE.
  14. */
  15. using UnityEngine;
  16. namespace PluginMaster
  17. {
  18. public static class SceneDragAndDrop
  19. {
  20. private static readonly int _sceneDragHint = "SceneDragAndDrop".GetHashCode();
  21. private const string DRAG_ID = "SceneDragAndDrop";
  22. public static void StartDrag(ISceneDragReceiver receiver, string title)
  23. {
  24. StopDrag();
  25. if (receiver == null) return;
  26. GUIUtility.hotControl = 0;
  27. UnityEditor.DragAndDrop.PrepareStartDrag();
  28. UnityEditor.DragAndDrop.objectReferences = new Object[0];
  29. UnityEditor.DragAndDrop.paths = new string[0];
  30. UnityEditor.DragAndDrop.SetGenericData(DRAG_ID, receiver);
  31. receiver.StartDrag();
  32. UnityEditor.DragAndDrop.StartDrag(title);
  33. #if UNITY_2019_1_OR_NEWER
  34. UnityEditor.SceneView.duringSceneGui += OnSceneGUI;
  35. #else
  36. UnityEditor.SceneView.onSceneGUIDelegate += OnSceneGUI;
  37. #endif
  38. }
  39. public static void StopDrag()
  40. {
  41. #if UNITY_2019_1_OR_NEWER
  42. UnityEditor.SceneView.duringSceneGui -= OnSceneGUI;
  43. #else
  44. UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
  45. #endif
  46. }
  47. private static void OnSceneGUI(UnityEditor.SceneView sceneView)
  48. {
  49. int controlId = GUIUtility.GetControlID(_sceneDragHint, FocusType.Passive);
  50. Event evt = Event.current;
  51. EventType eventType = evt.GetTypeForControl(controlId);
  52. ISceneDragReceiver receiver;
  53. if(eventType == EventType.DragPerform || eventType == EventType.DragUpdated)
  54. {
  55. receiver = UnityEditor.DragAndDrop.GetGenericData(DRAG_ID) as ISceneDragReceiver;
  56. if (receiver == null) return;
  57. UnityEditor.DragAndDrop.visualMode = receiver.UpdateDrag(evt, eventType);
  58. if (eventType == EventType.DragPerform
  59. && UnityEditor.DragAndDrop.visualMode != UnityEditor.DragAndDropVisualMode.None)
  60. {
  61. receiver.PerformDrag(evt);
  62. UnityEditor.DragAndDrop.AcceptDrag();
  63. UnityEditor.DragAndDrop.SetGenericData(DRAG_ID, default(ISceneDragReceiver));
  64. StopDrag();
  65. }
  66. evt.Use();
  67. }
  68. else if (eventType == EventType.DragExited)
  69. {
  70. receiver = UnityEditor.DragAndDrop.GetGenericData(DRAG_ID) as ISceneDragReceiver;
  71. if (receiver == null) return;
  72. receiver.StopDrag();
  73. evt.Use();
  74. }
  75. }
  76. }
  77. public interface ISceneDragReceiver
  78. {
  79. void StartDrag();
  80. void StopDrag();
  81. UnityEditor.DragAndDropVisualMode UpdateDrag(Event evt, EventType eventType);
  82. void PerformDrag(Event evt);
  83. }
  84. }