我正在统一制作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,
},
}
};
}
}
答案 0 :(得分: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;
从这里开始,您可以在FinishedObjective
和QuestCompletedEventArgs
以及List<QuestObjective>
中随时生成FinishedObjective.add(objectiveIn)
个对象。
当完成一定数量的目标或者你想对这些信息做什么时,你也应该能够使事件处理方法采取不同的行为。
当然,只要新方法的签名带有相同的签名,您还可以通过添加更多this.CompletedObjective += this.methodName;
行来添加多种不同的方法来响应此事件。
答案 1 :(得分: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
}
}
}