Unity时光倒流效果实现

时间:2023-02-03 19:08:02

Unity时光倒流效果实现<25/11/2017>

场景:一个Panel,一个由众多小Cube堆叠而成的巨大Cube,巨大Cube中心放置爆炸点Bomb.

实现方式:一共就三个脚本,每个Cube挂载一个TimeBack用来记录每帧的位置和旋转数据,一个Bomb用来促成爆炸效果的实现,然后还有一个Information用来定义数据结构类型不用挂载

最终效果:(Shift倒播前五秒记录信息,按下Space进行引爆)

Unity时光倒流效果实现

面板简介:

Unity时光倒流效果实现

三大脚本:

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);
            }
        }
    }
}
再来欣赏下效果,哈哈哈:

Unity时光倒流效果实现