Search Unity

[Solved]Having trouble with lists

Discussion in 'Scripting' started by PianoMeow, May 30, 2017.

  1. PianoMeow

    PianoMeow

    Joined:
    Sep 26, 2015
    Posts:
    107
    hi, what I'm trying to do is a little drag and drop script for my canvas. i have a single image that can be dragged and dropped onto many different spots using other images as placeholders. what i am having trouble with is making many different images be able to be dragged and dropped but i am having trouble re-writing what i have. i made a public list to add all the images i want to be able to drag but i am having trouble getting the position for them and i can't seem to make them game objects in my "Drag" any help would be appreciated

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DragAndDrop : MonoBehaviour
    6. {
    7.     public List<GameObject> unitImage;
    8.  
    9.     void Start()
    10.     {
    11.         unitImage = new List<GameObject> ();
    12.     }
    13.  
    14.     public void Drag()
    15.     {
    16.         //stores the possition of the mouse and moves teh object image accordingly
    17.         unitImage.transform.position = Input.mousePosition;
    18.         //GameObject.Find ("ArcherImage").transform.position = Input.mousePosition;
    19.         //print ("We are dragging the mouse");
    20.     }
    21.  
    22.     public void Drop()
    23.     {
    24.         for(int i = 1; i <=49; i++)
    25.         {
    26.             GameObject ph1 = GameObject.Find ("placeholder" + i);
    27.             float distance = Vector3.Distance (GameObject.Find ("ArcherImage").transform.position, ph1.transform.position);
    28.  
    29.             //print ("distance" + distance);
    30.             if(distance < 12)
    31.             {
    32.                 GameObject.Find ("ArcherImage").transform.position = ph1.transform.position;
    33.             }
    34.         }
    35.  
    36.     }
    37. }
     
  2. Dolzen

    Dolzen

    Joined:
    Mar 26, 2014
    Posts:
    90
    You should use the EventTriggers instead.
     
  3. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    I will start by saying we should replace those GameObject.Find calls, but we'll ignore those for now.

    Is this script on each image? If so, then each image has it's own copy of the List, which means they aren't going to interact with each other.

    For your Drag, you are trying to move a list and not a single object...this isn't going to work. You would have to call an index of the list, however, again, if this script is on many items, the list is different for each one.

    I'm not even sure how you are calling your drag and drop methods...

    You'll probably be better off using the interfaces that Unity has created for their event system to do this dragging script instead.

    https://docs.unity3d.com/ScriptReference/EventSystems.IBeginDragHandler.html
    https://docs.unity3d.com/ScriptReference/EventSystems.IDragHandler.html
    https://docs.unity3d.com/ScriptReference/EventSystems.IEndDragHandler.html

    https://docs.unity3d.com/ScriptReference/EventSystems.IPointerDownHandler.html
    https://docs.unity3d.com/ScriptReference/EventSystems.IPointerUpHandler.html

    https://docs.unity3d.com/ScriptReference/EventSystems.IDropHandler.html

    These are designed for this sort of thing and work really well.
     
  4. PianoMeow

    PianoMeow

    Joined:
    Sep 26, 2015
    Posts:
    107
    No I have the script on an empty game object and am using the event handlers. I was just struggaling with how call on what ever image in the list I was trying to drag. Thanks for the references, I'll try again tomarow after some sleep
     
  5. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    I don't see the connection between drag-and-drop, and requiring them to be tracked in a list. what is this supposed to be in your game or project?
     
  6. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    If this is an empty gameobject, then I'm not sure what you were trying to do. Usually you'll just use the built in methods that go with those interfaces and that way you're dragging a single image and then you drop it. Each piece can have it's copy of the script.
     
  7. PianoMeow

    PianoMeow

    Joined:
    Sep 26, 2015
    Posts:
    107
    Yes, the way I have it set up right now I can only grab a single image with the name "archerImage" What I am trying to do is have the option to grab any image as I am going to have about 10 with different names. I was thinking having a list would work best for that or am I wrong
     
  8. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Using a list probably isn't the best use case here.

    The interfaces I linked are all designed to make this easier for you. Normally you create a script, let's call it draggableImage. Then you'll implement the dragging interfaces in that script which should handle picking up the image, having it move with your cursor/touch, and then what happens when you let it go. This script will be on each image, thus as long as you click on that image, it will be the one that moves.

    Your best use is the draghandlers I linked. I linked some of the other things because they can also be used for other things as well. (we have a puzzle game that uses the ipointer interfaces and the draghandler interfaces for example)

    That isn't to say you can't have a list that you maintain on a manager if you need to, but you probably wouldn't use that list to do the actual dragging.
     
  9. PianoMeow

    PianoMeow

    Joined:
    Sep 26, 2015
    Posts:
    107
    this is what i ended up doing after a bit of research and solved all my problems for anyone who is having similar problems

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5.  
    6. public class DragAndDrop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
    7. {
    8.  
    9.     public void OnBeginDrag(PointerEventData eventData)
    10.     {
    11.         Debug.Log ("");
    12.     }
    13.  
    14.     public void OnDrag(PointerEventData eventData)
    15.     {
    16.         this.transform.position = eventData.position;
    17.     }
    18.  
    19.     public void OnEndDrag(PointerEventData eventData)
    20.     {
    21.         for (int i = 1; i <= 49; i++)
    22.         {
    23.             GameObject ph1 = GameObject.Find ("placeholder" + i);
    24.             float distance = Vector3.Distance (this.transform.position, ph1.transform.position);
    25.  
    26.             if(distance < 12)
    27.             {
    28.                 this.transform.position = ph1.transform.position;
    29.             }
    30.         }
    31.  
    32.     }
    33.  
    34. }
    35.  
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You went with a "close to something counts as a drop". That's cool. Are these placeholder spots far enough apart so they don't overlap, just out of curiousity?

    One things really stands out to me -- if these place holder objects are all in the scene, you would be better off assigning them to a list or array in the inspector. Then, even if you keep this distance_drop design, you could iterate much more quickly, avoiding GameObject.Find.

    One last note, minor I suppose but doesn't hurt to point it out for reference. If you get the square magnitude of your two positions (being compared in the distance check) and compare that to " 12 * 12 " it's a bit faster, avoiding a square root calculation. :)

    Oh, and before I forget 1 important thing. Congrats on getting it working! lol
     
  11. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    I agree with @methos5k , a list on a manager script that holds all the placeholders would be better since you're trying to do gameobject.find on 49 items. (I would do a list even if it was 10 items, or 5)

    The reason this is bad is you are telling it to search all objects in the scene 49 times to find the item you need. With a list you iterate through you'll have a direct reference to each object that is a placeholder.

    I would also suggest you put a break in your if(distance < 12)

    Code (CSharp):
    1. if(distance < 12)
    2. {
    3.    this.transform.position = ph1.transform.position;
    4.    break;
    5. }
    This way once you find the placeholder and set the piece down, you don't have to iterate through the rest of the objects. Just image if you drop the image into placeholder1 slot, you're currently still telling it to search for the other 48 placeholders. The break will end the loop and you'll not search the rest of the placeholders once you find the one you need.
     
  12. PianoMeow

    PianoMeow

    Joined:
    Sep 26, 2015
    Posts:
    107
    @methos1387 & brathnann thanks for the feed back
    @methos1387 my place holder spots are a somewhat representative of a grid layout almost like a chess board so they do not overlap but do share a boarder with each respective node

    @methos1387 & Brathnann again thank you for your input, i am still just trying to get the core functionality of my game down before tightening up the code, i do plan to make a array for my place holders, i think that would be best as i plan to have the player save the units position on the board map(i.e. all the place holders)

    sorry if my questions seem remedial, i am still a novice when it comes to unity interface
     
  13. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Okay, the reason I asked about the spacing was tied to wondering why you chose the "close distance" instead of using the IDropHandler :) That's all. It's your unique program if you like the distance, that's cool. Just mentioning it as an option, if you didn't consider it.

    I can understand wanting to get the game done well before tightening up or what not.. I guess I/we like to point things out, whether they're used right away or at some later point. Good practice/habit, etc.. :)

    Even though you got my handle wrong, I figure you meant me ;)

    Enjoy your game!
     
  14. PianoMeow

    PianoMeow

    Joined:
    Sep 26, 2015
    Posts:
    107
    @methos5k ha sorry yeah, i just saw a methos pop up and i just hit enter, i have considered what you said,and i just wanted to get a quick update of my code out in case anyone else was in the same scenario as i was

    again thanks for the feed back
     
  15. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    No problem :) Take it easy.