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): using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [RequireComponent(typeof(Image))] public class Family : MonoBehaviour, IDragHandler, IEndDragHandler { public static GameObject item; Vector3 startPosition; Transform startParent; //bool start = true; #region IBeginDragHandler implementation public void OnBeginDrag(PointerEventData eventData) { item = gameObject; startPosition = transform.position; startParent = transform.parent; GetComponent<CanvasGroup> ().blocksRaycasts = false; item.GetComponent<LayoutElement> ().ignoreLayout = true; item.transform.SetParent (item.transform.parent.parent); } #endregion #region IDragHandler implementation public void OnDrag (PointerEventData eventData) { transform.position = Input.mousePosition; } #endregion #region IEndDraghandler implementation public void OnEndDrag (PointerEventData eventData) { item = null; if (transform.parent == startParent) { transform.position = startPosition; } GetComponent<CanvasGroup> ().blocksRaycasts = true; } #endregion } Here is the code that supposedly creates the place holders: Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class PlaceHolder : MonoBehaviour, IDropHandler { public GameObject item { get { if (transform.childCount > 0) { return transform.GetChild (0).gameObject; } return null; } } #region IDropHandler implementation public void OnDrop(PointerEventData eventData) { if (!item) { Family.item.transform.SetParent (transform); ExecuteEvents.ExecuteHierarchy<IHasChanged> (gameObject, null, (x, y) => x.HasChanged ()); } } #endregion } 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 (); } }
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?
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?
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?
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.
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
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
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.
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?
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?
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.
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?
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.
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.