Author Topic: UI Drag Drop Item  (Read 8416 times)

SFDev

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
UI Drag Drop Item
« on: April 27, 2015, 09:16:49 AM »
Hello,
Working on a project and I have the case where my DragDrop-Item have to be instantiate and On-Drag on the same click.
I'm working on for 2 days and I'm turning crazy... ^^'
Maybe something more accurate is existing with NGUI or maybe i miss something ?
In any case, this feature look usefull for some other project, an idea ?

Thank you in advance

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UI Drag Drop Item
« Reply #1 on: April 27, 2015, 04:42:21 PM »
It's not quite clear what you mean by "have to be instantiate and On-Drag on the same click".

NGUI comes with the drag & drop example. Cloning an object when the drag operation begins is one of the options. You can also do your own custom drag & drop just by simply listening and reacting to the OnDragStart / OnDrag / OnDragOver / OnDragOut / OnDragEnd notifications that are built-in.

SFDev

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: UI Drag Drop Item
« Reply #2 on: April 28, 2015, 02:54:00 AM »
Hum, something like : 1: the drag drop object do not exist 2: click on a random button generate the prefab of the object under the mouse AND the drag drop object count as "on-drag" (follow the mouse and react properly if I release my click)
Something like 2 click in 1...
You're second proposition might be great but I'm not sure of it efficiency... as the object do not exist at the moment of the click...
I think about "message" systems but drag drop is not a button =/
I tried to override the class dragdrop item, unsuccessfully...

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UI Drag Drop Item
« Reply #3 on: April 29, 2015, 06:24:37 PM »
The object doesn't exist at the time of the click if you choose the "clone" option on the drag & drop script either. It's created at run-time, and the drag operation is started on that object instead of the original one.

SFDev

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: UI Drag Drop Item
« Reply #4 on: May 22, 2015, 05:03:50 AM »
Hello Aren,

the problem is still unsolved and we didn't succeed to found a workaround.
In your Clone on drag function, you simply make a copy of the object and replace the dragged object in the MouseOrTouch variable: it works because the system is already in a dragndrop process.
In our case, here is the process:
- the user clicks on a 3D object
- we instantiate a Sprite under the mouse with the DragdropItem component
- we call a new Force Dragging function which try to put the system in the drag mode but this doesn't work.

-> My thought is that there is some state in the system that are not initialized correctly in order to say we are in a Dragging mode.

Here is the ForceDrag function:
  1. public void ForceDragging ()
  2.         {
  3.                 if (!mDragging)
  4.                 {
  5.  
  6.                         mTouch = new UICamera.MouseOrTouch();
  7.                         if (mTouch != null  )
  8.                         {
  9.                                 mTouch.current = gameObject;
  10.                                 mTouch.pressed = gameObject;
  11.                                 mTouch.dragged = gameObject;
  12.                                 mTouch.last = gameObject;
  13.                                 mTouch.dragStarted = true;
  14.                                 mTouch.pressStarted = true;
  15.                                 mTouch.touchBegan = true;
  16.                                 mTouch.pressedCam = UICamera.currentCamera;
  17.                                 mTouch.clickNotification = UICamera.ClickNotification.BasedOnDelta;
  18.                                 mTouch.clickTime = 65f;
  19.                                 //mTouch.deltaTime = 125f;
  20.                         }
  21.                        
  22.                         mTouch = mTouch;
  23.                         mPressed = true;
  24.                         mDragging = true;
  25.                         Start();
  26.                         OnDragDropStart();
  27.                        
  28.                         if (UICamera.currentTouch == null)
  29.                                 UICamera.currentTouch = mTouch;
  30.                         UICamera.Notify(gameObject, "OnPress", true);
  31.                         UICamera.Notify(gameObject, "OnHover", true);
  32.                         UICamera.Notify(gameObject, "OnDrag",new Vector2(0,0));
  33.                         UICamera.currentKey = KeyCode.Mouse0;
  34.                         UICamera.isDragging = true;
  35.                         UICamera.currentTouchID = -1;
  36.                         UICamera.current = UICamera.currentCamera.GetComponent<UICamera>();
  37.  
  38.                 }
  39.         }

I try to set all the params of the UICamera like they are when we use the CloneOnDrag function but this does'nt work.
Did you have an idea on how we can do that?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UI Drag Drop Item
« Reply #5 on: May 22, 2015, 04:35:36 PM »
clickTime needs to be the actual time, not a fixed value.

mTouch = mTouch; <-- ??

You are making a new MouseOrTouch event, but doing so outside of any NGUI event... if you want to tie into an existing NGUI event, you should be modifying UICamera.currentTouch, ideally from within an OnClick event.

