Unity 使用事件代理实现任务管理功能

Unity 使用事件代理实现任务管理功能(初学者日记)

本功能是一个unity初学者基于消息中心 https://blog.csdn.net/Over_The_Clouds/article/details/102563065之上完成,杀死敌人任务测试正常,其余暂未测试

贴出代码:

任务管理中心

using System.Collections.Generic;
using System.Linq;
/// <summary>
/// 任务中心
/// </summary>
public class TaskManager
{
    private int id;
    private static TaskManager missionManager;

    /// <summary>
    /// 该对象的单例引用,并初始化了事件监听
    /// </summary>
    /// <returns></returns>
    public static TaskManager GetInstance() {
        if (missionManager == null) {
            missionManager = new TaskManager();
            //注册任务监听
            EventManager.CreateInstance().AddListener(TypeEvent.AddItem,
                new DelegateEvent.Handle(missionManager.updateTask));
            EventManager.CreateInstance().AddListener(TypeEvent.dialogue,
                new DelegateEvent.Handle(missionManager.updateTask));
            EventManager.CreateInstance().AddListener(TypeEvent.KillMonster,
                new DelegateEvent.Handle(missionManager.updateTask));
        }
        return missionManager;
    }
    //在对象被销毁前删除该监听
    ~TaskManager() {
        EventManager.CreateInstance().RemoveListener(TypeEvent.AddItem,
                new DelegateEvent.Handle(missionManager.updateTask));
        EventManager.CreateInstance().RemoveListener(TypeEvent.dialogue,
            new DelegateEvent.Handle(missionManager.updateTask));
        EventManager.CreateInstance().RemoveListener(TypeEvent.KillMonster,
            new DelegateEvent.Handle(missionManager.updateTask));
    }
    /// <summary>
    /// 任务列表
    /// </summary>
    private Dictionary<int, Task> listTask = new Dictionary<int, Task>();

    /// <summary>
    /// 获取一个任务id值
    /// </summary>
    /// <returns></returns>
    public int getTaskIndex() {
        return id++;
    }
    /// <summary>
    /// 增加一个任务
    /// </summary>
    /// <param name="task">任务内容</param>
    public bool addListTask(Task task) {
        if (!listTask.ContainsKey(task.id)) { 
            listTask.Add(task.id,task);
            return true;
        }
        return false;

    }
    /// <summary>
    /// 删除一条任务
    /// </summary>
    /// <param name="id">任务id</param>
    public void RemoveListTask(int id) {
        if (listTask.ContainsKey(id))
            listTask.Remove(id);
    }
    /// <summary>
    /// 获取指定任务
    /// </summary>
    /// <param name="id">任务id</param>
    /// <returns></returns>
    public Task getTaskById(int id) {
        if (listTask.ContainsKey(id))
            return listTask[id];
        return null;
    }
    /// <summary>
    /// 监听任务进程的方法
    /// </summary>
    /// <param name="data"></param>
    private void updateTask(EventData data) {
        foreach (Task task in listTask.Values) {
            if (task.state)
                break;
            if(data.type == TypeEvent.AddItem)
                if (task.maxItem != null)
                    task.updateTask0(data.data as Item);
            if (data.type == TypeEvent.KillMonster)
                if (task.maxKill != null)
                    task.updateTask1(data.data as Bean);
            if (data.type == TypeEvent.dialogue)
                if (task.dialogTask != null)
                    task.updateTask2(data.data as Bean);
            task.updateTaskState();
        }
    }

    /// <summary>
    /// 获取全部任务列表
    /// </summary>
    /// <returns></returns>
    public List<Task> getListTask() {
        return listTask.Values.ToList();
    }
    /// <summary>
    /// 获取已完成或未完成的任务列表
    /// </summary>
    /// <returns></returns>
    public List<Task> getListTask(bool t)
    {
        List<Task> tasks = new List<Task>();
        foreach (Task task in listTask.Values)
            if (t == task.state)
                tasks.Add(task);
        return tasks;
    }
}

任务类:

using System;
using System.Collections.Generic;
using System.Linq;

public class Task
{
    /// <summary>
    /// 任务Id
    /// </summary>
    public int id;
    /// <summary>
    /// 任务名称
    /// </summary>
    private string name;
    /// <summary>
    /// 任务状态
    /// </summary>
    public bool state = false;
    /// <summary>
    /// 提交状态
    /// </summary>
    public bool submit = false;
    /// <summary>
    /// 任务介绍
    /// </summary>
    public string introduce;
    /// <summary>
    /// 任务奖励
    /// </summary>
    public TaskReward reward; 
    /// <summary>
    /// 需要收集的物品及数量(0:物品名称 1:物品)
    /// </summary>
    public Dictionary<string, Item> maxItem;
    /// <summary>
    /// 当前已收集的物品及数量(0:物品名称 1:物品)
    /// </summary>
    public Dictionary<string, Item> thisItem;
    /// <summary>
    /// 需要kill的怪物及数量(0:怪物名称 1:怪物数量)
    /// </summary>
    public Dictionary<string, int> maxKill;
    /// <summary>
    /// 当前kill的怪物及数量(0:怪物名称 1:怪物数量)
    /// </summary>
    public Dictionary<string, int> thisKill;
    /// <summary>
    /// 需跟某些人物进行对话(0:人物名称 1:是否完成)
    /// </summary>
    public Dictionary<string, bool>dialogTask;

