游戏开发之任务系统

今天我们来揭秘任务系统的制作。

目录

一、需求分析

二、设计数据表

三、制作功能

四、总结


一、需求分析

首先我们获得需求:游戏的主界面有任务的入口,打开之后可以看见各种各样的任务,点击接取之后接取任务,然后在游戏战斗界面就可以看见接取的相应任务,直到完成任务之后任务面板显示已完成,完成之后就可以接取其他的任务。

分析之后,我们大致可以知道至少有三个大类,一个是任务界面的面板逻辑,一个是任务栏(一个小任务Item的脚本类),一个是战斗界面的任务面板界面类。

二、设计数据表

根据这些内容,我们结合策划案配置数据表的表头:(注意这是简单的任务系统)

我们制作完之后将其转换为二进制数据,然后读取数据接入代码之后,数据分离的方式也方便数据日后修改。

三、制作功能

根据之前的分析我们制作任务面板类:

using System.Collections.Generic;
using UnityEngine;
using NicoleFrameWork;
using UnityEngine.UI;

public class TaskPanel : TaskPanelBase
{
    public override void Start()
    {
        base.Start();
        ChangeTaskNum();
        for (int i = 0; i < MyCardGameMgr.Instance.TaskInfoContainers.DataDic.Count; i++)
        {
            GameObject obj=PoolMgr.Instance.GetPoolObj("UI/TaskItem");
            obj.transform.position = new Vector3(0f,  i * (-220)+340, 0);
            obj.transform.SetParent(GetControl<ScrollRect>("TaskList").content,false);
            obj.GetComponent<TaskItem>().Init(MyCardGameMgr.Instance.TaskInfoContainers.DataDic[i+1].TaskRes,i+1);
            if (MyCardGameMgr.Instance.TaskItems.Count < 4)
            {
                MyCardGameMgr.Instance.TaskItems.Add(obj);
            }
            if (i == (int)MyCardGameMgr.Instance.ETask)
            {
                if (MyCardGameMgr.Instance.TaskInfoContainers.DataDic[(int)MyCardGameMgr.Instance.ETask + 1].IsFinish)
                {
                    obj.GetComponent<TaskItem>().FinshTask();
                }
                else
                {
                    obj.GetComponent<TaskItem>().GetTask();
                }
            }
            else
            {
                if (MyCardGameMgr.Instance.ETask != E_Task.Null)
                {
                    if (MyCardGameMgr.Instance.TaskInfoContainers.DataDic[i + 1].IsFinish)
                    {
                        obj.GetComponent<TaskItem>().FinshTask();
                    }
                    else if(MyCardGameMgr.Instance.IsTasking&&!MyCardGameMgr.Instance.TaskInfoContainers.DataDic[i + 1].IsFinish)obj.GetComponent<TaskItem>().NotCatch();
                }
                // else if(MyCardGameMgr.Instance.ETask!=E_Task.Null&&MyCardGameMgr.Instance.IsTasking) obj.GetComponent<TaskItem>().NotCatch();
            }
        }
        GetControl<ScrollRect>("TaskList").content.sizeDelta =
            new Vector2(0, 220 * MyCardGameMgr.Instance.TaskInfoContainers.DataDic.Count);
    }

    private void OnDestroy()
    {
        MyCardGameMgr.Instance.TaskItems.Clear() ;
    }

    /// <summary>
    /// 改变其他的接取状态
    /// </summary>
    public void ChangeType()
    {
        for (int i = 0; i < MyCardGameMgr.Instance.TaskInfoContainers.DataDic.Count; i++)
        {
            if(MyCardGameMgr.Instance.TaskItems[i].GetComponent<TaskItem>().IsCatch||MyCardGameMgr.Instance.TaskItems[i].GetComponent<TaskItem>().IsFinish)continue;
            MyCardGameMgr.Instance.TaskItems[i].GetComponent<TaskItem>().NotCatch();
        }
    }
    /// <summary>
    /// 修改玩家完成任务的数量(完成任务之后需要调用)
    /// </summary>
    public void ChangeTaskNum()
    {
        txtNum.text = $"游戏任务进度({MyCardGameMgr.Instance.FinishTaskNum}/4)";
    }

    protected override void BtnCloseClick()
    {
        base.BtnCloseClick();
        UIMgr.Instance.HidePanel<TaskPanel>(true);
    }


    public override void HideMe()
    {
        base.HideMe();
        
    }

    public override void ShowMe()
    {
        base.ShowMe();
        
    }

}

由于任务面板要加载不同的任务,于是我们制作小任务栏的面板:

using NicoleFrameWork;
using UnityEngine;
using UnityEngine.UI;

public enum E_Task
{
    /// <summary>
    /// 杀死一次怪兽(蜘蛛除外)
    /// </summary>
    Task1,
    /// <summary>
    /// 成功翻越一座高山
    /// </summary>
    Task2,
    /// <summary>
    /// 使用勇士职业通关
    /// </summary>
    Task3,
    /// <summary>
    /// 成功使用任意一次技能
    /// </summary>
    Task4,
    /// <summary>
    /// 什么任务都没有接取
    /// </summary>
    Null,
}
public class TaskItem : MonoBehaviour
{
    [Tooltip("任务具体内容")]
    public Text txtRes;
    [Tooltip("接取的按钮")] 
    public Button btnCatch;
    [Tooltip("按钮文字显示")]
    public Text txtButton;
    /// <summary>
    /// 记录该任务的任务ID
    /// </summary>
    public int ID;
    /// <summary>
    /// 该任务是否能够被接取
    /// </summary>
    public bool IsCanCatch = true;
    /// <summary>
    /// 该任务是否被接取了
    /// </summary>
    public bool IsCatch = false;

    public bool IsFinish = false;
    /// <summary>
    /// 已经接取任务的逻辑
    /// </summary>
    public void GetTask()
    {
        IsCatch = true;
        btnCatch.image.color = Color.white;
        txtButton.text = $"已接取";
        MyCardGameMgr.Instance.IsTasking = true;
    }

    public void FinshTask()
    {
        MyCardGameMgr.Instance.IsTasking = false;
        IsCatch = false;
        IsFinish = true;
        btnCatch.image.color = Color.white;
        txtButton.text = $"已完成";
    }
    public void Start()
    {
        //点击接取按钮之后发生的代码逻辑
        btnCatch.onClick.AddListener(() =>
        {
            if(!IsCanCatch||IsCatch||IsFinish)return;
            IsCatch = true;
            btnCatch.image.color = Color.white;
            txtButton.text = $"已接取";
            MyCardGameMgr.Instance.IsTasking = true;
            UIMgr.Instance.GetPanel<TaskPanel>((panel) =>
            {
                panel.ChangeType();
            });
            switch (ID)
            {
                case 1:
                    MyCardGameMgr.Instance.ETask = E_Task.Task1;
                    break;
                case 2:
                    MyCardGameMgr.Instance.ETask = E_Task.Task2;
                    break;
                case 3:
                    MyCardGameMgr.Instance.ETask = E_Task.Task3;
                    break;
                case 4:
                    MyCardGameMgr.Instance.ETask = E_Task.Task4;
                    break;
            }
        });
    }
    
    /// <summary>
    /// 用于初始化具体内容的方法
    /// </summary>
    /// <param name="txtRes"></param>
    public void Init(string txtRes,int id)
    {
        this.txtRes.text = txtRes;
        ID = id;
        if (MyCardGameMgr.Instance.TaskInfoContainers.DataDic[ID].IsFinish)
        {
            txtButton.text = $"已完成";
            IsFinish = true;
        }
    }
    /// <summary>
    /// 将按钮设置为不可接取的方法
    /// </summary>
    public void NotCatch()
    {
        btnCatch.image.color = Color.gray;
        txtButton.text = $"不可接取";
        IsCanCatch = false;
    }
    /// <summary>
    /// 将按钮设置为接取的状态
    /// </summary>
    public void CanCatch()
    {
        btnCatch.image.color = Color.white;
        txtButton.text = $"接取任务";
        IsCanCatch = true;
    }
}

制作完之后,开始制作战斗界面之中的任务看板:

using System.Collections.Generic;
using NicoleFrameWork;
using UnityEngine;

public class TaskSPanel : TaskSPanelBase
{
    public override void Start()
    {
        base.Start();
        Init();
    }
    /// <summary>
    /// 用于初始化任务面板的方法
    /// </summary>
    public void Init()
    {
        txtRes.text=MyCardGameMgr.Instance.TaskInfoContainers.DataDic[(int)MyCardGameMgr.Instance.ETask+1].TaskRes;
        NotFinish();
        BtnShow.gameObject.SetActive(false);
    }
    /// <summary>
    /// 未完成任务的代码逻辑
    /// </summary>
    public void NotFinish()
    {
        txtFinsh.text = "未完成";
        txtFinsh.color=Color.red;
    }
    /// <summary>
    /// 完成任务的代码逻辑
    /// </summary>
    public void FinishTask()
    {
        txtFinsh.text = "已完成";
        txtFinsh.color=Color.green;
        MyCardGameMgr.Instance.IsTasking = false;
        if (MyCardGameMgr.Instance.TaskInfoContainers.DataDic[(int)MyCardGameMgr.Instance.ETask + 1].IsFinish == true)
        {
            return;
        }
        MyCardGameMgr.Instance.FinishTaskNum++;
        if (MyCardGameMgr.Instance.FinishTaskNum == 4)
        {
            if(MyCardGameMgr.Instance.AccomplishmentInfoContainers.DataDic[1].IsFinish == true)return;
            MyCardGameMgr.Instance.FinishATask++;
            MyCardGameMgr.Instance.AccomplishmentInfoContainers.DataDic[1].IsFinish = true;
            //没有存档
        }
        MyCardGameMgr.Instance.TaskInfoContainers.DataDic[(int)MyCardGameMgr.Instance.ETask + 1].IsFinish = true;
        BinaryMgr.Instance.AutoCreatFile(MyCardGameMgr.Instance.TaskInfoContainers);
    }

    protected override void BtnHideClick()
    {
        base.BtnHideClick();
        BK.gameObject.SetActive(false);
        BtnShow.gameObject.SetActive(true);
    }

    protected override void BtnShowClick()
    {
        base.BtnShowClick();
        BK.gameObject.SetActive(true);
        BtnShow.gameObject.SetActive(false);
    }

    public override void HideMe()
    {
        base.HideMe();
        
    }

    public override void ShowMe()
    {
        base.ShowMe();
        
    }

}

四、总结

总结:每一次系统都需要先分析需求,然后制作数据表,之后我们根据分析的内容制作功能。(以上代码仅供参考)

希望大家能够喜欢,感谢!(作者不易,请点赞收藏一下吧)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nicole Potter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值