簡體   English   中英

C# class inheritance 帶有 ScriptableObject UnityEvents 和不同類型的 UnityActions

[英]C# class inheritance with ScriptableObject UnityEvents and differently-typed UnityActions

我正在為游戲創建自定義 UnityEvents。 基礎 class 看起來像這樣:

public class EventSO : ScriptableObject
{
    List<UnityAction> listeners = new List<UnityAction>();

    public virtual void Raise() { ... }
    public virtual void AddListener(UnityAction listener) { ... }
    public virtual void RemoveListener(UnityAction listener) { ... }
}

有時我想將變量傳遞給事件。 所以我繼承:

public class FloatEventSO : EventSO
{
    List<UnityAction<float>> listeners = new List<UnityAction<float>>();

    public override void Raise(float f) { ... }
    public override void AddListener(UnityAction<float> listener) { ... }
    public override void RemoveListener(UnityAction<float> listener) { ... }
}

我的目標是能夠為我可以分配和調用的單個事件創建 ScriptableObjects:Float 事件的一個很好的例子可能是傳達游戲時間。 因此,例如,名為“OnEveryHalfSec”的 ScriptableObject。

這種方法的第一個問題是,我需要為傳遞給事件的每個變量組合創建一個新的 class:UnityAction<float, int>、UnityAction<float, string>... 等等。

第二個問題是我無法像上面顯示的那樣覆蓋基數 class; Raise(float) 不能覆蓋 Raise()。 所以我必須在每個 class 上重新定義。

有沒有更好的方法來解決這個問題?

看起來你應該定義

 public override void Raise(float f) {... }

作為

 public virtual void Raise(float f) {... } in the base class

您沒有將“(float f)”放入基數 class

你想使用generics

有一個基地 class 像例如

public abstract ParameterEventSO<T> : ScriptableObject
{
    List<UnityAction<T>> listeners = new List<UnityAction<T>>();

    public virtual void Raise(T value) 
    {
        foreach(var listener in listeners)
        {
            listener?.Invoke (value);
        }
    }
    public virtual void AddListener(UnityAction<T> listener)
    {
        listeners.Add(listener);
    }
    public virtual void RemoveListener(UnityAction<T> listener)
    {
        listeners.Remove(listener);
    }
}

現在您可以根據需要使用特定類型的派生類,例如

[CreateAssetMenu]
public class FloatEvent : ParameterEventSO<float> { }

或者

[CreateAssetMenu]
public class IntListEvent : ParameterEventSO<List<int>> { }

或者還有

public class CustomArgs
{
    public Vector3 Position;
    public string Name;
    public DateTime TimeStamp;
}

[CreateAssetMenu]
public class CustomArgsEvent : ParameterEventSO<CustomArgs> { }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM