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

Posted 努力码代码走上人生巅峰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity学习基于JSON的UI回放系统(倍速)相关的知识,希望对你有一定的参考价值。

【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下载

以上是关于Unity学习基于JSON的UI回放系统(倍速)的主要内容,如果未能解决你的问题,请参考以下文章

Unity学习基于JSON的UI回放系统

Unity学习基于JSON的UI回放系统

Unity学习完全基于Ultimate Replay 2.0的UI回放系统

Unity学习完全基于Ultimate Replay 2.0的UI回放系统

复习,网课,视频回放,太慢怎么办,试试倍速播放吧 (无需下载)

Unity 动画系列十一 Animator Record 录制与回放