今天我们来揭秘任务系统的制作。
目录
一、需求分析
首先我们获得需求:游戏的主界面有任务的入口,打开之后可以看见各种各样的任务,点击接取之后接取任务,然后在游戏战斗界面就可以看见接取的相应任务,直到完成任务之后任务面板显示已完成,完成之后就可以接取其他的任务。
分析之后,我们大致可以知道至少有三个大类,一个是任务界面的面板逻辑,一个是任务栏(一个小任务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();
}
}
四、总结
总结:每一次系统都需要先分析需求,然后制作数据表,之后我们根据分析的内容制作功能。(以上代码仅供参考)
希望大家能够喜欢,感谢!(作者不易,请点赞收藏一下吧)