Author Topic: How to spawn and drag item from list of items (drag and drop copy, not move)  (Read 12949 times)

Shifty Geezer

  • Full Member
  • ***
  • Thank You
  • -Given: 7
  • -Receive: 9
  • Posts: 226
    • View Profile
Using example 11 as a starting point, the intention is to have a scroll list where items can be dragged and dropped without removing them from the list. Think tower defense or Plants vs Zombies. Dragging from the list should create a new sprite that's dragged and dropped leaving the list untouched.

I can create the second drag sprite from the initial drag that functions and drops, but I don't know how to place it at the starting drag position under the finger/mouse and be dragged.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Two solutions. Easier one involves looking at it backwards. Instead of creating a copy then making the code drag the copy instead of the object, you can just create a copy and add it where the object started, so that you're dragging the object you pressed on, and the copy is what shows up behind it.

Another option is to set the references yourself. UICamera.currentTouch gives you full access to what camera is working with -- including pressed and dragged object references. You can change them as you see fit.

Shifty Geezer

  • Full Member
  • ***
  • Thank You
  • -Given: 7
  • -Receive: 9
  • Posts: 226
    • View Profile
Thanks, but I'm not having any luck with either solution. :(

With the easy solution, I tried accessing the grid as the transform's parent...

  1. GameObject new_sp = NGUITools.AddChild (gameObject.transform.parent.gameObject, gameObject);
... but that parents to the Drag and Drop Root, so I guess the reparenting happens before the OnDragDropStart() is called. So I provide the grid reference with a public object and I can add a clone back into the list...
  1.         public GameObject grid;
  2.  
  3.         protected override void OnDragDropStart (){    
  4.                 GameObject sp = NGUITools.AddChild (grid, gameObject);
  5.                 base.OnDragDropStart();                        
  6.         }
...but the grid is rearranged. I can't find a way to insert to new object at the old object's index as if it hasn't moved.

For the trickier method, although I can gain access to the UICamera.currentTouch and can set its objects, this doesn't rest control from the script.

  1.         GameObject sp = GameObject.Instantiate (gameObject) as GameObject;
  2.         UICamera.MouseOrTouch camtouch = UICamera.currentTouch;
  3.         camtouch.dragged = sp;
This leaves the grid untouched and creates a clone at the centre of the screen in the root, but again the dragged object is reparented to the Drag and Drop Root object and the new object isn't in any way attached to the drag activity.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
The grid is re-arranged... sounds to me like your entries have the same name or the grid is set to not be sorted. You should give them unique names if you want them to be in specific order, such as 001, 002, 003, etc. Grid must also be set to sort the children. This is the only proper way to ensure the order in which they show up. If you don't do this, things will behave differently on different platforms. Unity is inconsistent here.

Shifty Geezer

  • Full Member
  • ***
  • Thank You
  • -Given: 7
  • -Receive: 9
  • Posts: 226
    • View Profile
Thanks. That's pretty much working. I clone the object, return the copy to the grid, renaming it to remove the (clone) appendix, and have a draggable object.

Regards accessing the grid, is it possible to access the parent via code within the OnDragDropStart() method, or will I have to use some workaround like the public value defined at edit time?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Access the parent? You mean transform.parent?

Shifty Geezer

  • Full Member
  • ***
  • Thank You
  • -Given: 7
  • -Receive: 9
  • Posts: 226
    • View Profile
transform.parent returns the Drag And Drop Root, leading me to believe OnDragDropStart() is called after processing has been done to the drag object.

With this code attached to my dragdrop object in Grid -
  1. OnDragDropStart(){
  2.     GameObject new_sp = NGUITools.AddChild (gameObject.transform.parent.gameObject, gameObject);}
...a clone is duplicated and parented to Drag And Drop Root instead of to Grid.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
It does, yes. Look inside UIDragDropItem, line 109. It's at the very end of the function. The parent changes above it.

I'll make some modifications to it to make it easier to use for what you're trying to do (moving a copy).

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
I've added a boolean flag to UIDragDropItem that will clone the item for you instead of dragging the item itself. You will find it in the next update (likely tonight).

Shifty Geezer

  • Full Member
  • ***
  • Thank You
  • -Given: 7
  • -Receive: 9
  • Posts: 226
    • View Profile
Fabulous! Great support. Thanks.

jtms

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
I am trying to use the "clone on drag" boolean but when the cloned item gets dropped into a drag and drop container it does not get added to the grid I have setup. Unchecking this boolean makes the exact same objects able to be successfully dragged/dropped. What is it about the clone that makes it not be accepted by an otherwise working drag drop container?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
When the item is cloned, it won't be added on drop. It's intentional. If you want it to be, derive a custom script from UIDragDropItem and override the OnDragDropRelease function. Look at the same function in UIDragDropItem. Note how it simply destroys the game object if it was cloned. You will want to do something else.