用于 OnSelect 和 OnDeselect 的委托

McG*_*777 5 c# delegates unity-game-engine

我正在使用 Unity 并努力制作一个自定义 SelectableButton,该按钮将方法存储在两个不同的委托中,并在选择按钮时执行一个,在取消选择时执行另一个。相关部分显示如下:

public delegate void OnSelectAction();
public delegate void OnDeselectAction();

public class SelectableButton : MonoBehaviour
{
    private bool selected;

    public OnSelectAction onSelect;
    public OnDeselectAction onDeselect;

    public bool Selected
    {
        get { return selected; }
        set
        {
            selected = value;

            if(selected)
                onSelect();
            else
                onDeselect();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在另一个脚本中,我尝试在 onSelect 中封装一个方法,在 onDeselect 中封装另一个方法。

for(int i = 0; i < racesData.RaceList.Count; i++)
{
    selectableButton.onSelect = Select(racesData.RaceList[i]);
    selectableButton.onDeselect = Deselect(racesData.RaceList[i]);
}

public void Select(Race race)
{
// Does its selection stuff
}

public void Deselect(Race race)
{
// Does its deselection stuff
}
Run Code Online (Sandbox Code Playgroud)

最后,我得到了一个错误,告诉我我不能“将 void 转换为 OnSelectAction/OnDeselectAction”。如果我尝试这样写:

selectableButton.onSelect = () => Select(racesData.RaceList[i]);
selectableButton.onDeselect = () => Deselect(racesData.RaceList[i]);
Run Code Online (Sandbox Code Playgroud)

Select() 和 Deselect() 方法没有按照预期的方式执行。如果有人能帮我提供我在完成这项工作时所缺乏的部分,那就太好了,我会很感激你的手:)

Dra*_*18s 2

您的第一次尝试不起作用,因为这不是您分配代表的方式。

你需要这样做:

selectableButton.onDeselect = Deselect;
Run Code Online (Sandbox Code Playgroud)

因为您分配的是方法引用而不是方法调用的返回值。

但由于您的选择/取消选择方法采用参数,因此它们与您的委托定义不匹配。因此,无论如何您都不能这样做(或者您必须更改委托的定义才能接受该参数,但您可能不希望这样做)。

那么我们就得到了 lambda 版本,它分配正确,但功能不正确。由于Function Closure ,它无法正常运行

for(int i = 0; i < racesData.RaceList.Count; i++)
{
    int j = i; //declare new local variable with a copy of the data
    selectableButton.onSelect = () => Select(racesData.RaceList[j]);
    selectableButton.onDeselect = () => Deselect(racesData.RaceList[j]);
}
Run Code Online (Sandbox Code Playgroud)