[Unity实战]一个简单的任务系统(一)

对于任务系统来说,,最重要的就是处理脚本之间的消息传递,所以任务系统的核心必定就是事件委托了。这里给出核心代码:

using UnityEngine;using System.Collections;public class TaskCondition{public string id;//条件idpublic int nowAmount;//条件id的当前进度public int targetAmount;//条件id的目标进度public bool isFinish = false;//记录是否满足条件public TaskCondition(string id, int nowAmount, int targetAmount, bool isFinish){this.id = id;this.nowAmount = nowAmount;this.targetAmount = targetAmount;this.isFinish = isFinish;}public void Check(string id, int amount){if (id == this.id){nowAmount += amount;if (nowAmount >= targetAmount)isFinish = true;elseisFinish = false;}}}using UnityEngine;using System.Collections;public class TaskReward{public string id;//奖励idpublic int amount = 0;//奖励数量public TaskReward(string id, int amount){this.id = id;this.amount = amount;}}using UnityEngine;using System.Collections;using System.Collections.Generic;using System.Xml.Linq;public class Task : MonoBehaviour {public string id;//idpublic string caption;//任务描述public enum State{get,//接受任务progress,//进行任务finish,//完成任务reward//得到奖励}public State state = State.get;//接受任务时可能会触发:更新任务到任务面板中等操作public delegate void getDelegate(string info);public event getDelegate getEvent;//检查每个条件是否满足public delegate void checkDelegate(string id, int amount);public event checkDelegate checkEvent;//完成任务时可能会触发:提示完成任务等操作public delegate void finishDelegate(string info);public event finishDelegate finishEvent;//得到奖励时可能会触发:显示获取的物品等操作public delegate void rewardDelegate(string info);public event rewardDelegate rewardEvent;public List<TaskCondition> taskConditions = new List<TaskCondition>();public List<TaskReward> taskRewards = new List<TaskReward>();//根据id读取xml,进行初始化public Task(string id){this.id = id;XElement xe = TaskManager.instance.xElement.Element("Task" + id);IEnumerable<XElement> a = xe.Elements("conditionID");IEnumerator<XElement> b = xe.Elements("conditionTargetAmount").GetEnumerator();IEnumerable<XElement> c = xe.Elements("rewardID");IEnumerator<XElement> d = xe.Elements("rewardAmount").GetEnumerator();foreach (var s in a){b.MoveNext();TaskCondition tc = new TaskCondition(s.Value, 0, int.Parse(b.Current.Value), false);taskConditions.Add(tc);checkEvent += tc.Check;}foreach (var s in c){d.MoveNext();TaskReward tr = new TaskReward(s.Value, int.Parse(d.Current.Value));taskRewards.Add(tr);}getEvent += Notification.instance.PrintInfo;finishEvent += Notification.instance.PrintInfo;rewardEvent += Notification.instance.PrintInfo;Get();}//接受任务public void Get(){getEvent("接受任务Task" + this.id);state = State.progress;}//判断条件是否满足public void Check(string id, int amount){checkEvent(id,amount);for(int i = 0;i < taskConditions.Count;i++){if(!taskConditions[i].isFinish){state = State.progress;return;}}state = State.finish;Finish();}//完成任务public void Finish(){finishEvent("任务" + this.id + "完成!!");state = State.reward;}//获取奖励public void Reward(){if (state != State.reward) return;TaskReward tr;for (int i = 0; i < taskRewards.Count; i++){tr = taskRewards[i];rewardEvent("奖励物品" + tr.id + "奖励数量" + tr.amount);}DestroyTask();}public void DestroyTask(){Notification.instance.PrintInfo("奖励已获取,或者任务被取消!!");TaskManager.instance.tasks.Remove(this);TaskManager.instance.getEvent -= this.Get;TaskManager.instance.checkEvent -= this.Check;TaskManager.instance.rewardEvent -= this.Reward;Destroy(this);}}using UnityEngine;using System.Collections;using System.Collections.Generic;using System.Xml.Linq;public class TaskManager : MonoBehaviour {public static TaskManager instance;public XElement xElement;public List<Task> tasks = new List<Task>();//接受任务时可能会触发:更新任务到任务面板中等操作public delegate void getDelegate();public event getDelegate getEvent;//检查每个条件是否满足public delegate void checkDelegate(string id, int amount);public event checkDelegate checkEvent;//得到奖励时可能会触发:显示获取的物品等操作public delegate void rewardDelegate();public event rewardDelegate rewardEvent;void Awake(){if (!instance)instance = this;elseDestroy(this);}void Start (){xElement = XElement.Load(Application.dataPath + "/TestTask/Task.xml");//得到根元素}public void CreateTask(string id){for (int i = 0; i < tasks.Count; i++){if (tasks[i].id == id)return;}Task t = new Task(id);tasks.Add(t);getEvent += t.Get;checkEvent += t.Check;rewardEvent += t.Reward;}public void RemoveTask(string id){for (int i = 0; i < tasks.Count; i++){if (tasks[i].id == id)tasks[i].DestroyTask();}}public void Get(){if (getEvent != null)getEvent();}public void Check(string id, int amount){if (checkEvent != null)checkEvent(id,amount);}public void Reward(){if (rewardEvent != null)rewardEvent();}}思路(这里以怪物被消灭后为例):

1.怪物消灭后发送信息给监听它的东西,例如得分增加,经验上升等等,其中包括发送给我们的TaskManager

2.TaskManager将信息传递到正在执行的任务Task

3.任务Task再将信息传递到该任务的条件

这里为什么不直接将怪物消灭后的信息直接发送给条件呢?因为这个消息不知道哪个条件在监听它,而条件也不知道要监听哪些消息,这时就需要TaskManager这个中间体了

虽然消息传递很曲折,但是事件委托的效率比较高,所以应该不用担心效率方面的问题

测试:

1.对于收集物品的任务,当收集完成后,再丢弃部分物品。结果:任务不显示完成,领取不了奖励

2.任务完成后放弃任务。结果:领取不了奖励

3.多个任务同时进行。结果:可以领取完成了任务的奖励

木已成舟便要顺其自然

[Unity实战]一个简单的任务系统(一)

相关文章:

你感兴趣的文章:

标签云: