记得以前看过一个电影,叫做《独立游戏大电影》,其中有个一个游戏可以实现时间回退的功能,可以像倒带一样,十分有趣。因此我就想着用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);
}

因为旋转是雷同的,因此就不贴代码出来了。

改进

  1. 这里我们是每帧都记录信息,这样List的大小很容易暴走,因此我们可以每隔一段时间来记录,然后要时间回退的时候就进行插值。
  2. 通常我们的物体都带有动画,这时倒播动画就行。如果在时间回退过程中存在多个动画,我们就需要自己设计数据结构来保存某个时刻对应的动画和动画状态。

完整代码

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实现时间倒退效果的更多相关文章

  1. Unity 实现物体破碎效果(转)

    感谢网友分享,原文地址(How to Make an Object Shatter Into Smaller Fragments in Unity),中文翻译地址(Unity实现物体破碎效果) In ...

  2. CSS3实现时间轴效果

    原文:CSS3实现时间轴效果 最近打开电脑就能看到极客学院什么新用户vip免费一个月,就进去看看咯,这里就不说它的课程怎么滴了,里面实战路径图页面看到了这个效果: 有点像时间轴的赶脚,而且每一块鼠标悬 ...

  3. 使用ExpandableListView时间轴效果达到

    不废话,首先在地图上,查看结果 这是用ExpandableListView来实现时间轴效果,原理比較简单,以月份为第一级,以天为第二级来实现的. package com.hj.main; import ...

  4. Asp.net+jquery+ajaxpro异步仿Facebook纵向时间轴效果

    Asp.net+jquery+ajaxpro异步仿Facebook纵向时间轴效果 在一个项目中,用到了时间轴展示产品的开发进度,为了更好用户体验,想到了Facebook的timeline效果, 搜了一 ...

  5. Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!

    Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...

  6. JS时间轴效果(类似于qq空间时间轴效果)

    在上一家公司写了一个时间轴效果,今天整理了下,感觉有必要写一篇博客出来 给大家分享分享 当然代码还有很多不足的地方,希望大家多指点指点下,此效果类似于QQ空间或者人人网空间时间轴效果,当时也是为了需求 ...

  7. Android时间轴效果,直接使用在你的项目中

    近期开发app搞到历史查询,受腾讯qq的启示,搞一个具有时间轴效果的ui,看上去还能够,然后立即想到分享给小伙伴,,大家一起来看看,先上效果图吧 watermark/2/text/aHR0cDovL2 ...

  8. js实现的时间轴效果

    今天整理以前的资料发现以前写的一个时间轴效果,当时也是网上找了很久没有找到,就自己写了一个,现在发出来给有需要的人,代码写的可能有点乱. 效果图: 下面是美工做的设计图的效果(有个美工就是好): 下面 ...

  9. jQuery鼠标滑过横向时间轴效果

    jQuery鼠标滑过横向时间轴效果---效果图: jQuery鼠标滑过横向时间轴效果---全部代码: <!DOCTYPE html> <html> <head> & ...

随机推荐

  1. Java Graphics2D 画出文字描边效果

    在CSDN看到的,在此记下. (http://bbs.csdn.net/topics/390703095) import javax.swing.*; import java.awt.*; impor ...

  2. 浅谈Yii-admin的权限控制

    说到CMS,最需要有的东西就是权限控制,特别是一些复杂的场景,多用户,多角色,多部门,子父级查看等等.最近在开发一个线下销售的东东,这个系统分为管理员端,省代端,客户端,门店端,销售端, 部门端,部门 ...

  3. 【转】Redis入门

    Redis是一个开源,先进的key-value存储,并用于构建高性能,可扩展的Web应用程序的完美解决方案. Redis从它的许多竞争继承来的三个主要特点: Redis数据库完全在内存中,使用磁盘仅用 ...

  4. python之路:Day01 --- Python基础1

    本节内容 1.Python介绍 2.发展史 3.变量 4.用户输入 5.表达式 if...else语句 6.表达式 for 循环 7.表达式 while 循环 8.模块初识 9.数据类型初识 10.数 ...

  5. tp框架之分页与第三方类的应用

    1.先把分页类放在根目录下,比如放在某个模块下 2.在类里面写入命名空间,注意类名的格式(类名要与里面的方法名一致) 3.在需要的方法里面按照路径进行实例化,然后就可以使用了 方法: public f ...

  6. 用python实现一个不排序的列表功能

    #!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...

  7. [转]序列化悍将Protobuf-Net,入门动手实录

    最近在研究web api 2,看了一篇文章,讲解如何提升性能的, 在序列化速度的跑分中,Protobuf一骑绝尘,序列化速度快,性能强,体积小,所以打算了解下这个利器 1:安装篇 谷歌官方没有提供.n ...

  8. IT 网址

    蒋金楠 (Artech)            WCF ,asp.net等          博客地址:http://www.cnblogs.com/artech/tag/WCF/ 伍华聪       ...

  9. Keras官方Example里Mnist-cnn的调试运行

    问题:老板让测试运行Keras官网里的Mnist-cnn.py,结果从下载数据就是一路坑-- 当前环境:Ubuntu12.04.python2.7.Keras 1.1.1(不知道这个版本号对不对,在启 ...

  10. 好用的绿色工具(mss2sql,jd-gui)

    1.sql server导入mysql 神器(速度不是一般的快) mss2sql.exe 2.java 反序列化工具 jd-gui.exe