I’m probably not explaining this very well, check out the screenshots and ask away with any questions…
When the “Draw Cards” button is pressed, the cards appear in the lower right and become children of “PlayerHand”. I want to be able to drag+drop the cards onto one of the spaces and have it become a child of that space after I release the object and it snaps to the grid. For now I set the parent to “GridArea” just by typing in that string, but can’t figure out how to set the parent to whichever “dropzone” it lands on.
I have been stuck on this for weeks and it’s incredibly frustrating… I need the cards to become children of whichever space they’re dropped onto in order to keep fleshing out the game but I just can’t figure it out. The only way I’ve found to switch the parent is to type in a string directly.
Check out “On Drop” event. You can retrieve the dropped object via the PointerEventData output of the On Drop event. And you’d place this event on the empty slots.
You might also need to add a Canvas Group component on the card itself and disable Raycast blocking when the card is dragged so empty slots can detect the On Drop event.
Thanks for the reply! I’ll start playing around with “On Drop” events. I’m confused as to where it goes though… The graph in my screenshot above is attached to the Card prefab, why place it on the empty slots instead of including it in card prefab graph? Also, where does the SetParent node go here? I would’ve though that I put the OnDrop event on the card graph, set it to “self”, then connect that to SetParent, like this:
The docs on this are pretty sparse and non-descriptive, but my understanding of the On Drop event is the following:
On Drop event is called on a target that can accept a drop. You’re not dropping anything on a card. You’re dragging and dropping the card on something else, ie the game board slot.
The PointerEventData.pointerDrag GameObject references the dragged object that is dropped. If the On Drop is on a card, and the pointerDrag GameObject is another card, you’re back where you started.
So the On Drop event goes onto empty board slots because it triggers when something is dropped over it. That is, On Drop has conditions of two UI objects existing and you have to release one over another. On Drop triggers only on the other object and not the dragged object.
As for the graph, you need to swap the input connection places. The empty slot’s On Drop detects when a card is dropped onto it and also gives you the dragged card’s GO reference that you then use for the Transform.SetParent node. Except in the current configuration, it would set the empty slot as a child object of the dragged card - you want it the other way around.
EDIT: You might also want to use RectTransfrom.SetParent as these are UI objects. Transform is for regular worldspace GameObjects. It probably doesn’t matter in SetParent context, but it definitely matters when working with position and rotation, etc.
EDIT #2: If the built in On Drop logic doesn’t fit your needs, you can raycast, then filter the hit objects to find an open slot, then do something with it. On Drop is a lot cleaner in my opinion though.
Thanks! All that makes sense I think… I’ll keep experimenting but you’ve given me some direction. I get why the On Drop has to be on the empty slot instead of the card, but i still can’t make it work, i’m assuming i’m missing either something in the card graph or some component on the slot that helps them communicate to know when it’s been dropped over. I’m very much a newb at this so I’m probably lacking some basic understanding of Unity and coding that might make this easier to troubleshoot. On that note, one more thing: what exactly do you mean by “swap the input connection places”?
Talking about the graph image you posted. As it is now and assuming that graph goes onto the empty slot, the SetParent node sets “Self” which is the empty slot as a child object of the dragged card - the “p” input. You want that the other way around. There’s a dedicated “Self” node that you can input into the “p” which is parent input.
As for why it might not be working. It could be that the card images block raycasts to the empty slot. Try adding a CanvasGroup component to your card, which lets you perform several operations on all images a card has, such as controlling alpha. And On Drag Start try setting CanvasGroup “Blocks Raycasts” property to false. This might solve the On Drop event not triggering on the empty slot.
Ahh thank you!! I got it working, but not using On Drop after all – No matter what I tried I couldn’t get it to do anything. BUT I ended up dropping a SetParent node at the end of my DragDrop script (on the card prefab), with the “p” input coming from the collider (screenshot below), and now it changes parents as I drag the card around the board and remains there when I drop it. Hopefully this method doesn’t cause any problems later on, do you see any obvious cons to doing it this way as opposed to On Drop?
The only con would probably be missing out on On Drop event since it can run logic based on the dropped card. If you don’t need to do that, then it seems fine. And you can still trigger a custom event on the SnapPos collider GameObject anyway.
If it works and does what you need it to do, then don’t worry about it.