    /// <summary>
    /// 当前条件完成度
    /// </summary>
    public Dictionary<TypeEvent, bool> taskState = new Dictionary<TypeEvent, bool>{
            {TypeEvent.AddItem, false},
            {TypeEvent.KillMonster,false},
            {TypeEvent.dialogue,false}
        };

    /// <summary>
    /// 获得Task实例
    /// </summary>
    /// <param name="id">id</param>
    /// <param name="name">任务名称</param>
    /// <param name="introduce">任务介绍</param>
    /// <param name="maxItem">物品</param>
    /// <param name="maxKill">杀敌</param>
    /// <param name="dialogTask">对话</param>
    /// /// <param name="reward">任务奖励</param>
    public Task(int id, string name, string introduce, Dictionary<string, Item> maxItem,
       Dictionary<string, int> maxKill,Dictionary<string, bool> dialogTask, TaskReward reward)
    {
        this.id = id;
        this.name = name;
        this.introduce = introduce;
        this.maxItem = maxItem;
        this.maxKill = maxKill;
        this.dialogTask = dialogTask;
        this.reward = reward;

        if (maxItem != null)
        {
            this.thisItem = new Dictionary<string, Item>();
            foreach (Item item in maxItem.Values)
                this.thisItem.Add(item.name, item);
        }
        else
            this.taskState[TypeEvent.AddItem] = true;
            

        if (maxKill != null) 
        {
            this.thisKill = new Dictionary<string, int>();
            foreach (string s in maxKill.Keys)
                this.thisKill.Add(s,0);
        }else
            this.taskState[TypeEvent.KillMonster] = true;

        if(dialogTask == null)
            this.taskState[TypeEvent.dialogue] = true;

    }

    /// <summary>
    /// 当获得一个物品时被调用,判断当前获得物品是否在任务列表之中,是则加上该物品数量
    /// </summary>
    /// <param name="item">物品</param>
    public void updateTask0(Item item) 
    {
        //如果当前物品存在任务列表中
        if (thisItem.ContainsKey(item.name))
        {
            //使已获得数量+当前获得数量
            thisItem[item.name].number += item.number;
        }
    }
    /// <summary>
    /// 当kill一个怪物时被调用,判断当前怪物是否在任务列表之中,是则加上该怪物数量
    /// </summary>
    /// <param name="bean">怪物</param>
    public void updateTask1(Bean bean)
    {
        //如果当前怪物存在任务列表中
        if (thisKill.ContainsKey(bean.name))
        {
            //使已获得数量+当前获得数量
            thisKill[bean.name] += 1;
        }
    }
    /// <summary>
    /// 当跟一个角色进行对话时被调用
    /// </summary>
    /// <param name="bean">角色</param>
    public void updateTask2(Bean bean)
    {
        //当前对话的角色存在任务列表中 
        if (dialogTask.ContainsKey(name)) {
            if (!dialogTask[name])
                dialogTask[name] = true;
        }
    }

    /// <summary>
    /// 更新任务状态
    /// </summary>
    public void updateTaskState() {
        updateItemTask();
        updateKillTask();
        updateDialogueTask();

        //更新本次任务的状态
        foreach (bool state in taskState.Values)
            if (!state)
                return;

        //设置任务完成
        this.state = true;
    }

    private void updateItemTask() {
        //更新收集物品条件状态
        if (thisItem!=null && !taskState[TypeEvent.AddItem])
        {
            foreach (Item item in thisItem.Values)
            {
                if (item.number < maxItem[item.name].number)
                    return;
            }
            taskState[TypeEvent.AddItem] = true;
        }
    }
    private void updateKillTask()
    {
        //更新杀死怪物条件状态
        if (thisKill != null && !taskState[TypeEvent.KillMonster])
        {
            foreach (string name in thisKill.Keys)
            {
                if (thisKill[name] < maxKill[name])
                    return;
            }
            taskState[TypeEvent.KillMonster] = true;
        }
    }
    private void updateDialogueTask()
    {
        //更新对话条件 的状态
        if (dialogTask != null && !taskState[TypeEvent.dialogue])
        {
            foreach (bool state in dialogTask.Values)
            {
                if (!state)
                    return;
            }
            taskState[TypeEvent.dialogue] = true;
        }
    }
}

//调用测试

public void setTask() {
 		//未设置任务
        if (!settask)
        {
        	//添加任务奖励
            List<Item> items = new List<Item> {new Item("急救丸",2)};
            //获得任务实例
            Task task = new Task(11, "修复机器人", "请帮我把机器人全部修复", null,
                new Dictionary<string, int> { { "机器人", 5 } }, null, new TaskReward(1000,100,items)); ;
             //将任务添加进任务管理中心
            TaskManager.GetInstance().addListTask(task);
            //设置任务已发送
            settask = true;
        }
        else {
        	//根据id在任务列表中获取任务
            Task t = TaskManager.GetInstance().getTaskById(11);
            //如果任务完成
            if (t.state) {
                text.text = "哦,谢谢你";
                if (t.submit)
                    return;

                t.submit = true;
                Debug.Log("获得奖励:"+t.reward);
            }
            else
                text.text = "你还没有完成哦,已经修复了  "+t.thisKill["机器人"]+" 个机器人了,总共有 "+t.maxKill["机器人"]+" 个";
        }

    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值