TimeBake:part1
原文链接:http://www.manew.com/thread-98803-1-1.html
如何建立一个波斯王子风格的时间倒回系统 Part1
在这个教程中,我们在中建一个小游戏,游戏中玩家可以倒回(它也可以修改适用于其他系统中)。第一部分我们学习这个系统的基本部分,下一部分,我们完善它,并让它有更多功能。
基本功能的演示 你需要用到Unity最新的版本,并有一些相关经验。如果你想核对自己的代码,源代码可以下载。 准备好了吧,现在开始。
这种倒回机制不仅仅整合到了游戏中,在故事和游戏世界也同样适用,整个故事中它也被反复提及。
一个有这种系统的游戏是《时空幻境(Braid)》,它也是围绕着时间的游戏。在Overwatch中,主人公Tracer有一种可以把自己重置到几秒种之前的位置的能力,即使是多人游戏,她也可以倒回她的时间。
这个系统不仅仅只用于及时存储,另一种用法是用在赛车游戏和异步多人游戏游戏中的幽灵。
《燥热(SUPERHOT)》也是记录你的动作。当你完成游戏后,你的整个进度会被回放并显示几秒钟内发生的实际动作。
《超级食肉男孩(Super Meat Boy)》的关卡最后,你之前所有的尝试都会被同时回放。
当你在空跑道上,为了最好的成绩赛车时,会使用到赛车幽灵(Race-Ghosting)技术。同一时间,你在跟一个幽灵比赛,它是一辆像幽灵一样透明的车,总是你在前面挡住你的。你不能撞上它,这样你可以集中精力得到好的成绩。
异步的多人游戏中有另一种用法。这是一种非常不常见的用法,通过记录玩家的数据并发送给其他玩家,来进行多人匹配,随后可以挑战第一个玩家进行战斗。数据就是应用的“时间偿试幽灵(time-trial-ghost)”的方式,只有这样,你才可能跟其他的玩家进行挑战。
Trackmania-games(一种反重力赛车体验游戏)中体现了这种形式,游戏中可以挑战一些难度。记录的赛事,会给你一个挑战对手,并得到一定的奖励。
一旦创建了这个功能,你就可以记录,观看之前的比赛了。重要的一点就是一切都要记录下来,而不仅仅是你的视野中的物体。这意味着,你可以移动记录的游戏世界,看到每个物体,从头到尾对他们进行控制。
为了测试系统,我们需要建一个简单的游戏来测试,现在创建一个。
在场景中创建一个立方体,作为我们的角色。再创建一个名为Player.cs的C#脚本,加一个如下的Update()函数:
1
2
3
4
|
void Update()
{
transform.Translate (Vector3.forward * 3.0f * Time.deltaTime * Input.GetAxis ( "Vertical" ));
transform.Rotate (Vector3.up * 200.0f * Time.deltaTime * Input.GetAxis ( "Horizontal" ));
}
|
现在创建一个新的C#脚本,命名为TimeController.cs,创建一个空的GameObject,绑定脚本。脚本处理实时记录和随时倒回游戏。
为了让它运行,我们会记录玩家的所有移动。当我们按下倒回按钮时,可以修正玩家的坐标。为此,首先要创建一个变量来保存玩家,像这样:
public GameObject player;
|
1
2
3
4
5
|
public ArrayList playerPositions;
void Start()
{
playerPositions = new ArrayList();
}
|
按下来我们需要持续地记录player的位置。我们会存下player最后一帧的位置,6帧前的位置,8秒前的位置(不论多长时间都会被记录下来)。当我们点击按钮想要倒回去时,通过我们的数据,可以一帧一帧地设置之前的位置,从而形成时间倒回的功能。
1
2
3
|
void FixedUpdate()
{
playerPositions.Add (player.transform.position);
}
|
public bool isReversing = false ;
|
01
02
03
04
05
06
07
08
09
10
|
void Update()
{
if (Input.GetKey(KeyCode.Space))
{
isReversing = true ;
}
else
{
isReversing = false ;
}
}
|
01
02
03
04
05
06
07
08
09
10
11
|
void FixedUpdate()
{
if (!isReversing)
{
playerPositions.Add (player.transform.position);
}
else
{
player.transform.position = (Vector3) playerPositions[playerPositions.Count - 1];
playerPositions.RemoveAt(playerPositions.Count - 1);
}
}
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
using UnityEngine;
using System.Collections;
public class TimeController: MonoBehaviour
{
public GameObject player;
public ArrayList playerPositions;
public bool isReversing = false ;
void Start()
{
playerPositions = new ArrayList();
}
void Update()
{
if (Input.GetKey(KeyCode.Space))
{
isReversing = true ;
}
else
{
isReversing = false ;
}
}
void FixedUpdate()
{
if (!isReversing)
{
playerPositions.Add (player.transform.position);
}
else
{
player.transform.position = (Vector3) playerPositions[playerPositions.Count - 1];
playerPositions.RemoveAt(playerPositions.Count - 1);
}
}
}
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
using UnityEngine;
using System.Collections;
public class Player: MonoBehaviour
{
private TimeController timeController;
void Start()
{
timeController = FindObjectOfType( typeof (TimeController)) as TimeController;
}
void Update()
{
if (!timeController.isReversing)
{
transform.Translate (Vector3.forward * 3.0f * Time.deltaTime * Input.GetAxis ( "Vertical" ));
transform.Rotate (Vector3.up * 200.0f * Time.deltaTime * Input.GetAxis ( "Horizontal" ));
}
}
}
|
现在,你可以在世界中移动,按下空格健进行回放你的动作。如果你下载下本贴的附件中已经建好的包,你可以打开TimeRewindingFunctionality01 ,试一试。
你需要另一个数据来存储旋转值,在最开始的时候初始化它,在处理位置数据的地方保存和应用数据。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
using UnityEngine;
using System.Collections;
public class TimeController: MonoBehaviour
{
public GameObject player;
public ArrayList playerPositions;
public ArrayList playerRotations;
public bool isReversing = false ;
void Start()
{
playerPositions = new ArrayList();
playerRotations = new ArrayList();
}
void Update()
{
if (Input.GetKey(KeyCode.Space))
{
isReversing = true ;
}
else
{
isReversing = false ;
}
}
void FixedUpdate()
{
if (!isReversing)
{
playerPositions.Add (player.transform.position);
playerRotations.Add (player.transform.localEulerAngles);
}
else
{
player.transform.position = (Vector3) playerPositions[playerPositions.Count - 1];
playerPositions.RemoveAt(playerPositions.Count - 1);
player.transform.localEulerAngles = (Vector3) playerRotations[playerRotations.Count - 1];
playerRotations.RemoveAt(playerRotations.Count - 1);
}
}
}
|
我们建立了一个可用的时间倒回系统的简单的原型,但它还没有完成。这个系列的下一部分,我们会让它更稳定和多样,再加一些好的效果。
- 每12帧记录一次,解决巨大的数据量
- 只保存最后75个Player的位置和旋转数据,以保正数据不会变得巨大,而引起崩溃。
之前只有player的属性,后面我们还会扩展一下这个系统:
- 记录更多的数据,而不是仅仅是player
- 增加特效显示回放正在进行
- 使用一个自定义类保存玩家位置和旋转数据,而不是用数组。
TimeBake:part1相关推荐
- Storefront与NetScaler的集成配置 - part1
Storefront与NetScaler的集成配置 - part1 http://kaiqian.blog.51cto.com/blog/236001/1344447 Storefront与NetSc ...
- Lync Server 2010标准版系列PART1:基础构建
可能环境准备已经是老生常谈的东西了,但我们搭建环境做测试.评估,或者说在客户生产环境做部署,非常需要重视的就是细节,力求做到一丝不苟,并且快速完成部署任务.所以在测试环境的搭建中,基础环境的准备是非常 ...
- 从零开始学Win32平台缓冲区溢出(Part1)
原文:Stack Based Buffer Overflow in Win 32 Platform: The Basics 译者:鸢尾 来源:从零开始学Win32平台缓冲区溢出(Part1) 缓冲区溢 ...
- Cocos2dx-demo演示项目:Part1
这个项目,我主要是用来积累.记录自己在利用cocos2dx引擎进行项目开发.学习实践中的开发经验.每天的开发任务.查看别人分享的内容,总是能够收获到可取的东西,将这些可取的东西自己再着手开发一次,能够 ...
- CS231n 学习笔记(1)——神经网络 part1 :图像分类与数据驱动方法
*此系列为斯坦福李飞飞团队的系列公开课"cs231n convolutional neural network for visual recognition "的学习笔记.本文主要 ...
- 写给大家看的机器学习书【Part1】什么是机器学习?机器学到的到底是什么?
写给大家看的机器学习书[Part1]什么是机器学习?机器学到的到底是什么? 机器学习 深度学习 神经网络 人工智能 阅读1390
- 黑客与画家 part1 版权声明 part2 O'Reilly Media,Ina.介绍
part1 版权声明 page 11 版权声明 英文原版O'Reilly Media,Ina.出版社2004. 简体中文版由人民邮电出版社出版,2011.英文原版的翻译得到O'Reilly Media ...
- 用PHP写一个最简单的解释器Part1
偶然间在朋友圈发现有人在看一本<两周自制脚本语言>,觉得写个脚本语言挺不错的,方便自己对语言本身进一步了解.于是乎,买了下来看了看,写的挺通俗易懂,但是不便的是,采用的语言是Java,PH ...
- Lync Server 2010迁移至Lync Server 2013部署系列 Part1: 扩展AD架构
由于最近直在忙Lync 升级,好久没有更新博客了,今天开始将对最近做的Lync Server 2010迁移至Lync Server 2013项目做一个系列的部署操作更新,希望能给即将在企业中部署的兄弟 ...
- std string与线程安全_C++标准库多线程简介Part1
Part1:线程与互斥量 本篇文章将简单的介绍一下C++的标准线程库,本篇内容十分基础,如果你有C++多线程相关的使用经验或者知识,就不必在这篇文章上浪费时间了... 如果你认为本篇文章对你有帮助,请 ...
最新文章
- oracle Hash Join及三种连接方式
- Android艺术——性能优化问题
- c#下实现GUI编程_程序员会懂的冷笑话:各大编程语言的内心独白
- 排序算法系列:插入排序算法
- 关于软件项目工作量估算的若干问题
- traceroute程序_来!程序猿教你们玩微信代码~
- 赞!Google 资深软件工程师 LeetCode 刷题笔记首次公开
- ms sql server 添加列,删除列。
- java this() super()_java中的this和super
- CentOS Linux 系统镜像文件(M1 Mac虚拟机专用)
- 【题解】Inspection UVa 1440 LA 4597 NEERC 2009
- 【Codeforces 1051D】Bicolorings
- jep-java-4.0-trial.jar 下载
- 状态模式,懂你的另一半
- 微信公众平台接口API
- 安全管理体系升级 迈动互联获得ISO国际认证
- 使用python创建学员管理系统
- THINKPHP6 运行出现Malformed UTF-8 characters, possibly incorrectly encoded
- Android 实现人脸识别检测时的扫描动画效果(二维码扫描动画效果同理)
- 计算机课各种造型靠图形教案,三年级信息技术课老师教案参照三篇
热门文章
- vb改变字形的代码是什么_VB怎么改变字体?
- linux脚本自动 输入命令,Linux脚本自动输入密码
- Java 反编译工具包(.class -> .java) 及其在 Minecraft 中相关应用
- python将经纬度标注在地图上_Python 给定的经纬度标注在地图上的实现方法
- Linux虚拟镜像下载
- 【避坑指南】GD32 KEIL中SW Device没有识别芯片,jlink下载不进去的问题
- 基于Fisher准则线性分类器设计
- C4D四视图切换及基本操作
- 总纲篇:产品结构设计指导VII(本博客指引章节)
- 《深入浅出通信原理》连载1-562合集