引言
近来在新的项目中负责开发任务系统,起初自己做了一份设计,后来经与同事的交流,发现从系统设计上还有诸多可以改善的空间,这里加以记录。
背景&需求
MMORPG游戏中的任务系统远了说从《征途》《传奇》《魔兽世界》开始,一直占据着串联游戏内容,增加游戏粘性,丰富游戏内容等等很多本身功能之外的责任。所以不无可避免的,任务系统会与游戏的中的各种其他模块打交道,从设计的角度上如何避免过度耦合就是一个要注意的难点了。
通常的任务系统,会由接受任务、对话系统、完成任务的指定条件、交付任务等几个阶段构成。近年来的手游作品又会在对话系统上下功夫,引入了诸如剧情动画,过场动画等增加代入感的小功能。在设计之处,显然要考虑到后期加入此类玩法的扩展性,对话系统可能会有分支的出现。
出现这类树形结构时,如何配置这样的对话成了一个问题。在程序数据结构的设计上,并非不可解决,然而如何通过配置文件配置出一棵形如二叉树的对话树就有些棘手了。
伪流程图
可以看出对话系统与后续的动作一般相连出现,而在设计对话系统时应该避免将对话系统与后续的动作耦合太深,对话系统作为一个相对独立的模块,只需关注何时进入对话,如何切换对话内容,何时结束对话等“份内”的工作,而不应该与系统外的功能发生联系。否则无论从配置上还是设计上,都会使任务系统越来越复杂。
上代码
借鉴插件式的设计思想,任务系统内类似对话系统的模块可以设计成插件式的结构
public class QuestBase : MonoBehaviour
{
public class DialogBase
{
public delegate void DialogEndEventHandler();
public event DialogEndEventHandler OnDialogEndEventHandler;
public void HandleStartDialog()
{
}
public void HandleStopDialog()
{
OnDialogEndEventHandler();
}
public void HandleOperateDialog()
{
//切换对话内容
}
}
DialogBase _dialogData;
...
}
当任务系统需要某个模块时,便初始化这个模块加入到任务数据当中,而整个任务的流程(这里指对话系统前后的行为,应该由对话系统的主体即任务系统来驱动,而不应与对话系统发生耦合)。