Unity中的时间控制 - 时间倒退

2024-02-09 22:38
文章标签 时间 控制 unity 倒退

本文主要是介绍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中的时间控制 - 时间倒退的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695467

相关文章

如何搭建并配置HTTPD文件服务及访问权限控制

《如何搭建并配置HTTPD文件服务及访问权限控制》:本文主要介绍如何搭建并配置HTTPD文件服务及访问权限控制的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、安装HTTPD服务二、HTTPD服务目录结构三、配置修改四、服务启动五、基于用户访问权限控制六、

利用Python实现时间序列动量策略

《利用Python实现时间序列动量策略》时间序列动量策略作为量化交易领域中最为持久且被深入研究的策略类型之一,其核心理念相对简明:对于显示上升趋势的资产建立多头头寸,对于呈现下降趋势的资产建立空头头寸... 目录引言传统策略面临的风险管理挑战波动率调整机制:实现风险标准化策略实施的技术细节波动率调整的战略价

Python日期和时间完全指南与实战

《Python日期和时间完全指南与实战》在软件开发领域,‌日期时间处理‌是贯穿系统设计全生命周期的重要基础能力,本文将深入解析Python日期时间的‌七大核心模块‌,通过‌企业级代码案例‌揭示最佳实践... 目录一、背景与核心价值二、核心模块详解与实战2.1 datetime模块四剑客2.2 时区处理黄金法

MySQL精准控制Binlog日志数量的三种方案

《MySQL精准控制Binlog日志数量的三种方案》作为数据库管理员,你是否经常为服务器磁盘爆满而抓狂?Binlog就像数据库的“黑匣子”,默默记录着每一次数据变动,但若放任不管,几天内这些日志文件就... 目录 一招修改配置文件:永久生效的控制术1.定位my.cnf文件2.添加核心参数不重启热更新:高手应

macOS Sequoia 15.5 发布: 改进邮件和屏幕使用时间功能

《macOSSequoia15.5发布:改进邮件和屏幕使用时间功能》经过常规Beta测试后,新的macOSSequoia15.5现已公开发布,但重要的新功能将被保留到WWDC和... MACOS Sequoia 15.5 正式发布!本次更新为 Mac 用户带来了一系列功能强化、错误修复和安全性提升,进一步增

Pandas进行周期与时间戳转换的方法

《Pandas进行周期与时间戳转换的方法》本教程将深入讲解如何在pandas中使用to_period()和to_timestamp()方法,完成时间戳与周期之间的转换,并结合实际应用场景展示这些方法的... 目录to_period() 时间戳转周期基本操作应用示例to_timestamp() 周期转时间戳基

JavaScript时间戳与时间的转化常用方法

《JavaScript时间戳与时间的转化常用方法》在JavaScript中,时间戳(Timestamp)通常指Unix时间戳,即从1970年1月1日00:00:00UTC到某个时间点经过的毫秒数,下面... 目录1. 获取当前时间戳2. 时间戳 → 时间对象3. 时间戳php → 格式化字符串4. 时间字符

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

SpringBoot请求参数接收控制指南分享

《SpringBoot请求参数接收控制指南分享》:本文主要介绍SpringBoot请求参数接收控制指南,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring Boot 请求参数接收控制指南1. 概述2. 有注解时参数接收方式对比3. 无注解时接收参数默认位置