我在做统一QuestSystem。
我想要做的是分配给我的questData一个事件,所以当追求目标已经完成了它才能知道。
比方说,有一类名为A
和行动称为a
。
我想通过这门课B
,行动b
希望有参考A.a
所以,如果我这样做
b = A.a;
,
b+= someAction;
,它实际上a+=someAction;
但是,当如果我这样做。这将只是简单b+=someAction
和A.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,
},
}
};
}
}
一个可能的解决方案是创建一套新的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;
从这里,你可以使FinishedObjective
内QuestCompletedEventArgs
对象List<QuestObjective>
和FinishedObjective.add(objectiveIn)
在适当的时候。
你也应该能够使事件处理方法,行为方式时的目标一定量已经完成,或任何你想利用这些信息做。
当然,你也可以添加多种不同的方法来响应这个事件通过增加更多的this.CompletedObjective += this.methodName;
线,只要新的方法(S)的签名携带相同的签名。
读入你的榜样,我已经写了一些代码,其中“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
}
}
}