SFDev

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: UI Drag Drop Item
« Reply #6 on: May 25, 2015, 08:47:21 AM »
There might be some unclean code as I'm trying a lot of things.
Quote
you should be modifying UICamera.currentTouch, ideally from within an OnClick event
That's my problem as when I need to put the new sprite in a drag mode, the current touch event of the UICamera is null.
it happens because I click on 3D object to start the drag process.

this is why I try to simulate the click event, without success at this time... :(

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UI Drag Drop Item
« Reply #7 on: May 26, 2015, 03:05:44 PM »
Attach a UICamera script to your 3D camera as well and your currentTouch will not be null, and your 3D object will receive the events you are looking for.

alexsan99

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: UI Drag Drop Item
« Reply #8 on: September 21, 2015, 04:38:29 PM »
I believe I'm working on similar task.. what is the best way to simulate Drag and Drop solution like it is in Clash?

I want to Instantiate a Prefab in my 2D game when I Drag an Item/Sprite from the UIGrid (Clone on drag enabled), not immediately, but right
after Item leaves the UIpanel. I have 'UIDragDropItem' script attached to every Item in the Grid, and it should be different prefabs
instantiating corresponding to different Items.

Appreciate any help on this!

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UI Drag Drop Item
« Reply #9 on: September 26, 2015, 03:41:32 PM »
Very similar to the drag & drop example that comes with NGUI, except you will be writing some custom OnDragDropMove code that will keep an eye on what's underneath the dragged object, and when it leaves the panel it will create a 3D object instead.

I did this for a game prototype earlier. My dragged object creates a 3D instance of some object when it leaves the UI region and hides the UI element (alpha = 0). When it re-enters the UI element it hides the 3D object and shows the UI element. For positioning of the 3D object I do a simple planar raycast, but you can do a physics raycast instead.

alexsan99

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: UI Drag Drop Item
« Reply #10 on: September 29, 2015, 06:29:54 PM »
 All right, thank you for the tips!
It did worked for me to Instantiate a Prefab right at the moment when UI-element leaves the UI panel, but I cannot get it work to continue dragging instantiated object? The new object doesn't receive a focus, I get that, but need some advice how to solve this problem.

 edited
btw, I'm using: NGUITools.Destroy(gameObject);
for the UI-element instead of alpha=0. I have a UI-container with 2 sprites in it, not sure how to change alpha for this one..

I have 'UIDragDropItem' script attached to UI-element and I call from here Instantiate function, which is in another script (Global manager):
  1. protected void OnDrag (Vector2 delta) {
  2.  ...
  3.  
  4.  if(UICamera.hoveredObject.name == ("hoveredBase"))
  5.   Manager.Instantiate...
  6.  
  7.  ...
  8. }
an instantiated object has its own 'onDrag' script.
My Main Camera is for the game objects, and UI Camera for NGUI, so.. if I understand it right, these two receive their own events? shall I do Raycast for the 'Main Camera' right after instantiation?

Would you be so kind and share some code example perhaps of how to switch from dragging of UI-element to that new instantiated game object? so I have one continuous drag movement. Thanks.
« Last Edit: September 30, 2015, 09:43:23 AM by alexsan99 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UI Drag Drop Item
« Reply #11 on: October 01, 2015, 02:04:19 AM »
You need to forward events from the actual dragged icon (the widget with alpha 0) to the object you are dragging and have some script there handle the rest. For example this is how I achieve it:
  1. public class UIPartListItem : UIDragDropItem
  2. {
  3.         // ... skipping some code ...
  4.  
  5.         protected override void OnDragDropStart ()
  6.         {
  7.                 base.OnDragDropStart();
  8.                 if (mPart != null) ShipBuilder.instance.StartDragging(mPart, !UICamera.isOverUI); // <-- forwarding the event to another script
  9.                 else Debug.LogWarning("No part available", this);
  10.         }
  11.  
  12.         protected override void OnDragDropMove (Vector2 delta)
  13.         {
  14.                 base.OnDragDropMove(delta);
  15.                 bool overUI = UICamera.isOverUI;
  16.                 ShipBuilder.instance.DragMove(!overUI); // <-- forwarding the event to another script
  17.                 mWidget.alpha = overUI ? 1f : 0f;
  18.         }
  19.  
  20.         protected override void OnDragDropEnd ()
  21.         {
  22.                 ShipBuilder.instance.StopDragging(); // <-- forwarding the event to another script
  23.                 base.OnDragDropEnd();
  24.         }