0

I'm working on a drap and drop system and trying to implement a hooking system (similar to what WordPress uses) so I can trigger action when certain events occurs.

I'm having multiple problems with my delegate functions:

  • cannot convert UIElementDragger.CallBackFunction expression to type ListObserver.CallBackFunction
  • The best overloaded method match for ListObserver.ListObserver(string, ListObserver.CallBackFunction) has some invalid arguments

Do you have any suggestions as to how either correct or otherwise implement a "hook system" so I can have functions with parameters called upon certain custom-defined events?

I have truncated the code bellow to leave the relevant sections, but if you need the whole thing I'd be happy to provide it.

The code to bind the events is:

Note: UIElementDragger is attached to the EventSystem.

//... removed "using"

public class GameSyllab : MonoBehaviour { 

//... removed attributes

private UIElementDragger UIElementDragger;

// Use this for initialization
void Start () {

    //Hook the functions
    UIElementDragger = GetComponent<UIElementDragger> ("UIElementDragger");
    UIElementDragger.HookOnto("DropComplete", DropComplete);
    UIElementDragger.HookOnto("DropCancel", DropCancel);

    //... removed unrelated code
}   

void DropComplete(Object objDraggable, Object objDropZone){
    // Do an action based on the element being dropped
}
void DropCancel(Object objDraggable, Object objDropZone){
    // Play a cancel sound
}

//...removed unrelated class code

The code from the UIElementDragger class that adds the draggable behaviour:

Note: This class is also attached to the EventSystem

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class UIElementDragger : MonoBehaviour {
    //A list with observers that are waiting for something to happen
    List<ListObserver> observers = new List<ListObserver>();
    public delegate void CallBackFunction(Object objDraggable, Object objDropZone);

    // ... removed extra attributes

    // Update is called once per frame
    void Update () {

        //... removed Mouse down code

        if (Input.GetMouseButtonUp (0)) {
            if (objectToDrag != null) {
                Transform objectToDrop = GetDraggableTransformUnderMouse(DROPZONE_TAG);

                if (objectToDrop != null) {
                    //Drop the dragged object on it's new drop zone
                    objectToDrag.position = objectToDrop.position;
                    NotifyObservers ("DropComplete", objectToDrag, objectToDrop);
                } else {
                    //Move the item back to its original position
                    objectToDrag.position = originalPosition;
                    NotifyObservers ("DropCancelled", objectToDrag, null);
                }

                objectToDragImage.raycastTarget = true;
                objectToDrag = null;
            }
            dragging = false;
        }


    }




    //Send notifications if something has happened
    public void NotifyObservers(string hookName, Object objectInstance, Object dropZoneInstance)
    {
        for (int i = 0; i < observers.Count; i++)
        {
            if (observers [i].GetHookName () == hookName) {
                observers [i].Call (objectInstance, dropZoneInstance);
            }
        }
    }

    //Add observer to the list
    public void HookOnto(string newHookName, CallBackFunction newCallBackFunction)
    {
        ListObserver newObserver = new ListObserver (newHookName, newCallBackFunction);
        observers.Add(newObserver);
    }
}

//In the same file, but a separate class
public class ListObserver:MonoBehaviour{
    private string hookName;
    public delegate void CallBackFunction(Object objDraggable, Object objDropZone);
    private CallBackFunction callBackFunction;

    public ListObserver(string newHookName, CallBackFunction newCallBackFunction){
        hookName = newHookName;
        callBackFunction = newCallBackFunction;
    }

    public void Call(Object objDraggable, Object objDropZone){
        callBackFunction (objDraggable, objDropZone);
    }

    public string GetHookName(){
        return hookName;
    }
}

1 Answer 1

2

You have two, incompatible, delegates

public delegate void CallBackFunction(Object objDraggable, Object objDropZone);

and

public delegate void CallBackFunction(Object objDraggable, Object objDropZone);

They have the exact same name and exact same parameters, but they are not the same object. This is the same problem you'd have if you tried to name a class something like Math or Class or List<T>: all of those classes already exist (in another namespace) and will cause problems, as you would be unable to cast Math to System.Math or Class to System.Reflection.Class because the two types are not compatible.

You need to remove the one delegate (the one inside UIElementDragger) and use the other in its place, using a fully qualified name if needed (ListObserver.CallBackFunction).

Sign up to request clarification or add additional context in comments.

1 Comment

... and there I spent 4 hours flipping my code upside down trying to find the problem... Just needed a good slap in the face ;) That was such a simple solution... don't know why I didn't realize that earlier. Thanks Draco !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.