Unity时光倒流效果实现<25/11/2017>
场景:一个Panel,一个由众多小Cube堆叠而成的巨大Cube,巨大Cube中心放置爆炸点Bomb.
实现方式:一共就三个脚本,每个Cube挂载一个TimeBack用来记录每帧的位置和旋转数据,一个Bomb用来促成爆炸效果的实现,然后还有一个Information用来定义数据结构类型不用挂载
最终效果:(Shift倒播前五秒记录信息,按下Space进行引爆)
面板简介:
三大脚本:
Information:
using System; using UnityEngine; /// <summary> /// 记录物体的位置跟旋转信息,用于实现时光倒流的技能 /// </summary> public class Information { public Vector3 position; public Quaternion rotation; public Information(Vector3 _position, Quaternion _rotation) { position = _position; rotation = _rotation; } }TimeBack:
using UnityEngine; using System.Collections; using System.Collections.Generic; public class TimeBack : MonoBehaviour { public bool isRewinding = false;//用来判断是否需要时光逆流 public float recordTime;//时光逆流时间 private List<Information> informations; private Rigidbody rb; void Start() { rb = GetComponent<Rigidbody>(); informations = new List<Information>(); } void Update() { //按下shift开始时光倒流 if (Input.GetKeyDown(KeyCode.LeftShift)) { StartRewind(); } //松开时停止 if (Input.GetKeyUp(KeyCode.LeftShift)) { StopRewind(); } } void FixedUpdate() { if (isRewinding) Rewind(); else Record(); } /// <summary> /// 开始时光逆流 /// </summary> private void StartRewind() { isRewinding = true; rb.isKinematic = true;//使物体不受力 } /// <summary> /// 停止时光逆流 /// </summary> private void StopRewind() { isRewinding = false; rb.isKinematic = false;//物体开始受力 } /// <summary> /// 时光逆流 /// </summary> private void Rewind() { //记录点数量大于0时才可以倒流 if (informations.Count > 0) { Information information = informations[0]; transform.position = information.position; transform.rotation = information.rotation; informations.RemoveAt(0); } } /// <summary> /// 记录物体的信息 /// </summary> private void Record() { if (informations.Count > Mathf.Round(recordTime / Time.fixedDeltaTime))//计算出记录时间在对应fixedDeltaTime中一共有多少帧 { informations.RemoveAt(informations.Count - 1);//移除最后一个 } informations.Insert(0, new Information(transform.position, transform.rotation));//在最前面插入记录点信息 } }Bomb:
using UnityEngine; using System.Collections; public class Bomb : MonoBehaviour { public float radius = 5.0f;//爆炸半径 public float power = 10;//爆炸力 public float explosiveLift = 1.0f;//从下方多少距离施加力 void Update() { if (Input.GetKeyDown(KeyCode.Space)) Fire(); } private void Fire() { Vector3 pos = transform.position; Collider[] colliders = Physics.OverlapSphere(pos, radius); foreach (var hit in colliders) { if (hit.GetComponent<Rigidbody>()) { hit.GetComponent<Rigidbody>().AddExplosionForce(power, pos, radius, explosiveLift); } } } }再来欣赏下效果,哈哈哈: