用Unity实现时间倒退效果
记得以前看过一个电影,叫做《独立游戏大电影》,其中有个一个游戏可以实现时间回退的功能,可以像倒带一样,十分有趣。因此我就想着用Unity也实现一个类似的简单Demo,说不定哪天会用到。
效果

这个Demo可以回退Transform的Position和Rotation。
思路
一个简单的思路就是用Stack来记录物体的Position和Rotation,当需要时间回退的时候就Pop出来,赋值到物体上。
不过为了可以进行拓展,比如只能回退到某段时间内的,而不是一下子回退到最开始的地方,我们需要剔除太久之前的信息。如下图:

因此我选择使用List而不是Stack。
代码
[完整代码看文章尾]
//Pos
Vector3 pos = this.transform.position;
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
if (Mathf.Abs(horizontal) > 0.0001f) //左右移动
{
pos.x += Time.deltaTime * horizontal * Speed;
}
if (Mathf.Abs(vertical) > 0.0001f) //上下移动
{
pos.y += Time.deltaTime * vertical * Speed;
}
this.transform.position = pos;
HistoryPos.Add(pos);
这里HistoryPos就是我们用来存储历史位置的List,我们每帧都存储物体的位置。
当我们需要时间回退时,可以每帧调用下面的代码:
if (HistoryPos.Count > 0)
{
int index = HistoryPos.Count - 1;
this.transform.position = HistoryPos[index];
HistoryPos.RemoveAt(index);
}
这就是每次取出最后的位置(即最新的),赋值到物体上
当我们需要限制时间回退的时间跨度,可以在HistoryPos.Add后加上下面这些代码:
HistoryPos.Add(pos);
if (ShouldLimit && HistoryPos.Count > Limit)
{
HistoryPos.RemoveAt(0);
}
因为旋转是雷同的,因此就不贴代码出来了。
改进
- 这里我们是每帧都记录信息,这样List的大小很容易暴走,因此我们可以每隔一段时间来记录,然后要时间回退的时候就进行插值。
- 通常我们的物体都带有动画,这时倒播动画就行。如果在时间回退过程中存在多个动画,我们就需要自己设计数据结构来保存某个时刻对应的动画和动画状态。
完整代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 就是利用Stack的原理来获取历史位置
/// 如果同时有动画,把动画倒放就是
/// </summary>
public class TBPlayer : MonoBehaviour {
public int Speed = 3;
public int RotateSpeed = 100;
public bool ShouldLimit = false;
public int Limit = 100; //可以存放的坐标上限
private List<Vector3> HistoryPos;
private List<Quaternion> HistoryRot;
private bool _IsTimeBack = false;
void Start () {
HistoryPos = new List<Vector3>();
HistoryRot = new List<Quaternion>();
}
void Update () {
if (_IsTimeBack)
TimeBack();
else
ControlPos();
}
void ControlPos()
{
//Pos
Vector3 pos = this.transform.position;
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
if (Mathf.Abs(horizontal) > 0.0001f) //左右移动
{
pos.x += Time.deltaTime * horizontal * Speed;
}
if (Mathf.Abs(vertical) > 0.0001f) //上下移动
{
pos.y += Time.deltaTime * vertical * Speed;
}
this.transform.position = pos;
HistoryPos.Add(pos);
//Rotation
Quaternion rot = this.transform.rotation;
Vector3 rotv = rot.eulerAngles;
float rotate = Input.GetAxis("Fire1");
if (Mathf.Abs(rotate) > 0.0001f)
{
rotv.z += Time.deltaTime * rotate * RotateSpeed;
}
rot = Quaternion.Euler(rotv);
this.transform.rotation = rot;
HistoryRot.Add(rot);
if (ShouldLimit && HistoryPos.Count > Limit)
{
HistoryPos.RemoveAt(0);
HistoryRot.RemoveAt(0);
}
}
void TimeBack()
{
if (HistoryPos.Count > 0)
{
int index = HistoryPos.Count - 1;
this.transform.position = HistoryPos[index];
HistoryPos.RemoveAt(index);
}
if (HistoryRot.Count > 0)
{
int index = HistoryRot.Count - 1;
this.transform.rotation = HistoryRot[index];
HistoryRot.RemoveAt(index);
}
}
void OnGUI()
{
if (GUILayout.Button("时间倒流"))
{
_IsTimeBack = true;
}
if (GUILayout.Button("Reset"))
{
HistoryRot.Clear();
HistoryPos.Clear();
_IsTimeBack = false;
}
}
}
用Unity实现时间倒退效果的更多相关文章
- Unity 实现物体破碎效果(转)
感谢网友分享,原文地址(How to Make an Object Shatter Into Smaller Fragments in Unity),中文翻译地址(Unity实现物体破碎效果) In ...
- CSS3实现时间轴效果
原文:CSS3实现时间轴效果 最近打开电脑就能看到极客学院什么新用户vip免费一个月,就进去看看咯,这里就不说它的课程怎么滴了,里面实战路径图页面看到了这个效果: 有点像时间轴的赶脚,而且每一块鼠标悬 ...
- 使用ExpandableListView时间轴效果达到
不废话,首先在地图上,查看结果 这是用ExpandableListView来实现时间轴效果,原理比較简单,以月份为第一级,以天为第二级来实现的. package com.hj.main; import ...
- Asp.net+jquery+ajaxpro异步仿Facebook纵向时间轴效果
Asp.net+jquery+ajaxpro异步仿Facebook纵向时间轴效果 在一个项目中,用到了时间轴展示产品的开发进度,为了更好用户体验,想到了Facebook的timeline效果, 搜了一 ...
- Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!
Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...
- JS时间轴效果(类似于qq空间时间轴效果)
在上一家公司写了一个时间轴效果,今天整理了下,感觉有必要写一篇博客出来 给大家分享分享 当然代码还有很多不足的地方,希望大家多指点指点下,此效果类似于QQ空间或者人人网空间时间轴效果,当时也是为了需求 ...
- Android时间轴效果,直接使用在你的项目中
近期开发app搞到历史查询,受腾讯qq的启示,搞一个具有时间轴效果的ui,看上去还能够,然后立即想到分享给小伙伴,,大家一起来看看,先上效果图吧 watermark/2/text/aHR0cDovL2 ...
- js实现的时间轴效果
今天整理以前的资料发现以前写的一个时间轴效果,当时也是网上找了很久没有找到,就自己写了一个,现在发出来给有需要的人,代码写的可能有点乱. 效果图: 下面是美工做的设计图的效果(有个美工就是好): 下面 ...
- jQuery鼠标滑过横向时间轴效果
jQuery鼠标滑过横向时间轴效果---效果图: jQuery鼠标滑过横向时间轴效果---全部代码: <!DOCTYPE html> <html> <head> & ...
随机推荐
- html5 Application Cache 机制以及使用
那什么是Application Cache呢? 顾名思义,AppCache就是对app内存缓存的方案,具体表现为当请求某个文件时不是从网络获取该文件,而是从本地内存中获取. Application C ...
- JavaScript跨域提交数据
1.通过jsonp跨域 场景:假设前台有JS方法"crossJS", 1.1发送请求http://www.xxx.com/?callback=crossJS.(创建一个scr ...
- Jquery知识点
Jquery $代表选择器 JS 选取元素 操作内容 操作属性 操作样式 <div id="aa" style="width:100px; height:100px ...
- TFS API:一、TFS 体系结构和概念
TFS API:一.TFS 体系结构和概念 TFS是Team Fundation Server的简称,是微软VSTS的一部分,它是Microsoft应用程序生命周期管理(ALM)工具的核心协作平台, ...
- elasticsearch5.0.0 安装插件及配置过程
elasticsearch5.0.0 安装插件及配置过程 由于es5.0是里程碑式的更新,所以很多变化的地方,暂时我就插件安装遇到的问题记录一下. 插件安装命令 2.3版本的安装命令 安装Marvel ...
- Python爬虫进阶二之PySpider框架安装配置
关于 首先,在此附上项目的地址,以及官方文档 PySpider 官方文档 安装 1. pip 首先确保你已经安装了pip,若没有安装,请参照 pip安装 2. phantomjs PhantomJS ...
- Python-类的属性
类的属性,可以称为成员变量 类的方法,可以称为成员函数 对象的创建 - 创建对象的过程称之为实例化:当一个对象被创建后,包含三个方面的特性:对象句柄.属性和方法. - 句柄用于区分不同的对象(实例 ...
- ExecutorService中submit()和execute()的区别
在使用java.util.concurrent下关于线程池一些类的时候,相信很多人和我一样,总是分不清submit()和execute()的区别,今天从源码方面分析总结一下. 通常,我们通过Execu ...
- OpenLayers 3 之 地图样式(ol.style)详解
地图样式是由 style 类控制的,其包含了地图样式的方方面面,例如,填充色.图标样式.图片样式.规则图形样式.边界样式.文字样式等,样式一般针对矢量要素图层. 矢量图层样式可以事先写好,写成静态的, ...
- 修改socket为keepAlive
参考文章:http://blog.csdn.net/ctthuangcheng/article/details/8596818 [root@mdw- gpadmin]# vi /etc/sysctl. ...