Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Drag and Drop Custom Asset to Heirarchy

Discussion in 'Extensions & OnGUI' started by exodrifter, Dec 12, 2014.

  1. exodrifter

    exodrifter

    Joined:
    Mar 17, 2013
    Posts:
    7
    I'm trying to figure out how to allow the user to drag and drop a custom asset into the hierarchy, like it would be for an AudioClip.

    So far, I have the following code in my custom inspector:
    Code (CSharp):
    1. [CustomEditor(typeof(RenPyScriptAsset))]
    2. [InitializeOnLoad]
    3. public class RenPyScriptAssetEditor : UnityEditor.Editor
    4. {
    5.     static RenPyScriptAssetEditor()
    6.     {
    7.         // Adds a callback for when the hierarchy window processes GUI events
    8.         // for every GameObject in the heirarchy.
    9.         EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemCallback;
    10.     }
    11.  
    12.     private static void HierarchyWindowItemCallback(int pID, Rect pRect)
    13.     {
    14.         if (Event.current.type == EventType.DragExited) {
    15.             // get all the drag and drop information ready for processing.
    16.             DragAndDrop.AcceptDrag();
    17.  
    18.             // used to emulate selection of new objects.
    19.             var selectedObjects = new List<GameObject>();
    20.  
    21.             // run through each object that was dragged in.
    22.             foreach (var objectRef in DragAndDrop.objectReferences) {
    23.                 // if the object is the particular asset type...
    24.                 if (objectRef is RenPyScriptAsset) {
    25.                     // we create a new GameObject using the asset's name.
    26.                     var gameObject = new GameObject(objectRef.name);
    27.  
    28.                     // we attach component X, associated with asset X.
    29.                     var display = gameObject.AddComponent<RenPyDisplay>();
    30.  
    31.                     // we place asset X within component X.
    32.                     display.Script = objectRef as RenPyScriptAsset;
    33.  
    34.                     // add to the list of selected objects.
    35.                     selectedObjects.Add(gameObject);
    36.                 }
    37.             }
    38.  
    39.             // we didn't drag any assets of type AssetX, so do nothing.
    40.             if (selectedObjects.Count == 0) return;
    41.  
    42.             // emulate selection of newly created objects.
    43.             Selection.objects = selectedObjects.ToArray();
    44.  
    45.             // make sure this call is the only one that processes the event.
    46.             Event.current.Use();
    47.         }
    48.     }
    49.     ...
    50. }
    This example stole a lot of code from this StackOverflow question. Unfortunately, while this does work, it doesn't work exactly the same way. Using this method doesn't show the correct cursor when I hover over the heirarchy window. Instead, it shows the cursor that tells me I can't do the operation. It also fails to select the GameObjects in the hierarchy that have been created and it adds GameObjects at the wrong time (It does it when the drag exits).

    What do I do to make this work like any other supported asset (Sprites, AudioClips, Prefabs, etc) when you drag it to the hierarchy?
     
    Last edited: Dec 12, 2014
  2. Tran-Ngoc-Tam

    Tran-Ngoc-Tam

    Joined:
    Jul 26, 2016
    Posts:
    20
    Sorry for the very late answer, but I found the solution for the wrong cursor today, just catch another DragUpdated event and change DragAndDrop.visualMode to appropriated value. Here is an example code:
    Code (CSharp):
    1. private static void OnHierarchyGUI(int instanceID, Rect r)
    2.         {
    3.             if (Event.current.type == EventType.DragUpdated ||
    4.                 Event.current.type == EventType.DragExited)
    5.             {
    6.                 DragAndDrop.AcceptDrag();
    7.                 Object[] draggedObjects = DragAndDrop.objectReferences;
    8.                 if (draggedObjects != null &&
    9.                     draggedObjects.Length == 1)
    10.                 {
    11.                     if (draggedObjects[0] is LPTData)
    12.                     {
    13.                         if (Event.current.type == EventType.DragUpdated)
    14.                         {
    15.                             DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
    16.                         }
    17.                         else if (Event.current.type == EventType.DragExited)
    18.                         {
    19.                             LPTData data = draggedObjects[0] as LPTData;
    20.                             GameObject terrain = CreateGameObjectUtilities.CreateAdvancedTerrainWithExistingData(data);
    21.                             Selection.activeGameObject = terrain;
    22.                         }
    23.                         Event.current.Use();
    24.                     }
    25.                 }
    26.             }
    27.         }