RPG游戏想必不用多介绍了,剧情系统是RPG游戏中必不可少的功能。
曾经听过一些朋友谈论:目前正在做一款RPG游戏,但是不知道如何实现RPG游戏中的剧情,仅仅实现了对话系统,主要问题在实际开发过程中发现,对话系统需要和人物动画、摄像机镜头等多个方面进行耦合,希望能够通过外部的配置文件来配置这些细节,使用脚本来进行处理,但是却没有好方法。
问题确实很多,但是静下心来仔细想,还有有一些思路的。
如果你认同代码即数据,c#就是一个不错的脚本语言。
我有两个观点的,请往下看:
首先需要明确剧情系统的目标:
剧情所要解决的核心问题就是:
如何调度不同的系统来处理分布在时间轴上面的剧情命令;
核心解决思路就是两个:
系统分层和协程。
制作RPG游戏的剧情需要有不同的系统协作:如同拍摄电影电视剧一样,最重要的是导演,负责调度控制剧情流程,而剧情的具体流程类似于剧本,影视剧中的剧本书写方法大部分都应该是:
首先确定拍摄的环境地点,人物
接着一行,一行描述,对话,镜头,人物的相关行为;
既然如此,我们制作游戏剧情也可以按照影视剧中剧本书写方法的流程来实现我们的功能。因为,游戏剧情系统做到最流弊的就是让玩家看起来就像看电影一样,对吧!越华丽越秀越好,当然了为了满足不同的玩家,我们也要添加跳过功能,因为,有一部分玩家就不喜欢看剧情,所以我们要贴合玩家。如果剧情做的特别好,就想给玩家看,但是玩家又不爱看怎么办呢,我们可以设置一个小奖励,比如观看完当前剧情,会给玩家发点虚拟物品,这样就会令一些不爱看剧情的玩家,也会去默默的观看剧情啦!咳。。咳。。,题外话说多了,继续我们今天的内容!
总之我们的目标就是,将剧情的配置方式完全参考电影剧本来做,采用命令模式描述就是:
场景 1 野外1;
创建玩家在 0,0点上;
创建怪物在 5,5点上;
UI展示剧情对话1,玩家头像:内容 → 你瞅啥?;
UI展示剧情对话2,怪物头像:内容 → 瞅你咋地!;
玩家 → 发动攻击;
延迟1s(攻击动作有延迟);
生成攻击特效;
拉近镜头到玩家身上;
如果要实现上面这种基于命令的配置方式,需要实现以下内容:
系统分层:
对话,UI,镜头控制,角色控制等是游戏中的不同系统,这些不同系统对外提供一些接口,用于实现对剧情展示的支持;
导演剧本:
针对每个剧情书写特定的剧本,来编写类似于与上面的剧情命令脚本;
开发量更小的方法,使用unity自带的协程来书写,类似于这样:
IEnumerator StoryProgress()
{
yield return StartCoroutine(CreatePlayer());
yield return StartCoroutine(CreateMonster()):
yield return StartCoroutine(ShowUI("Hello world"));
yield return StartCoroutine(WaitForEvent("MonsterDie"));
}
这样一个导演剧本是独立于所有系统的,只负责组织和操控其它系统;
通过协程我们可以实现,等待特定事件,等待某个操作结束,等待一定时间,而这3个能力,就可以实现一个优雅的线性的剧情描述了。
而只需要在合适的时候,执行上面的 StoryProgress,就可以做到通过特定的事件来触发特定的剧情。
当然你需要注意一点,在播放剧情之前,可能需要对当前游戏环境进行清理,例如网络游戏中,隐藏其它玩家,隐藏其它不相关怪物,等等。
而要开发相关的剧情编辑器的功能就是,将编辑好的时间轴生成相关的StoryProgress的c#代码即可。
至此一个优雅的剧情系统就完成了。
一个简单参考实现:
https://www.insideria.cn/article/category/game_development_tutorials
当然上面描述了这些,只解决了一个底层问题,即如何组织一个剧情故事;
而上层问题是,如何设定在合适的条件下,触发某个剧情,设计思路如下,首先设定某个剧情,在满足哪些条件的情况下触发;
例如:满足和Npc1对话过,和Npc2对话过,要和Npc3对话,背包里面有物品item1;
而剧情触发经常是在处理要和Npc3对话时,对条件进行检测;
因此需要在系统中存系统的条件变量,例如主线任务进行到某一步的条件变量;
当和某个NPC对话时,触发剧情检测,若条件变量满足,则触发剧情。
因此需要设计:主动触发剧情检测的观察点,系统的条件变量,以及满足哪些条件触发某个剧情相关配置。
举几个检测点的例子:
1:在和某NPC对话时检测剧情条件是否成立;
2:在进入场景的时候检测剧情条件是否成立;
3:在进入某个区域时检测剧情条件是否成立;