使用泛型和非泛型UnityEvents的集合

时间:2018-03-17 16:35:25

标签: c# unity3d

我正在Unity中开展一些项目。我有:

[Serializable]
public class ItemAction
{
    [SerializeField]
    private UnityEvent unityEvent;

    public void Perform()
    {
        unityEvent.Invoke();
    }
}

[Serializable]
public class ItemAction<T>
{
    [SerializeField]
    private UnityEvent<T> unityEvent;

    public void Perform(T parameter)
    {
        unityEvent.Invoke(parameter);
    }
}

我也有这个课程:

public abstract class Item : MonoBehaviour
{
    [SerializeField]
    private float weight;
    [SerializeField]
    private [collection of item actions] actions;

    public abstract void Use();
    public abstract void Grab(Transform transform);
    public abstract void Drop();
}

如何使用混合泛型和非泛型ItemAction实例创建集合(因此某些操作可能需要一些参数)? 例如:

对于未装备的武器,我只能抓住它们。 对于未装备的medkits,我可以抓住它们或立即使用它们。 对于触发器/切换器,我只能使用它们。

我可能使用空接口,但我不认为这是一个很好的解决方案......

2 个答案:

答案 0 :(得分:0)

就像你说的那样你可以创建一个空接口或者只是使用一组对象,因为你无论如何都必须进行强制转换,或者你跳过ItemAction类并且只使用带有参数的版本并且对于那些没有参数的动作传递null t需要一个参数(也不是一个“好的”解决方案,但这就是WPF框架使用ICommand接口的方式,例如)

但是还有一个问题,无论你使用的是接口还是对象列表,你都无法在编辑器中显示它们(除非你创建了一个自定义编辑器),因为编辑器没有显示泛型类

答案 1 :(得分:0)

因为你想在继承自Item的每个特定项类中实现这些方法(至少,我猜你自己声明了那些方法abstract), 我将使用其他路由,并为每个特定操作实现接口。

例如:

public interface IItem {
    float Weight { get; set; }
}

public interface IGrabItem : IItem {
    void Grab();
}

public interface IDropItem : IItem {
    void Drop();
}

public interface IUseItem : IItem {
    void Use();
}

public class MedKit : MonoBehaviour, IGrabItem, IUseItem {
    [SerializeField]
    float weight;
    public float Weight {
        get { return weight; }
        set { weight = value; }
    }
    public void Grab() {
        //Your code
    }
    public void Use() {
        //Your code
    }
}

然后您可以选择直接在每个特定的项目类中实现代码,或使用某种event来提升它们。

哦,顺便说一句,如果可能的话,避免使用UnityEvent并依赖标准的.NET event,它会更快,并且开销更少。