本帖最后由 martin4500 于 2018-5-9 09:57 编辑 这段时间比较闲,所以抽时间写了游戏中常见的系统,任务系统,可以接受任务啊,然后通过刷怪等条件去触发任务条件,直到完成任务。
这个系统相对来说比较的简单,可以满足小型的游戏任务系统的基本要求吧!这里面的任务的描述是通过读取Json数据来获取的,当然你也可以去写Excel和XML格式的。序列化Json数据不是用的Unity自带的 JsonUtility.FromJson函数,因为有个更强大的Json解析插件Json .Net for Unity2.0
,直接支持对Dictionary类型的支持,这样省事多了,可以在AssetStore直接下载。下面是效果展示:
废话不多说了上代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
public class DataManager : MonoSingletions<DataManager>
{
private Dictionary<string, Task> taskAllDic = new Dictionary<string, Task>();
private TextAsset mTextAsset;
private void Awake()
{
if (mTextAsset == null)
{
mTextAsset = Resources.Load("Txt/Task", typeof(TextAsset)) as TextAsset;
}
taskAllDic = JsonConvert.DeserializeObject<Dictionary<string, Task>>(mTextAsset.text);
// taskAllDic = UnityEngine.JsonUtility.FromJson <Dictionary<string, Task>> (mTextAsset.text);
foreach (var item in taskAllDic)
{
string tempName=item.Value.taskName;
Debug.Log(tempName);
}
}
public Task GetTaskByID(string Id)
{
Task value;
if (taskAllDic.TryGetValue(Id, out value)) return value;
else Debug.LogError("不存在这个字典");
return null;
}
}
这个类主要是来读取Json文本解析数据,也不需要多去解释了
MonoSingletions
是Mono的单例
public class Task
{ public string taskID; public string taskName; public string description; public List<TaskConditions> taskConditions = new List<TaskConditions>(); public TaskRewards[] taskRewards = new TaskRewards[2];//最好是用数组比链表要节省空间 public Task(string _taskId,string _taskName,string _description, TaskRewards[] _taskRewards,List<TaskConditions> _taskConditions) { taskID = _taskId; taskName=_taskName; description = _description; taskRewards = _taskRewards; taskConditions=_taskConditions; } } Task类就是一个JSon数据实例化的载体类,就是根据你的Json文本来写的,记住一点的就是:属性名称一定要和json的属性名称一致。 public class TaskManager :MonoSingletions<TaskManager> { TransferEvent transfer = new TransferEvent(); private Dictionary<string, Task> currentTaskDic = new Dictionary<string, Task>(); public void AcceptTask(string taskID) { if (currentTaskDic.ContainsKey(taskID)) { print(string.Format("{0},任务已经接受过",taskID)); return; } else { Task t = DataManager.Instance.GetTaskByID(taskID); if (t == null) return; currentTaskDic.Add(taskID, t); TaskArgs args = new TaskArgs(); args.taskId = taskID; TransferEvent.Instance.InvokeEventListen((System.Int16)EventType.OnGetEvent, args); } } /// <summary> /// 更新任务进度 /// </summary> /// <param name="args"></param> public void CheackTask(TaskArgs args) { foreach (var item in currentTaskDic) { UdateUIData(item, args); CheackFinishTask(item, args); } } //更新数据 private void UdateUIData(KeyValuePair<string,Task> item,TaskArgs args) { TaskConditions tc; for (int i = 0; i < item.Value.taskConditions.Count; i++) { tc = item.Value.taskConditions; if (tc.id == args.id) { if (tc.nowAmount >= tc.targetAmount) return; tc.nowAmount += args.amount; args.taskId = item.Value.taskID; args.amount = tc.nowAmount; if (tc.nowAmount < 0) tc.nowAmount = 0; if (tc.nowAmount >= tc.targetAmount) { tc.nowAmount = tc.targetAmount; tc.isFinish = true; } else tc.isFinish = false; //更新UI数据 TransferEvent.Instance.InvokeEventListen((System.Int16)EventType.OnCheackEvent, args); } } } private void CheackFinishTask(KeyValuePair<string, Task> item,TaskArgs args) { TaskConditions tc; for (int i = 0; i < item.Value.taskConditions.Count; i++) { tc = item.Value.taskConditions; if (!tc.isFinish) return;//只要是没有完成就返回 } FinishTask(args); } private void FinishTask(TaskArgs args) { //调用任务完成事件 TransferEvent.Instance.InvokeEventListen((System.Int16)EventType.OnFinishEvent, args); } /// <summary> /// 获取任务奖励 /// </summary> /// <param name="args"></param> public void GetReward(TaskArgs args) { if (currentTaskDic.ContainsKey(args.taskId))//当任务存在 { Task t = currentTaskDic[args.taskId]; for (int i = 0; i < t.taskRewards.Length; i++) { TaskArgs a = new TaskArgs(); a.id=t.taskRewards.id; a.amount = t.taskRewards.amount; a.taskId = args.taskId; TransferEvent.Instance.InvokeEventListen((System.Int16)EventType.OnRewardEvent, args); currentTaskDic.Remove(args.taskId); } } } public void CancelTask(TaskArgs args) { if (currentTaskDic.ContainsKey(args.taskId)) { TransferEvent.Instance.InvokeEventListen((System.Int16)EventType.OnCancelEvent, args); currentTaskDic.Remove(args.taskId); } } } TaskManager是管理类,简单的说就是连接任务数据和相关任务操作(UI文本提示,事件的触发等)这里的CheackTask(TaskArgs args)是检查任务是否完成和更新UI提示,主要通过对当前任务字典的中的任务内容进行相关赋值实现。其它函数都是比较简单看几眼就知道了就不多说了。 public enum EventType { OnGetEvent=0, OnCheackEvent=1, OnFinishEvent=2, OnRewardEvent=3, OnCancelEvent=4 } public class TransferEvent { private List<MesTransfer> mListTransfer ; private List<MesTransfer> mAddListener; private event MesTransfer OnGetEvent;//接受任务时,更新任务到任务面板等操作 private event MesTransfer OnCheackEvent;//更新任务信息 private event MesTransfer OnFinishEvent;//完成任务时,提示完成任务等操作 private event MesTransfer OnRewardEvent;//得到奖励时,显示获取的物品等操作 private event MesTransfer OnCancelEvent;//取消任务时,显示提示信息等操作 private static TransferEvent mInstance; public TransferEvent() { mListTransfer = new List<MesTransfer>(); mListTransfer.Add(OnGetEvent); mListTransfer.Add(OnCheackEvent); mListTransfer.Add(OnFinishEvent); mListTransfer.Add(OnRewardEvent); mListTransfer.Add(OnCancelEvent); } public static TransferEvent Instance { get { if (mInstance == null) mInstance = new TransferEvent(); return mInstance; } } public bool isCheackNull(System.Int16 index) { return mListTransfer[index] == null ? true:false ; } //添加事件 public void AddEventListen(MesTransfer temp,System.Int16 index) { if (mListTransfer[index]!=null) return; mListTransfer[index] += temp; } //回调事件 public void InvokeEventListen(System.Int16 index,TaskArgs args) { if (index > mListTransfer.Count - 1) { Debug.Log("链表索引越界"); return; } MesTransfer mes = mListTransfer[index]; if (mListTransfer[index]!=null) { if (!isCheackNull(index)) mes(args); } } //清空所有的监听事件 public void ClearListTransfer() { int i = 0; IEnumerator listEnumerartor=mListTransfer.GetEnumerator(); while(listEnumerartor.MoveNext()) { MesTransfer mes = (MesTransfer)listEnumerartor.Current ; mes -= mAddListener; i++; } mListTransfer.Clear(); } } 这是一个事件委托的管理类网上的模板很多,大概都是这个样子了,只要是对事件的增加监听,或者事件回调,和观察者模式很像,主要是为了降低代码之间的耦合性的,如果对委托不是很了解建议自己网上去查,或者照着我这个敲一遍练练手还是可以的。 public class SMSNotifiler :MonoSingletions<SMSNotifiler> { private void Start() { TransferEvent.Instance.AddEventListen(GetPrintInfo, (System.Int16)EventType.OnGetEvent); TransferEvent.Instance.AddEventListen(finishPrintInfo, (System.Int16)EventType.OnFinishEvent); TransferEvent.Instance.AddEventListen(rewardPrintInfo, (System.Int16)EventType.OnRewardEvent); TransferEvent.Instance.AddEventListen(cancelPrintInfo, (System.Int16)EventType.OnCancelEvent); TransferEvent.Instance.AddEventListen(cheackPrintInfo, (System.Int16)EventType.OnCheackEvent); } public void GetPrintInfo(TaskArgs e) { print("接受任务" + e.taskId); } public void finishPrintInfo(TaskArgs e) { print("完成任务" + e.taskId); } public void rewardPrintInfo(TaskArgs e) { print("奖励物品" + e.id + "数量" + e.amount); } public void cancelPrintInfo(TaskArgs e) { print("取消任务" + e.taskId); } public void cheackPrintInfo(TaskArgs e) { print(string.Format("任务是{0},{1}完成了{2}",e.taskId,e.id,e.amount)); } 就像类名一样这个就是相关提示信息,由TaskManager中的去发布信息,然后Notifiler去执行相关细节而已,也是非常简单的脚本。 public class ControllerTest : MonoBehaviour { private SMSNotifiler mSMSNotifiler; private TaskManager mTaskManager; void Start() { if(mSMSNotifiler==null) mSMSNotifiler = SMSNotifiler.Instance; if (mTaskManager == null) mTaskManager = TaskManager.Instance; } private void OnGUI() { if (GUILayout.Button("接受任务Task1")) { mTaskManager.AcceptTask("T001"); } if (GUILayout.Button("接受任务Task2")) { mTaskManager.AcceptTask("T002"); } if (GUILayout.Button("接受任务T003")) { mTaskManager.AcceptTask("T003"); } if (GUILayout.Button("打怪Enemy1")) { TaskArgs e = new TaskArgs(); e.id = "Enemy1"; e.amount = 1; mTaskManager.CheackTask(e); } if (GUILayout.Button("打怪Enemy2")) { TaskArgs e = new TaskArgs(); e.id = "Enemy2"; e.amount = 1; mTaskManager.CheackTask(e); } } } 这个ControllerTest挂在unity的主场景中会自动添加相关的调用代码比如:TaskManager,主要是一个你游戏任务的相关操作都可以写这里,这个类只是一个简单的示例,比如添加不同的任务参数种类等等。 好了这个任务相对比较简单,不过我自己觉得也算是五脏俱全了吧,欢迎给我大佬指正不足的地方。最后是项目的工程文件下载地址https://download.csdn.net/download/martins1994/10402293 |
Unity 实现任务系统 TaskSystem
猜你喜欢
转载自blog.csdn.net/martins1994/article/details/80250593
今日推荐
周排行