【Unity学习】基于JSON的UI回放系统(倍速)(二)

前言

因为本人要实现的是仿真回放系统,必然少不了三维物体的回放功能,这里使用Ultimate Replay 2.0来实现需要的功能,同时借助其api实现第一篇基于JSON的UI回放系统(一)中的倍速播放功能,此外本文还会介绍一种基于Ultimate Replay 2.0实现的UI回放方法。

视频演示

基于JSON的UI回放系统2

Ultimate Replay 2.0使用

插件本身具有详实的使用帮助文档和API文档,具体使用可下载插件免费版本结合Demo进行学习。

借助Ultimate Replay 2.0实现UI倍速回放

1.实现三维物体的Transform回放

首先需要在原有场景里加入Ultimate Replay 2.0的录制和回放方法,此处根据本人项目需要,使用文件存储的格式,如下:

using System.Collections;
using System.Collections.Generic;
using UltimateReplay;
using UltimateReplay.Storage;
using UnityEngine;

public class ReplayObjManager : Singleton<ReplayObjManager>
{
    private ReplayFileTarget recordStorage = null;
    private ReplayFileTarget playbackStorage = null;
    private ReplayHandle recordHandle;
    private ReplayHandle playbackHandle;
    private TaskRealTimeInfo taskRealTimeInfo;

    private void Start()
    {
        taskRealTimeInfo = FindObjectOfType<TaskRealTimeInfo>();
    }

    public void Record(bool b)
    {
        if (b)
        {
            ReplayManager.RegisterReplayPrefab(Resources.Load<ReplayObject>("Cube").gameObject);
            recordStorage = ReplayFileTarget.CreateReplayFile
                (@Application.streamingAssetsPath + "/Replay/ReplayFiles/" + taskRealTimeInfo.taskName.text + ".replay");
            recordHandle = ReplayManager.BeginRecording(recordStorage, null, false, true);
            Debug.LogWarning("开始录制");
        }
        else
        {
            // Stop recording
            if (ReplayManager.IsRecording(recordHandle) == true)
            {
                ReplayManager.StopRecording(ref recordHandle);
                recordHandle.Dispose();
                Debug.LogWarning("录制结束");
            }
        }
    }

    public void Replay(bool isReplay)
    {
        if (ReplayManager.IsReplaying(playbackHandle))
        {
            ReplayManager.StopPlayback(ref playbackHandle);
            Debug.LogWarning("回放停止");
            return;
        }
        if (!isReplay)
            return;
        // Start replaying
        playbackStorage = ReplayFileTarget.ReadReplayFile
            (@Application.streamingAssetsPath + "/Replay/ReplayFiles/" + ReplayUIManager.Instance.replayTaskName + ".replay");

        playbackHandle = ReplayManager.BeginPlayback(playbackStorage, null, true);
        Debug.LogWarning("开始回放");
        // Add end playback listener
        ReplayManager.AddPlaybackEndListener(playbackHandle, this.OnPlaybackComplete);
    }

    private void OnPlaybackComplete()
    {
        Debug.LogWarning("回放结束");
        playbackStorage.Dispose();
        playbackStorage = null;
    }

    protected override void OnDestroy()
    {
        base.OnDestroy();
        if (playbackStorage != null)
            playbackStorage.Dispose();

        if (recordStorage != null)
            recordStorage.Dispose();
    }

    private void OnApplicationQuit()
    {
        Record(false);
        Replay(false);
        if (playbackStorage != null)
            playbackStorage.Dispose();

        if (recordStorage != null)
            recordStorage.Dispose();
    }
}

在场景中添加Cube方块,添加ReplayTransform和ReplayObject组件如下,并将Cube放进Resources文件夹下:
在这里插入图片描述

最终效果如下:
在这里插入图片描述

2.实现三维物体和UI的倍速播放

更改ReplayObjManager脚本如下:

using System.Collections;
using System.Collections.Generic;
using UltimateReplay;
using UltimateReplay.Storage;
using UnityEngine;
using UnityEngine.UI;

public class ReplayObjManager : Singleton<ReplayObjManager>
{
    private ReplayFileTarget recordStorage = null;
    private ReplayFileTarget playbackStorage = null;
    private ReplayHandle recordHandle;
    private ReplayHandle playbackHandle;
    private TaskRealTimeInfo taskRealTimeInfo;
    public float replayTime;
    private float replayTimeScale;

    private void Start()
    {
        taskRealTimeInfo = FindObjectOfType<TaskRealTimeInfo>();
    }

    private void Update()
    {
        if (ReplayManager.IsReplaying(playbackHandle))
        {
            replayTime = ReplayManager.GetPlaybackTime(playbackHandle).Time;
        }
    }

    public void Record(bool b)
    {
        if (b)
        {
            ReplayManager.RegisterReplayPrefab(Resources.Load<ReplayObject>("Cube").gameObject);
            recordStorage = ReplayFileTarget.CreateReplayFile
                (@Application.streamingAssetsPath + "/Replay/ReplayFiles/" + taskRealTimeInfo.taskName.text + ".replay");
            recordHandle = ReplayManager.BeginRecording(recordStorage, null, false, true);
            Debug.LogWarning("开始录制");
        }
        else
        {
            // Stop recording
            if (ReplayManager.IsRecording(recordHandle) == true)
            {
                ReplayManager.StopRecording(ref recordHandle);
                recordHandle.Dispose();
                Debug.LogWarning("录制结束");
            }
        }
    }

