How to make Drag and Drop Reset without restart scene

Hello. I want to make reset bubutt for drag and drop. I mean what if i dropped an object to slot but dropped to wrong slot, then when i press the reset buttonb it will drop old location. Anyone know how to make it? I did the drag and drop script from this video:

@Kiwasi :slight_smile:

1 Like

Do I ask him? Actually I asked in this video but nobody reply me

You need to track where the object was before you dropped it somewhere else so you can reset it. Haven’t watched the tutorial, so no clue how it’s set up.

The script is basically set up with the dragable GameObjects as children of the slot GameObjects. So to reset it you need to build a script that has a reference to all of the original slots and their children. Then at runtime, you can simply set them all back to their original. Something like this:

Dictionary<Slot, GameObject> originalSetup = new Dictionary<Transform, Transform> ();

void Start (){
    Slot[] slots = FindObjectsOfType<Slot>();
    foreach (Slot slot in slots){
        originalSetup.Add(slot.transform, slot.transform[0]);
    }
}

public void Reset (){
    foreach (KeyValuePair<Transform, Transform> pair in originalSetup){
        pair.value.SetParent(pair.key);
    }
}

Its not super elegant. It will fail if you make other changes to the scene. But you get the idea.

The other option is to simply put all of the resetable stuff in its own scene, and simply reload the scene.

giving error. the script named “Slot” is “DropHandler” on me

Assets/Scripts/GameController.cs(55,52): error CS0021: Cannot apply indexing with [ ] to an expression of type UnityEngine.Transform' Assets/Scripts/GameController.cs(55,18): error CS1502: The best overloaded method match for System.Collections.Generic.Dictionary<DropHandler,UnityEngine.GameObject>.Add(DropHandler, UnityEngine.GameObject)’ has some invalid arguments
Assets/Scripts/GameController.cs(55,27): error CS1503: Argument #1' cannot convert UnityEngine.Transform’ expression to type DropHandler' Assets/Scripts/GameController.cs(115,55): error CS0030: Cannot convert type System.Collections.Generic.KeyValuePair<DropHandler,UnityEngine.GameObject>’ to System.Collections.Generic.KeyValuePair<UnityEngine.Transform,UnityEngine.Transform>' Assets/Scripts/GameController.cs(41,54): error CS0029: Cannot implicitly convert type System.Collections.Generic.Dictionary<UnityEngine.Transform,UnityEngine.Transform>’ to `System.Collections.Generic.Dictionary<DropHandler,UnityEngine.GameObject>’

That’s what happens when I write a script without using a compiler. This should fix some of the errors.

Dictionary<Transform, Transform> originalSetup = new Dictionary<Transform, Transform> ();

void Start (){
    Slot[] slots = FindObjectsOfType<Slot>();
    foreach (Slot slot in slots){
        originalSetup.Add(slot.transform, slot.transform.GetChild(0));
    }
}

public void Reset (){
    foreach (KeyValuePair<Transform, Transform> pair in originalSetup){
        pair.value.SetParent(pair.key);
    }
}

doesn’t work. nothing happens

Put in the appropriate Debug statements and figure out why. Is Start being called? Is Reset being called? How many items are in the Dictionary?

I debugged and giving warning in this line

DropHandler[] slots = FindObjectsOfType<DropHandler>();
        foreach (DropHandler slot in slots){
            if (slot.transform.childCount > 0) {
                originalSetup.Add(slot.transform, slot.transform.GetChild(0));
            }

        }

 public void Reset (){
        foreach (KeyValuePair<Transform, Transform> pair in originalSetup){
            pair.Value.SetParent(pair.Key);
        }
    }

this The name ‘this’ does not exist in the current context.
pair The name ‘pair’ does not exist in the current context.

also DropHandler[ ] returning null

What?

The text you copied are compiler errors, not warnings. Go to the line they reference. Fix it. Then move on.

key and value returning null. there are no another errors. you can look the picture. also I debugged Start and Dictionary variable. it is same. only null.

I can’t be certain, but I would consider renaming that method, as “Reset” is a Unity method name.

1 Like

I thought the same thing, but when I checked on Reset, it’s only magic to the editor. I have actually used it before way way back without realizing it was a special method to Unity.

So, I did a test on it to double check and if you call it with a button click, it runs fine. Or you can use the cog wheel icon and it will run reset as well. Of course, that being said, it never hurts to use method names that Unity doesn’t use.

If drophandler is null, he’ll have an empty dictionary, but the dictionary shouldn’t be null, it should just be empty if he declared it like @Kiwasi showed.

I’m not sure, but may need to see the rest of the script.

Also there is something one more. The letters that correct will not reset. I mean they will not place old location. I don’t know what i do

You could consider generalizing the idea, if you’re current implementation is not working as you desire.
Any incorrectly placed pieces simply get added back (in their current order) to the “letter pile” or whatever that area is.

However, if you have the rest of the earlier script (/idea) working properly now, when a piece is moved correctly, you could remove it from the dictionary. Then, any reset would only be moving the remaining letters.

1 Like

So go back to Start where the dictionary is filled. What is FindObjectsOfType returning?

Looking at your GameController script, it seems you already have a collection of slots. Why not use that instead?

In my opinion. We write the code wrong place. Because when the game starts, the slots already empty. So the code in start method sees null. I think we should put in update method. Right?

I would call it after you first fill the slots. Which probably shouldn’t be from Update.

Edit: My fool. there is no DropHandler script in the letter object. I am really idiot. This is works. now it have to back start position, so to the letters object but staying in slot again.