查看: 1643|回复: 2
打印 上一主题 下一主题

[教程] 如何实现时间倒退效果

[复制链接]

436

主题

17

听众

4683

积分

中级设计师

Rank: 5Rank: 5

纳金币
1380
精华
9

最佳新人 活跃会员 热心会员 灌水之王 突出贡献 周年庆

跳转到指定楼层
楼主
发表于 2017-2-28 09:16:18 |只看该作者 |倒序浏览
有一些游戏提供了回退的功能,那么在游戏开发中如何实现时间倒退这个效果呢,相信会有很多人想知道,为此下面就给大家介绍下实现时间倒退效果的方法,一起来看看吧。

  一个简单的思路就是用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);
}

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

  改进

  1.这里我们是每帧都记录信息,这样List的大小很容易暴走,因此我们可以每隔一段时间来记录,然后要时间回退的时候就进行插值。

  2.通常我们的物体都带有动画,这时倒播动画就行。如果在时间回退过程中存在多个动画,我们就需要自己设计数据结构来保存某个时刻对应的动画和动画状态。

  完整代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

///
/// 就是利用Stack的原理来获取历史位置
/// 如果同时有动画,把动画倒放就是
///
public class TBPlayer : MonoBehaviour {
    public int Speed = 3;
    public int RotateSpeed = 100;
    public bool ShouldLimit = false;
    public int Limit = 100; //可以存放的坐标上限

    private List HistoryPos;
    private List HistoryRot;
    private bool _IsTimeBack = false;

    void Start () {
        HistoryPos = new List();
        HistoryRot = new List();
    }

    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;
        }
    }
}

效果.gif (1.19 MB, 下载次数: 440)

效果.gif

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏1 支持支持0 反对反对0
回复

使用道具 举报

0

主题

6

听众

834

积分

初级设计师

Rank: 3Rank: 3

纳金币
114
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2017-3-8 13:19:19 |只看该作者
受教了,谢谢楼主分享经验
回复

使用道具 举报

Kasug    

0

主题

2

听众

962

积分

初级设计师

Rank: 3Rank: 3

纳金币
151
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2017-12-14 10:24:57 |只看该作者
多谢楼主分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-25 01:07 , Processed in 0.096563 second(s), 34 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部