Search Unity

Feature Request External object drag and drop

Discussion in 'UI Toolkit' started by L4Z3RC47, Jan 16, 2020.

  1. L4Z3RC47

    L4Z3RC47

    Joined:
    Jun 21, 2015
    Posts:
    46
    I would love to see implementation of a UI object or event callback for cross platform external object drag and drop support in runtime/UnityEngine. Similar to the UnityEditor DragAndDrop API. This would enable things such as easy runtime import of UGC for textures, videos, models, etc...
     
  2. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
  3. L4Z3RC47

    L4Z3RC47

    Joined:
    Jun 21, 2015
    Posts:
    46
    Thanks, this is interesting though I don't think this would help because the main issue is that the class DragAndDrop is inherits from the UnityEditor class. What I would need is for the DragAndDrop class to be added to the UnityEngine class for this function to be able to be called and ported to game UI objects if I'm not mistaken?
     
  4. L4Z3RC47

    L4Z3RC47

    Joined:
    Jun 21, 2015
    Posts:
    46
    @uDamian Any additional thoughts? Still really wanting this for runtime :(
     
  5. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    L4Z3RC47 likes this.
  6. L4Z3RC47

    L4Z3RC47

    Joined:
    Jun 21, 2015
    Posts:
    46
    @uDamian Just saw this update, thanks! Though I'm not quite clear on how I would implement this?

    Followup question. How would I be able to grab the filepath info for the asset being dragged into screenspace via MouseManipulator? Just to clarify as well as I don't think I did a great job above, I'm looking to drag in an external object from the finder/explorer outside of the application scope into the runtime window so I can grab that filepath and reference it during runtime. A usecase example would be I have a photo that I would like to add as an avatar image. I want to be able to drag and drop this from my desktop or documents folder into the running application and either make a copy of that file or keep a reference to that path.
    Another use case would be I have a folder of video files in my documents folder. I want to be able to drag in that folder into a UI window in the running application to be able to pull in the list of files within that path to ingest those references and be able to select a background video for my AR effect or some other thing.
     
  7. L4Z3RC47

    L4Z3RC47

    Joined:
    Jun 21, 2015
    Posts:
    46
    This is the perfect reference however because of some editor integration issues it doesn't work in editor and its also only compatible with windows. I'd love to see something that supports Windows, MacOS, and Linux

    https://github.com/Bunny83/UnityWindowsFileDrag-Drop
     
    theteadrinker likes this.
  8. L4Z3RC47

    L4Z3RC47

    Joined:
    Jun 21, 2015
    Posts:
    46
    Hi again @uDamian
    Was wondering if you had a followup to the above? Thank again for your time. I really appreciate it!
     
    antnasce likes this.
  9. antnasce

    antnasce

    Joined:
    Apr 27, 2019
    Posts:
    12
    Would really love cross-platform desktop file drag-drop support, to allow assets like images/audio to be used in Unity built apps. Similar to Qt's drag-drop QMimeData from the file system would be amazing! https://zetcode.com/gui/pyqt5/dragdrop/
     
    ul_antnasce likes this.
  10. lesnier

    lesnier

    Joined:
    May 7, 2021
    Posts:
    5
    I would love that too.I am using unity for app development and i would like as windows forms has a drag and drop operation in the two ways out of unity to os and back.I am fixing that problem with socket comunication but is not ideal.
     
  11. bobby55

    bobby55

    Joined:
    Jun 24, 2020
    Posts:
    48
    This would also be usefull for rythm games where we need the user to upload custom music files. A drag and drop would be a nice feature - especially cross platform.
     
    gabrieljsmith77 likes this.
  12. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    You can use this to make a VisualElement reparent into a panel that renders to a texture, and then drag the rendered texture around. That way you don't have to worry about dragging around a component and it's consequences on layouts. This implementation is not perfect but should work on some cases. I wish there was a built in "render to texture" method on any arbitrary VisualElement so I don't have to use such a strange workaround.
    Code (CSharp):
    1. public static RenderTexture ForceRender(this VisualElement aThis, VisualElement Target) {
    2.             if (m_VisualTreeUpdater == null) {
    3.                 m_VisualTreeUpdater = typeof(Panel). //
    4.                                       GetField("m_VisualTreeUpdater", BindingFlags.Instance | BindingFlags.NonPublic). //
    5.                                       DelegateForGet<Panel, VisualTreeUpdater>();
    6.             }
    7.  
    8.             RenderTexture RT = null;
    9.  
    10.             if (aThis.panel is Panel panel) {
    11.                 VisualElement oldparent = Target.parent;
    12.                 int oldIndex = oldparent.IndexOf(Target);
    13.                 aThis.Add(Target);
    14.                 if (panel is BaseRuntimePanel BPanel) {
    15.                     var ResolvedStyleWidth = (int) Target.resolvedStyle.width;
    16.                     var ResolvedStyleHeight = (int) Target.resolvedStyle.height;
    17.  
    18.                     if (BPanel.targetTexture.width != ResolvedStyleWidth || BPanel.targetTexture.height != ResolvedStyleHeight) {
    19.                         BPanel.targetTexture.Release();
    20.                         BPanel.targetTexture.width = ResolvedStyleWidth;
    21.                         BPanel.targetTexture.height = ResolvedStyleHeight;
    22.                         BPanel.targetTexture.Create();
    23.                     }
    24.                     RT = BPanel.targetTexture;
    25.                 }
    26.  
    27.                 VisualTreeUpdater _m_VisualTreeUpdater = m_VisualTreeUpdater(panel);
    28.                 _m_VisualTreeUpdater.OnVersionChanged(Target, VersionChangeType.Repaint);
    29.  
    30.                 var Current = Event.current;
    31.                 panel.Repaint(Current);
    32.                 oldparent.Insert(oldIndex, Target);
    33.             }
    34.             return RT;
    35.         }
     
  13. bobby55

    bobby55

    Joined:
    Jun 24, 2020
    Posts:
    48
    Hi @Guedez - sorry to bother but am i correct in assuming this a solution to allow an interception of any dragged file using a visual element to capture it within UI in some sort of way?

    I'm also unsure as to how to use this function and it produces many errors such as " 'Panel' is inaccessible due to its protection level" and "The name 'BindingFlags' does not exist in the current context" - would you be so kind as to explain?

    Thankyou!
     
    Last edited: Jul 28, 2022
  14. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    What it is: The code reparent a VisualElement to a panel that renders to a render texture, force the panel to render now, and then return the VisualElement to it's original parent on it's original position.

    On why it is not working: I've used the internals access hack (asmref file referencing the assembly I want to access internals from) with the uitoolkit 0.18preview package version. Now that I think about it, it probably does not work at all with the built in version.
    Should be possible to replicate the internals access trick using a ton of reflection to reproduce the code above. Once you have a rendertexture of the VisualElement you want to drag around, it becomes exceedingly easy to make a drag and drop system that is very unlikely to cause unintended issues.
     
    bobby55 likes this.