Unity c#:使用参数绑定函数

时间:2018-03-16 20:11:20

标签: c# unity3d events delegates listener

我正在处理一个drap and drop系统并试图实现一个挂钩系统(类似于WordPress使用的),所以我可以在发生某些事件时触发操作。

我的委托功能存在多个问题:

  • 无法将UIElementDragger.CallBackFunction表达式转换为ListObserver.CallBackFunction
  • 类型
  • ListObserver.ListObserver(string, ListObserver.CallBackFunction)的最佳重载方法匹配包含一些无效参数

您对如何纠正或以其他方式实施"挂钩系统有任何建议吗?所以我可以使用在某些自定义事件上调用参数的函数吗?

我已经截断了下面的代码以离开相关部分,但是如果你需要整个事情,我很乐意提供它。

绑定事件的代码是:

注意:UIElementDragger附加到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

UIElementDragger类中添加可拖动行为的代码:

注意:此类也附加到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 个答案:

答案 0 :(得分:2)

您有两个不兼容的代理

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

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

它们具有完全相同的名称和完全相同的参数,但它们不是同一个对象。如果您尝试将类命名为MathClassList<T>,则会出现同样的问题:所有这些类已经存在(在另一个命名空间中)会导致问题,因为您无法将Math投放到System.MathClass投放到System.Reflection.Class,因为这两种类型不兼容。

您需要删除一个委托(UIElementDragger内部的委托)并在其位置使用另一个委托,如果需要,使用完全限定名称(ListObserver.CallBackFunction)。