当前位置:丝路教程网 > Unity3D >

Unity3d教程:如何实现时间倒退效果

2018-01-12 09:26 来源: 丝路教程网 分类: Unity3D
147 作者:丝路教程网

[导读] 有一些游戏提供了回退的功能,在游戏开发中如何实现时间倒退这个效果呢,可能有人不知道怎么操作,为此下面unity 3D培训班就给大家介绍下实现时间倒退效果的方法。

  有一些游戏提供了回退的功能,在游戏开发中如何实现时间倒退这个效果呢,可能有人不知道怎么操作,为此下面unity 3D培训班就给大家介绍下实现时间倒退效果的方法。

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

unity 3d教程

  因此这里选择使用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;

  ///

  /// 就是利用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;

  }

  }

  }

  最终完成的效果

 


免责声明:

丝路教程网的部分文章信息来源于网络以及网友投稿,本网站只负责对文章进行整理、排版、编辑,是出于传递更多信息之目的,如权利人发现存在误传其作品情形,请及时与本站联系。

Unity3d教程:如何实现时间倒退效果

的相关文章
Copyright © 2008-2017 blog.silucg.com 丝路教程网 版权所有 网站地图
点击这里给我发消息
丝路教育