分配事件与新订阅

问题描述 投票:0回答:2

我在做统一QuestSystem。

我想要做的是分配给我的questData一个事件,所以当追求目标已经完成了它才能知道。

比方说,有一类名为A和行动称为a

我想通过这门课B,行动b希望有参考A.a

所以,如果我这样做

b = A.a;

b+= someAction;,它实际上a+=someAction;

但是,当如果我这样做。这将只是简单b+=someActionA.a仍将null

我应该怎么做来执行我想要什么?

这里有一些标签。 (我不知道答案是什么。所以..)

# event
# subscribing event
# assigning event
# referencing event
# action
# delegate

======编辑=======这里是我的代码。

QuestData.cs

public class QuestData
{
    public string questName;
    public string qusetID;
    public string questDescription;
    public SceneType questSceneType;

    private string isActivePrefsKey { get { return $"QuestKey{qusetID}"; } }
    public bool isActive {
        get {
            return Convert.ToBoolean (PlayerPrefs.GetInt (isActivePrefsKey));
        }
        set { PlayerPrefs.SetInt (isActivePrefsKey, Convert.ToInt16 (value)); }
    }
    public QuestObjective questObjective;
    public QuestReward questReward;


    public void Activate ()
    {
        if (AppController.CurrentScene == questSceneType) {
            questObjective.ActivateObjective ();

        }
    }

}

QuestObjective.cs

public class QuestObjective
{
    // TODO rename all
    public int goalObjectiveCount;
    public int currentObjectiveCount;


    public Action questAction;

    public void OnConditionMatch ()
    {
        Debug.Log ("OnConditionMatch");
        currentObjectiveCount += 1;
    }

    public void ActivateObjective ()
    {
        questAction += OnConditionMatch;
    }


}

QuestManager.cs

public class QuestManager : MonoBehaviour
{

    List<QuestData> questDatas;


    void Awake ()
    {
        PrepareQuestDatas ();
        ActivateActiveQuests ();
    }


    void ActivateActiveQuests ()
    {
        var activeQuests = GetActiveQuests ();
        foreach (var activeQuest in activeQuests) {
            activeQuest.Activate ();
        }
    }


    List<QuestData> GetActiveQuests ()
    {
        // for debuging
        return questDatas;

        // real code
        return questDatas.Where (q => q.isActive == true).ToList ();
    }



    public void PrepareQuestDatas ()
    {
        questDatas = new List<QuestData> {
            new QuestData {
                questName = "Foot Print",
                questDescription  = "win the game for first time",
                questSceneType = SceneType.Main,
                questObjective = new QuestObjective {
                    goalObjectiveCount = 1,
                    questAction = GamePlayController.instance.endGameCon.onWinGame
                },
                questReward = new QuestCoinReward{
                    rewardAmount = 100,
                },
            }
        };
    }


}
c# events delegates event-handling
2个回答
1
投票

一个可能的解决方案是创建一套新的EventArgs的,就像这样:

public class QuestCompletedEventArgs : System.EventArgs
{
    public QuestObjective FinishedObjective { get; }
    public QuestCompletedEventArgs(QuestObjective objectiveIn) {
        this.FinishedObjective = objectiveIn;
    }
}

(可能在不同的文件)...然后使用它是这样的:

首先,创建一个事件委托:

public delegate void QuestObjectiveCompleteHandler(object sender, QuestCompletedEventArgs e);

实例事件委托:

public event QuestObjectiveCompletedHandler CompletedObjective;

定义当目标完成,将做一些方法:

public void ObjectiveCompleted(object sender, QuestCompletedEventArgs e) 
{
    // do something 
}

指定该方法的事件:

this.CompletedObjective += this.ObjectiveCompleted;

从这里,你可以使FinishedObjectiveQuestCompletedEventArgs对象List<QuestObjective>FinishedObjective.add(objectiveIn)在适当的时候。

你也应该能够使事件处理方法,行为方式时的目标一定量已经完成,或任何你想利用这些信息做。

当然,你也可以添加多种不同的方法来响应这个事件通过增加更多的this.CompletedObjective += this.methodName;线,只要新的方法(S)的签名携带相同的签名。


0
投票

读入你的榜样,我已经写了一些代码,其中“A”是QuestObjective和“B”是Quest。该Quest对象需要知道什么时候目标已经标记为完成。

使用事件处理程序,我们可以当一个行动A.发生设定,让B是通知

像这样:

// B
public class Quest
{
    public Quest()
    {
        Objectives = new List<QuestObjective>();
        // load objectives... Fake
        Objectives.Add(new QuestObjective("obj 1"));
        Objectives.Add(new QuestObjective("obj 2"));
        Objectives.Add(new QuestObjective("obj 3"));

        foreach(var o in Objectives) // subscribe to QuestObjective events
        {
            o.ObjectiveCompleted += (sender, args) => ReportObjectiveCompleted();
        }
    }

    public void ReportObjectiveCompleted()
    {
        // let 'em know
    }

    public List<QuestObjective> Objectives { get; set; }
}

// A
public class QuestObjective
{
    public string Name { get; set; }
    public QuestObjective(string name = "unknown")
    {
        Name = name;
    }
    public event EventHandler ObjectiveCompleted;

    public void MarkCompleted()
    {
        // when a task is marked as complete and IF there are 
        // subscribers to this event then call the event handler
        var a = ObjectiveCompleted;
        if (a != null)
        {
            a(this, new EventArgs()); // use different event args to pass data
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.