    public void Replay(bool isReplay)
    {
        if (ReplayManager.IsReplaying(playbackHandle))
        {
            ReplayManager.StopPlayback(ref playbackHandle);
            Debug.LogWarning("回放停止");
            return;
        }
        if (!isReplay)
            return;
        // Start replaying
        playbackStorage = ReplayFileTarget.ReadReplayFile
            (@Application.streamingAssetsPath + "/Replay/ReplayFiles/" + ReplayUIManager.Instance.replayTaskName + ".replay");

        playbackHandle = ReplayManager.BeginPlayback(playbackStorage, null, true);
        Debug.LogWarning("开始回放");
        ReplayManager.SetPlaybackTimeScale(playbackHandle, replayTimeScale);
        // Add end playback listener
        ReplayManager.AddPlaybackEndListener(playbackHandle, this.OnPlaybackComplete);
    }

    private void OnPlaybackComplete()
    {
        Debug.LogWarning("回放结束");
        playbackStorage.Dispose();
        playbackStorage = null;
    }

    public void SetReplayTimeScale(int index)
    {
        switch (index)
        {
            case 0:
                SetReplayTimeScale(0.5f);
                break;
            case 1:
                SetReplayTimeScale(1f);
                break;
            case 2:
                SetReplayTimeScale(2f);
                break;
            default:
                break;
        }
    }

    private void SetReplayTimeScale(float scale)
    {
        replayTimeScale = scale;
        if (ReplayManager.IsReplaying(playbackHandle))
        {
            ReplayManager.SetPlaybackTimeScale(playbackHandle, replayTimeScale);
        }
    }

    protected override void OnDestroy()
    {
        base.OnDestroy();
        if (playbackStorage != null)
            playbackStorage.Dispose();

        if (recordStorage != null)
            recordStorage.Dispose();
    }

    private void OnApplicationQuit()
    {
        Record(false);
        Replay(false);
        if (playbackStorage != null)
            playbackStorage.Dispose();

        if (recordStorage != null)
            recordStorage.Dispose();
    }
}

更改ReplayUIManager脚本部分代码如下:

 private void ReplayRealtimeText()
    {
        foreach (var data in replayRealtimeTexts)
        {
            if (data.Equals(tempReplayRealtimeText))
                continue;
            dataTime = (int)(data.time * 100) * 0.01f;
            //sceneTime = (int)((Time.timeSinceLevelLoad - replayStartTime) * 100) * 0.01f;
            sceneTime = ReplayObjManager.Instance.replayTime;
            //if (dataTime == sceneTime)
            if (Mathf.Abs(dataTime-sceneTime)<0.1f)
            {
                taskRealTimeInfo.AddText(data.contentText);
                tempReplayRealtimeText = data;
                dataCount--;
                break;
            }
        }
    }

效果如下:
在这里插入图片描述

基于Ultimate Replay 2.0的另一种UI回放方法

Ultimate Replay 2.0本身只能回放物体的Transform、GameObject Enabled State、Component Enabled State、ParticleSystem、Material、Audio、Animator、LineRender、TrailRender等属性,没有明确说明可以回放UI系统的操作,但是可以通过自己添加脚本a继承ReplayBehaviour,将需要UI动态显示的textA(string)、textB(int)等属性暴露出来,添加[ReplayVar]特性,然后通过其他脚本b将脚本a中的textA(string)、textB(int)等属性赋值给对应的UI组件,这样就可以实现相应的UI回放功能,具体实现如下:

给上一步用到的Cube方块添加如下脚本:

using System.Collections;
using System.Collections.Generic;
using UltimateReplay;
using UnityEngine;

public class ReplayUIByUR2 : ReplayBehaviour
{
    [ReplayVar]public string textA;
    [ReplayVar] public int textB;
    private float interval = 1.5f;
    private float time = 0;

    private void Update()
    {
        if (IsRecording)
        {
            time += Time.deltaTime;
            if (time >= interval)
            {
                textA = "测试:" + Random.Range(0, 10).ToString();
                textB = Random.Range(0, 10);
                time = 0;
            }
        }
    }
}

往场景中添加如下样式UI组件:
在这里插入图片描述
并为其添加如下脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SetReplayUIByUR2 : MonoBehaviour
{
    public Text textA, textB;
    public ReplayUIByUR2 replayUIByUR2;

    // Update is called once per frame
    void Update()
    {
        textA.text = replayUIByUR2.textA;
        textB.text = replayUIByUR2.textB.ToString();
    }
}

最终演示效果如下:
请添加图片描述
请忽略上图出现的错误,我也不知道怎么解决,目前来看并无影响。

Demo下载

注意:Ultimate Replay 2.0支持Unity2019.4.32以及上版本,往下的版本打开会报错。本Demo使用的是2020.3.25f1c1版本。
Demo下载

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值