Search Unity

Drag and Drop problems

Discussion in 'Scripting' started by jwparker62, Feb 26, 2018.

  1. jwparker62

    jwparker62

    Joined:
    Feb 26, 2018
    Posts:
    7
    I'm new to unity and C# coding so I started with this video because I would like to create a simple drag and drop game for my daughter:



    First error I was getting was for some reason Unity 2017 was seeing 'IBeginDragHandler' as a class rather than an interface, which was odd.

    I think I have remedied all of the errors and I can successfully run the program now, however, my place holders seem to be non existent. I can drag the pictures around and all day long, but they will never snap to a place. I have been over this code multiple times and have thrown break points in different places, but I can't seem to get it to function properly. Can someone take a look at my codes and see if Im missing something or is there an issue with the different versions of Unity.

    Ive been spinning my wheels for about 9 hours over a weeks time trying to figure out what Im missing.

    Here is the code for the Items that will be dragged.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5. using UnityEngine.UI;
    6.  
    7.  
    8. [RequireComponent(typeof(Image))]
    9. public class Family : MonoBehaviour, IDragHandler, IEndDragHandler {
    10.     public static GameObject item;
    11.     Vector3 startPosition;
    12.     Transform startParent;
    13.     //bool start = true;
    14.  
    15.  
    16.  
    17.     #region IBeginDragHandler implementation
    18.     public void OnBeginDrag(PointerEventData eventData)
    19.     {
    20.         item = gameObject;
    21.         startPosition = transform.position;
    22.         startParent = transform.parent;
    23.  
    24.         GetComponent<CanvasGroup> ().blocksRaycasts = false;
    25.         item.GetComponent<LayoutElement> ().ignoreLayout = true;
    26.         item.transform.SetParent (item.transform.parent.parent);
    27.  
    28.     }
    29.  
    30.     #endregion
    31.  
    32.  
    33.  
    34.     #region IDragHandler implementation
    35.     public void OnDrag (PointerEventData eventData)
    36.     {
    37.         transform.position = Input.mousePosition;
    38.     }
    39.     #endregion
    40.  
    41.  
    42.  
    43.     #region IEndDraghandler implementation
    44.     public void OnEndDrag (PointerEventData eventData)
    45.     {
    46.         item = null;
    47.  
    48.         if (transform.parent == startParent) {
    49.             transform.position = startPosition;
    50.         }
    51.         GetComponent<CanvasGroup> ().blocksRaycasts = true;
    52.  
    53.     }
    54.     #endregion
    55.  
    56.  
    57. }
    58.  
    59.  

    Here is the code that supposedly creates the place holders:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5.  
    6. public class PlaceHolder : MonoBehaviour, IDropHandler {
    7.  
    8.     public GameObject item
    9.     {
    10.         get {
    11.             if (transform.childCount > 0) {
    12.                 return transform.GetChild (0).gameObject;
    13.             }
    14.             return null;
    15.         }
    16.     }
    17.  
    18.     #region IDropHandler implementation
    19.     public void OnDrop(PointerEventData eventData)
    20.     {
    21.         if (!item)
    22.  
    23.         {
    24.             Family.item.transform.SetParent (transform);
    25.             ExecuteEvents.ExecuteHierarchy<IHasChanged> (gameObject, null, (x, y) => x.HasChanged ());
    26.         }
    27.     }
    28.     #endregion
    29. }
    30.  
    The final code is for the Text string to read the item object within the upper place holders:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;

    public class Inventory : MonoBehaviour, IHasChanged {
    [SerializeField] Transform placeHolder;
    [SerializeField] Text inventoryText;

    // Use this for initialization
    void Start () {
    HasChanged ();
    }

    #region IHasChanged implementation
    public void HasChanged()
    {
    System.Text.StringBuilder builder = new System.Text.StringBuilder ();
    builder.Append (" - ");
    foreach (Transform slotTransform in placeHolder) {
    GameObject item = slotTransform.GetComponent<PlaceHolder>().item;
    if (item)
    {
    builder.Append (item.name);
    builder.Append (" - ");
    }
    }
    inventoryText.text = builder.ToString ();
    }
    #endregion
    }

    namespace UnityEngine.EventSystems {
    public interface IHasChanged : IEventSystemHandler {
    void HasChanged ();
    }
    }

     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Do you have any child objects in the place holders? I can't see anything truly 'wrong', so I'm not sure what's up.
    If you Debug.Log in OnDrop, above the 'if statement' , does anything get printed?
    You have to make sure that you can raycast the target of the place holder(s).

    I'm guessing when you let go of the drag, it just returns to where you started?
     
  3. jwparker62

    jwparker62

    Joined:
    Feb 26, 2018
    Posts:
    7
    Ive only been coding for a week so forgive me if it takes me some time to get the full understanding. Is this the correct set up for the debug.log:

    public void OnDrop(PointerEventData eventData)
    {
    Debug.Log("message", gameObject);
    if (!item)
    If so then nothing is printing currently.

    Right now, when I let go of an item, it just stays put. It seems that none of the place holders are working at all. Would this have something to do with the 'IBeginDragHandler' not being in there?
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Yes, that's how you would write a debug log. I hadn't noticed that the IBeginDragHandler wasn't there at the top of the class.. did you add that and try?
     
  5. jwparker62

    jwparker62

    Joined:
    Feb 26, 2018
    Posts:
    7
    yes when I tried to add that, for some reason, my unity is seeing it as another base class rather than an interface. So I had to completely remove it so I could even attempt to run the script. I still have the code for its implementation in there.
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Okay, you must re-add it.. otherwise it will never be called - regardless of whether you have the code there.

    I'm not sure what happened the first time you tried, but try again :)
     
    Kiwasi likes this.
  7. jwparker62

    jwparker62

    Joined:
    Feb 26, 2018
    Posts:
    7

    So this is the error I get when I try to have the IBeginDragHandler at the beginning. I'm going to try the set up on a totally different computer this evening to check and see if there is an issue with my Unity Download
     

    Attached Files:

  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Check that you didn't accidentally create a class/script called IBeginDragHandler?
    You could of course type the fully qualified name, like UnityEngine.EventSystems.IBeginDragHandler
    but I think you should first check you don't have a script/class by that name causing a conflict.
     
  9. jwparker62

    jwparker62

    Joined:
    Feb 26, 2018
    Posts:
    7
    Such a simple fix. thanks for the help man.
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    No problem, you're welcome. :)

    Out of curiosity, did you find a class by that name in your files, or did you use the long name?
     
  11. jwparker62

    jwparker62

    Joined:
    Feb 26, 2018
    Posts:
    7
    There was a script with that name that I hadn't even noticed. I guess it created itself, I'm not sure. Once I deleted that script, its all working as its suppose to. However, every time I choose and object, I get 3 NullReferenceExceptions ( see attachment). What does this mean?
     

    Attached Files:

  12. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Just check which lines they occur on and look for what could be null there. Perhaps you didn't attach a canvas group component to each or a layout element?

    Otherwise, if you can't figure it out, post the line(s) of code in question here, and perhaps I or someone else can assist you further.
     
  13. jwparker62

    jwparker62

    Joined:
    Feb 26, 2018
    Posts:
    7
    The null refers to item.GetComponent<LayoutElement> ().ignoreLayout = true; on line 25. If I comment it out, one of the 6 icons disappears while being dragged.

    Where would I find the Layout Element?
     
  14. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    The layout element must have been part of the original tutorial, because it's certainly not required for dragging n dropping in general. The layout element would have been on the element you drag, I believe.
     
  15. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The layout element was my cheat way of auto positioning the object in the slot when you drop it. Its one of the built in components, you can add it from the add component menu.