本文主要是介绍Unity中的时间控制 - 时间倒退,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
转载自:Unity中的时间控制 - 时间倒退http://forum.china.unity3d.com/thread-22660-1-1.html
(出处: Unity官方中文论坛)
之前我们探讨了Unity中时间控制在关卡创建方面的应用,今天我们将以解谜游戏《Lintrix》为例,继续为大家分享在开发游戏的过程中,如何在Unity中实现时间倒退功能,并且对游戏设计与机制进行深入的探讨,希望能对大家有帮助。
时间倒退功能的必要性
在开发并试玩游戏的过程中,我们认识到玩家往往会忘记在关卡中犯过的错误,所以需要在游戏中做大量的记录。事实上,一些游戏关卡的设计目的就是为了从各个方向分散玩家的注意力,让玩家在某个时刻忽视某个方向来的敌人,最终导致游戏失败。当然,游戏中也有很多选择可以用来帮助玩家回想起发生过的事情,例如展示遇到过敌人的轨迹,或者在玩家之前的游戏过程中角色死亡次数比较多的地方设置警示点。
但有人担心这样做会让屏幕变得混乱,或者让玩家容易重复之前的行为而不去思考新的方式,降低了游戏的趣味性。为了解决这个问题,我们发现利用时间轴复用功能进行提示似乎是个不错的选择。因为每次游戏失败之后,在玩家点击“重新开始”按钮后,以相反的方向显示之前的游戏经历,如下图所示:
从失败那一刻开始,呈现最有可能导致失败的片段
但若要有一个完美的解决方案,应该还要知道之前发生了什么事情,记录下来作为回放。
实现方法
事实上,反向回放要做的工作几乎都在上一篇为关卡设置时间轴时就完成了。而下面将要讲述的方法,虽然可能这不是最优的解决方案,但是这种做法十分简单。
虽然用之前已经实现的后退操作就能完成敌人和水晶的运动。但是关卡中的其它事件是由玩家或者玩家动作触发的。对于这种情况,需要为TimeManager添加新的接口:
public delegate void ReversingTimeActionDelegate();
publicclassTimeManager
{classReversingActionWithTime{public float Time {get;set;}public ReversingTimeActionDelegate ActionToCarryOut {get;set;}}public void RememberAction(ReversingTimeActionDelegate action)
}
我们引入了ReversingActionWithTime这个类来记录动作的时间以及一个函数,它可以执行反向动作,这个逻辑与编程中的命令模式相似,但它是通过与时间绑定而不是点击ctrl+Z或其他类似的组合键来触发执行的。当关卡运行且动作发生时,只需要把RememberAction反向函数添加到这一时刻,如果想让时间倒退就可以调用这个函数。
例如当有敌人碰到屏障且消失时,就添加这个函数。在之后点击重新开始后,就可以回放到这一时间点了。 这个函数会自动用于再次激活敌人的TimeManager调用,使敌人出现在屏幕上:
publicclassEnemy{void onCollisionWithBarrier(){timeManager.RememberAction(Activate);Deactivate();}void Activate(){//进行激活相关的操作}
//.. 剩下的实现
}
在时间倒退模式中,我们并不关心碰撞,因为这些碰撞已经在游戏正常运行的时候发生了。只需要倒退游戏状态以更快的速度跳过一些帧即可, 这里不需要太强大的设备,因为倒退可以按照正常速度的20倍进行,并且关卡倒退完成就相当于重置所有对象的位置。
但是在某些情况下,也需要将一些变量的值存储在函数中。例如下图中黄色的搬运者敌人,一种在被消灭后会产生细小敌人的角色,它的确切运动需要记录下来,是因为生成的小敌人的运动轨迹会有1秒或2秒的随机延迟。
视觉反馈
为了让玩家更好地注意到时间倒退的发生,要添加一些视觉反馈功能。玩家非常喜欢游戏中时间倒退的部分,特别是引入像移动水晶或搬运者这些高端的东西的时候。时间倒退不仅是一个视觉体验,而且还能让玩家再回顾一次如何败给之前的敌人。这可以给玩家在游戏开始前留一些缓冲时间,可以减少一些挫败感。
当玩家成功地通关之后,我们大概都会做相似的事情。比如把界面切换到游戏地图,而不仅仅是打开下一关卡,播放不同类型的动画并且有专门的地方让玩家查看进度。
例如在上图中,我们把红色的敌人高亮了,因为这是玩家需要看到的最重要的东西,同时,这样还会得到一个很好的视觉效果。我们还添加了时间倒退小图标,虽然最开始我们尝试过类似VHS的时间倒退效果,但这不符合我们的视觉风格。这个简单的效果只需使用灰度就能实现,但要让值大于0.7的红色像素保持不变。
另外,如果想要将这个效果应用到相机而非单独的物体中,我们可以将着色器赋给某个材质,并将下面脚本绑定到相机中:
usingUnityEngine;publicclassBasicPostEffect:MonoBehaviour
{[SerializeField]Material mat;void OnRenderImage(RenderTexture src,RenderTexture dst){Graphics.Blit(src,dst,mat);}
}
接着,将新材质赋给相机对应的字段。有趣的事情是添加了这个效果之后,玩家最终可以直观的知道发生了什么事情,并且不再点击屏幕创建屏障了。同样有趣的是,有部分玩家观察到有一个倒退回放只会在十次重新开始后出现,但对这个回放丝毫没有印象。
基于上述的讨论,我们还添加了双击屏幕任何地方就能跳过倒退回放的功能,双击屏幕也算是玩家想跳过的时候最常见的反应了。
延伸思考
这篇教程还可以举一反三,尝试一些其它用法。例如在游戏中,玩家失败后就及时提供指示信息,然后倒退一点时间并让玩家再次挑战。在我们看来,这比让整个关卡重新开始,或在玩家要行动的时候停下来提示的做法要好。还可以倒退回玩家连续多次失败的关节点。
总结
希望您能轻松上手这个功能,实现时间倒退的效果。在下一篇文章中,我们会关注利用了时间轴的游戏设计,了解如何解决一些常见的问题并提升游戏质量。
这篇关于Unity中的时间控制 - 时间倒退的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!