Search Unity

[Released] Ultimate Replay 2.0 - Next generation state-based replay system

Discussion in 'Assets and Asset Store' started by scottyboy805, Sep 8, 2020.

  1. hauwing

    hauwing

    Joined:
    Dec 13, 2017
    Posts:
    69
    Hi thanks for getting back. Yes, interpolation is set in the Rigidbody of RaceCar. For simplicity, I have disabled the GhostCar completely. I tried different combinations of Update, Late update and Fixed Update in the Playback options, I found that Fixed Update is the worst. The playback FPS is kept as -1. Thanks.


    upload_2021-12-18_11-14-7.png
     
  2. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi again,
    Thanks for checking that and for the extra info. I had a quick look into it and I think I can see what you are talking about. I just added some more replay objects to the scene and I can see that the ghost vehicle has a slight stutter when in playback mode like it is snapping to the correct position almost, but it is quite subtle. I also noticed that the framerate stays nice and high too (Well into triple figures) when this occurs so it looks more like a problem with updating the playback rather than performance related. I will have to do some more testing and debugging to see if I can work out what might be causing the problem but I will let you know when I have looked into it a bit more.
    Let me know if you discover any more information relating to this issue in the meantime.
     
    firstuser likes this.
  3. hauwing

    hauwing

    Joined:
    Dec 13, 2017
    Posts:
    69
    Hello, any update? thx.
     
    julianr likes this.
  4. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, I believe this has now been reproduced and fixed on our end, but has not yet been released. We are just working on some other fixes and then hopefully we will have an update ready shortly if all goes well.
     
    julianr likes this.
  5. unity_FBD51AC9A7093C5E8B77

    unity_FBD51AC9A7093C5E8B77

    Joined:
    Oct 7, 2021
    Posts:
    1
    HI
    I am trying to add a slider for position, I have tried meany things but unable to do, however it's work in normal record and replay but when I try to save replay it's not work at all
     

    Attached Files:

  6. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, You say it works with a memory storage target but not a file target? Are you able to check the value of 'fileTarget.Duration' to see if it looks correct? We have had a couple of reports that the property is not working correctly in all cases and can return strange values and that could cause the seek issue you mention I believe.
     
  7. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Ultimate Replay 2.2.0 has been released on the asset store. This version includes:
    • Fixed an issue where calling 'ReplayScene.RemoveReplayObject' would only cause top level replay behaviours to be unregistered potentially causing exceptions stating that a destroyed component is still being accessed.
    • Fix a bug where bool values would not be deserialized correctly when used as replay variables or replay method arguments due to having no suitable deserialize method registered.
    • Fixed an issue where creating a new ReplayScene instance using the IEnumerable constructor could mean that the replay preparer was not setup correctly and cause issues down the line.
    • Fixed a bug in the replay ghost vehicle demo (Best lap version) where the replay file stream would not be disposed correctly if the ghost vehicle reached the finish line before the player vehicle causing IOSharing violations in some cases.
    • Remove test/debugging game objects and components from demo scenes to avoid missing script warnings on import.
    • Fix jittering issue in some cases caused by incorrect delta time.
    • Added support for replay variable field types that implement the IReplaySerialize interface.
    • Added support for replay method parameter types that implement the IReplaySerialize interface.
     
    julianr likes this.
  8. Japi

    Japi

    Joined:
    Jan 13, 2010
    Posts:
    14
    Hey, I'm wondering has anybody used this asset with animations that have been created with Spine? (As Spine doesn't use the Unity's Animator component, but have their own SkeletonAnimation component to control the animations)
     
  9. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, I am not familiar with Spine but does it have a skeleton transform setup that controls the movement of limbs etc? If so, then it will be possible to record and replay animation by attaching ReplayTransform components to all bones of the character. Other than that you can create a custom replay component as long as there is a way to read and write all necessary animation state information like current clip, time, parameters etc if applicable. It may be worth taking a look at the source code for the ReplayAnimatior component to see how we handle it.
     
  10. faisalqazi31

    faisalqazi31

    Joined:
    Apr 11, 2019
    Posts:
    1
    Hey! I have a Question.
    How does this Ultimate Replay records replay and show us? Actually i want to record my gameplay and then show recorded gameplay at the end of round or On Button Press, I search in asset store for some Replay Systems but they all record transform of gameobject at every frame but i want to record gameplay and show at the end of my game round. Does this ultimate replay do that kind of thing?
    Thanks.
    P.S: Sorry for bad english
     
  11. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, yes this is something that Ultimate Replay 2.0 can do.
    The asset works by recording properties of a game object at fixed intervals like transform, animator, particles and so on depending upon the replay components that you attach (ReplayTransform, ReplayAnimator, etc.).
    When you want to view the replay, the replay system will reconstruct the scene as best it can (Re-instantiate destroyed objects for example) and simulate the movements and other properties of these objects while rendering in real time. Using this approach means that we can save much less data when compared to screen recorders and also we can view the replay for new camera angles since it is rendered in real time.
    We do offer a free trial version of Ultimate Replay 2.0 so that might be worth checking out to learn more about the asset.

    I hope that helps you. Let me know if you have any more questions or if there is anything else.
     
  12. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Ultimate Replay 2.2.1 has been released on the asset store. This version includes the following changes:
    • Expose ComponentPreparer and ComponentPreparer(T) base types so that is it now possible to create additional preparers for components without needing to implement the 'IReplayPreparer' interface.
    • Component preparers will now be discovered in all loaded assemblies instead of just the Ultimate Replay 2.0 assembly.
     
  13. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    Hi! I am using this excellent plugin, along with Mirror, and facing this small problem:
    As you see, In mirror, there is a NetworkIdentity Component, which work just like ReplayObject, it mark gameobject as unique, and should only exist once in nested GameObjects (Check this for more detail).
    So, if you want to sync child's Transform, you need to Add NetworkTransformChild Component on root gameobject. Take Player gameobject as example, here's what we should do if we want to sync the body, head, hands:
    upload_2022-3-9_17-48-41.png

    However, I had read through the UserGuide, and it seems not have the component simular to NetworkTransformChild, and if I attach ReplayTransform to any child gameobject, the NetworkIdentity component will be auto attached as well (because ReplayBehaviour is inherited from NetworkBehaviour, which required NetworkIdentity component), which is not allowed by Mirror:
    upload_2022-3-9_18-1-57.png

    So I wonder, how should I record&replay the child gameobject like this on Network? Would it help if ReplayTransform expose the target Transform so that I can assign which child's Transform get record? Thanks again for your plugins again, big fan here!
     
  14. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    I don't really have too much experience with Mirror so forgive me on not really knowing the workings of it.
    I think I understand what the problem is but does it actually cause an issue having the 'NetworkIdentity' component added at each level in the hierarchy or is it just an optimization thing (One root 'NetworkIdentity' to manage the whole object like 'ReplayObject')? Like you say, the component is auto added because ReplayBehaviour an in turn ReplayTransform derives from 'NetworkBehaviour' when the 'MIRROR' define is set.
    I am not sure if it would be suitable but you can prevent Ultimate Replay types from deriving from 'NetworkBehaviour' if required by adding 'ULTIMATEREPLAY_SUPPRESS_MIRROR' define symbol in the player settings.
    Otherwise I think some changes would need to be made like you say to get around the problem, but I am not sure what those changes could be. Exposing a target 'transform' property in the 'ReplayTransform' component is not really an option we would want to go with because it could add extra complexity to setup, require extra null checks and quite a bit of refactoring of the code, change the overall philosophy of UR where one ReplayComponent per object is all you need (Currently a hard requirement for the ReplayTransform component) etc.
    I will have a little think about the problem but let me know if you have any more thoughts on how the assets could work well together.
     
  15. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    Thanks for response! Multi NetworkIdentity Component in nested GameObjects is not allowed, and here's what Mirror said:
    upload_2022-3-10_9-51-38.png

    And here's how Mirror deal with child gameobjects sync problem: You can attach multi NetworkTransformChild component on root gameobject to deal with each child gameobject, so that these components can relay on the same NetworkIdentity (Actually I think it's not so flexible, but it's how it works, Mirror just use the same implementation as UNET):


    So, if exposing the target Transform is not an option, how about a new Component named 'ReplayTransformChild', which work just like NetworkTransformChild? If not, I think adding 'ULTIMATEREPLAY_SUPPRESS_MIRROR' define symbol is the only choice, thanks!
     
  16. KoalityGame

    KoalityGame

    Joined:
    Jan 30, 2016
    Posts:
    21
    Hi @scottyboy805, thank you for developing this plugin! While testing out the trial version I wanted to build it for Android to see how well it works on mobile devices but ran into this error:

    ArgumentException: The Assembly UnityEditor is referenced by UltimateReplay ('Assets/Ultimate Replay 2.0/Plugin/UltimateReplay.dll'). But the dll is not allowed to be included or could not be found.

    Any help is appreciated!
     
  17. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    And here's other thing: If we try to add Assembly files for Ultimate ReplayV2 like this:

    Script Dir:
    upload_2022-3-10_11-22-32.png

    Editor Dir:
    upload_2022-3-10_11-23-50.png

    Demo Dir:
    upload_2022-3-10_11-24-40.png

    It will show the following error:
    upload_2022-3-10_11-25-48.png

    And the reason is the following field not set as public:
    • ReplayObject.isObservedComponentsExpanded
    • ReplayBehaviour.noManagingObject
    So I wonder, would you consider set those fields to public?
     
    Last edited: Mar 11, 2022
  18. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi again,
    I don't think it would be quite as easy as creating a new 'ReplayChildComponent' due to the way Ultimate Replay is setup. All replay components must derive from 'ReplayRecordableBehaviour' which in turn derives from 'ReplayBehaviour' which in turn derives from 'NetworkBehaviour' when mirror is installed. Creating a new replay component would cause the same problem, and also ReplayTransform is intended for use on both root and child objects in the UR workflow.
    I would suggest trying to disable the mirror functionality using the define I mentioned in the player settings to see if that is something that could solve the problem, because it seams like the simplest and easiest potential fix for the moment. Let me know if there are issues with that approach and maybe we can see what else can be done at that stage.

    Thanks for the heads up about the assembly definition issue. I don't think it should be a problem to make those few variables public if it can allow the use of assembly definitions. I will see if those changes can be added in the next update.
     
    Threeyes likes this.
  19. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    Thanks for the interest in our asset.
    Unfortunately we do not support standalone builds in the trial version or there would be no reason to buy the full asset. The trial version is only intended for testing out the capabilities of the asset in the Unity editor to see if it would be a good fit for your project. Purchasing the full version will remove all build restrictions and will also provide full C# source code for the asset.
    I hope that helps you.
     
    KoalityGame likes this.
  20. KoalityGame

    KoalityGame

    Joined:
    Jan 30, 2016
    Posts:
    21
    That makes total sense! Thank you I will be purchasing the full version to test it out on mobile :)
     
    scottyboy805 likes this.
  21. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    Hi! I wonder another thing about network recording.
    In multi-player games, an new player will get instantiated when the client is connected, and it will get a new replayID. In our game, we only begin the record when all players get instantiated, and the number of players are uncertain. So, can I open the replay file, find out all ReplayObject's that attached to the players, and manual instantiate player gameobjects and rebind them via ReplayObject.CloneReplayObjectIdentity?
    In short: can we read the replay file and read all ReplayObject info before replay?
     
  22. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    Usually the replay system will be setup so that dynamically spawned objects like players will be replay prefabs meaning that they can be destroyed and recreated automatically during playback. Ie the replay system will instantiate the player prefab during the replay automatically and will not use existing player objects in the scene unless they have an identical replay id, and are added to the current replay scene.
    You can manually assign a replay id to all players if you like so that they will always be predictable or known to the game, but the replay system will still take control over spawning such dynamic objects if needed assuming they are setup as replay prefabs. You could maybe take over the spawning and despawning callbacks to provide your own implementation, but then there is not enough information provided at that point to determine whether a game object is a player or not.
    To answer your main question: Yes it is possible to extract all replay objects and components from a storage target through the scripting API if that would help solve your problem. There is a mostly undocumented API that you can use to extract any piece of data from a replay file and there is a quick example shown in this post.
     
  23. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    Since we can't record before the Playersget spawned, so getting our hands dirty and mess up with record file seems to be the only option.
    That's exactly what I need! Appreciate!
     
    Last edited: Mar 15, 2022
    scottyboy805 likes this.
  24. ScottySR

    ScottySR

    Joined:
    Sep 29, 2018
    Posts:
    48
    Is it possible to configure the maximum length for a recording. I only want to keep the latest X seconds of recording and play it when certain events occur
     
  25. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, Yes that is possible if you are using a 'ReplayMemoryTarget' to record the data in memory. When creating a memory storage target as the destination to save the replay, you can specify a 'rollingBufferRecordSeconds' value which represents the X amount of seconds to keep in the replay. That means that the recording will only ever store the last X amount of seconds and will discard previous data by overwriting it to ensure that memory usage remains consistent and does not continually grow.
    I hope that helps you. Let me know if there is anything else.
     
  26. ScottySR

    ScottySR

    Joined:
    Sep 29, 2018
    Posts:
    48
    Do you have any idea why replaying some objects doesn't work? I have attached replay object and replay transform with position and rotation set for all axes.

    Replaying particle systems also seems to be pretty buggy. Sprite sheet animations get stuck to one sprite and are displayed when the particle system shouldn't even be on. For some particle effects the particles seem to spawn correctly, but they don't move.

    I also encountered a bug where a replay object loses it's scene id after the replay has ended resulting in a "Scene [scene_name] needs to be opened and resaved, because the scene object [object_name] has no valid sceneId yet." error and causing the gameplay to get stuck.
     
  27. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, It is difficult to say without seeing the project but here are a few things to check:
    1. Are the replay objects added to the replay scene? Should be the case if you are using the built in ReplayControls and the objects are in the active Unity scene.
    2. If you select a replay object in the hierarchy that is not functioning correct, can you check out the 'Observed Components' list in the inspector to make sure it lists the expected components like ReplayTransform.
    3. Do any replay objects in the scene have identical replay identities. It should not happen but it is possible in some rare cases.
    The particle system component is indeed a little limited in what it can do at the moment (Moving particles systems do not always play well) but it sounds like you could be dealing with a bug from what you describe. Would you be able to send the particle system as a .unitypackage to info(at)trivialinteractive.co.uk and I will be happy to take a look to see what the problem might be. If it is licensed content or you cannot share for some reason then some setup instructions to create a particle system with the same issues would be really helpful.

    Not sure what could be going on for the third issue, but if you mean the replay identity is resetting for replay objects and components then that is a problem and could very well be the cause of the first issue too. Id's should remain the same for replay objects placed in the scene unless there is a conflict for some reason, in which case Ultimate Replay might try to resolve that at edit time. Are there replay objects prefabs instances by any chance? If so could you try breaking the prefab link to see if that resolves the problem (Not a permanent solution and I would not expect you to do this to build your game but it will give me an idea of what the issue might relate to).
     
  28. ScottySR

    ScottySR

    Joined:
    Sep 29, 2018
    Posts:
    48
    I ran into another issue. I originally had some particle system recorders that I ended up deleting and adding custom code for that purpose. However the array that contains all the record components did not remove the old particle system recorder components and I'm getting null refs when running the game. They do not appear in the recordable object's list in inspector, but when adding breakpoint in code where the error happens and inspecting the array contents there are some null items in it.

    Is it possible to refresh this list so the null items wouldn't appear in the array?
    I did notice that some replay objects are not showing the approximation for bytes needed per sample, but I'm not sure if this is caused by it or if this causes it.

    The error occurs at ReplayObject.cs:166

    Here is a screen shot of the array contents if you need it:
    watch.PNG
     
  29. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hey,
    Thanks for reporting this. It looks like a bug where the runtime components collection can get out of sync and not update correctly when they should. I will make sure that is fixed in the next update but for now I think you will have to remove and re-add the ReplayObject component to fix the issue. There is an 'UpdateRuntimeComponents' method but it won't solve the problem in this case due to the bug.
     
  30. ScottySR

    ScottySR

    Joined:
    Sep 29, 2018
    Posts:
    48
    I did a bit more debugging and it seems like the one object that isn't replayed doesn't get
    OnReplaySerialize()
    called on it.

    Here is what I have in the inspector:

    rpl.PNG

    To my knowledge there shouldn't be anything wrong with this. Is there something else that can cause this? I did make sure that the object appears in the replay objects list.
     
  31. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    I am not sure why that could be the case. I assume you mean that the replay object is added to the current replay scene objects list? If so, then that is the only reason why a replay object should not be recorded.
    are you able to try setting a break point in the 'ReplayScene.CaptureSnapshot(...)' method, at around line 425 of 'Assets/Ultimate Replay 2.0/Scripts/ReplayScene.cs'. You should see a foreach loop around that line mark that iterates over all registered replay objects and calls the serialize method. You should be able to see why the method would not be called at that point, although I cannot see any obvious conditions as to why it would not be called if it was indeed added to the 'replayObject' list.
     
  32. ScottySR

    ScottySR

    Joined:
    Sep 29, 2018
    Posts:
    48
    It doesn't seem to appear in the
    replayObject
    list, but it is added to the
    allReplayObjects
    list in
    ReplayObject.cs
    . There seems to be more than one object missing from the
    replayObject
    list based on the difference in the size of these two lists.

    EDIT: Looks like the replay objects that are in the list are added to the list before the replay scene is created, and the ones that are missing are added after it. They are added to the replay prefabs list in the settings, so what else could be wrong here?

    EDIT 2: I also added the
    AddReplayObjectToPlaybackScenes()
    to the code, but it doesn't seem to fix it. (can that method be in the spawned object's
    awake()
    instead of right after
    Instantiate()
    ?)

    EDIT 3: Adding the object to the playback scene seems to fail at
    ReplayManager.cs:1077
     
    Last edited: Mar 30, 2022
  33. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, The 'allReplayObjects' list is not used to mark which replay objects will be recorded and replayed, although it is used as the source collection to scan all registered replay objects. It sounds more and more like your replay object is not added to the active replay scene, unless I am misunderstanding something. If you open the 'Assets/Ultimate Replay 2.0/Scripts/ReplayScene.cs' script to around line 552, you will see how Ultimate Replay is selecting replay objects from the 'allReplayObjects' list only if they are part of the active scene.
    A few more things to check:
    • Are you using the ReplayControls component to start and stop record and replay operations, or are you using the API?
    • Does the replay object exist in the active Unity scene (according to SceneManager) and is it enabled at the time when you start recording?
    • Is the replay object marked as 'DontDestroyOnLoad' at any point, because I believe Unity now treats such objects as belonging to a different scene.
     
  34. ScottySR

    ScottySR

    Joined:
    Sep 29, 2018
    Posts:
    48
    I managed to fix the previous problem.

    I noticed that instantiating prefabs during replay is giving the following error:
    ArgumentException: An item with the same key has already been added. Key: ReplayIdentity(52186)
    . The prefab instantiation seems to work just fine, but I'm not sure if this can cause other issues. Where in the code are they created? I want to try to add code that checks if the replay identity is in use and makes a new one to try to fix this.

    Another problem I started getting recently is
    AccessViolationException: The specified storage target is in use by another replay operation
    errors at
    ReplayManager.cs:776
    and
    ReplayManager.cs:424
     
  35. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, Do you have a stack trace for that first exception. That sounds like a bug and possibly multiple replay objects sharing the same replay identity. Instantiating and Destroying replay objects during the replay takes place in 'Assets/Ultimate Replay 2.0/Scripts/Storage/ReplaySnapshot.cs' in the method named 'RestoreReplayObjects', at roughly line 340.

    The second exception usually means that you are trying to start multiple replay operations (Recording or replaying) at the same time using the same storage target. Storage targets can only be in use by one operation at a time so make sure you call 'StopRecording' or 'StopPlayback' when you have finished. Also if you are passing 'null' for the storage target parameter (Or using the built in ReplayControls component) of 'BeginRecording' or 'BeginPlayback', then this will cause a default replay storage target to be used. You should not start multiple replay operations at the same time while passing 'null' as the storage target, but you should manually manage targets in that case by creating them manually and passing them in. Also in the case of file targets you must remember to call 'Dispose' to release the file handle too.
     
  36. ScottySR

    ScottySR

    Joined:
    Sep 29, 2018
    Posts:
    48
    Here is a stack trace:

    I couldn't replicate the second issue anymore. It seemed to happen ~20% the time a replay was supposed to start yesterday. I'll post more info on that if I run into it again.

    EDIT: I just ran into the issue again. Here is a stack trace for that error if it is needed:

    I'm using custom
    ReplayControls
    that is modified from the one that comes with the plugin.
    The replay is started with this code:

    Code (CSharp):
    1.     public void StartReplaySequence()
    2.     {
    3.         if(ReplayAllowed() && matchState != MatchState.Replaying)
    4.         {
    5.             SetMatchState(MatchState.Replaying);
    6.             Replay.StopRecording();
    7.             Replay.StartReplay();
    8.             uiGlobal.BeginOverlaySequence(UI_Global.OverlaySequenceType.IN);
    9.         }
    10.     }
    Here is the relevant parts from the
    ReplayControls
    :

    Code (CSharp):
    1.         public void StopRecording()
    2.         {
    3.             if (ReplayManager.IsRecording(recordHandle) == true)
    4.                 ReplayManager.StopRecording(ref recordHandle);
    5.         }
    6.  
    7.         public void StartReplay()
    8.         {
    9.             if (!IsReplaying())
    10.                 playbackHandle = ReplayManager.BeginPlayback(storageTarget, null, true);
    11.                 // ^ ReplayControls.cs:58 from the stack trace
    12.         }
    I don't think there is anything obvious in the code that could cause this issue. This started happening after I got the replay prefab instantiation working.
     
    Last edited: Apr 6, 2022
  37. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    The stack trace for the first issue seems to indicate that you could have registered the same prefab multiple times in the settings window. Could that be a possibility? It should just be a case of removing the duplicate in the settings window to solve the problem, but I will also add some extra error checking in the next update so that it will not throw an exception for duplicates.

    I am not sure about the seconds issue. Like I say, that error can only be raised if the storage target is being used multiple times. There is a 'ReplayStorageTarget.IsLocked' property that will let you know whether the storage target is being used by a replay operation. Are you sure that all replay handles are cleaned up correctly 'StopRecording/StopPlayback' before they are overwritten for instance, since they are value types? I guess so if the code is just modified from the ReplayControls script but I can't see what else it could be.
     
  38. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    When I Add Custom Recorder Components on Gameobject, it keep showing the following warning tips and won't dismiss:
    upload_2022-5-9_19-14-26.png

    And when I run the app, it will show the following error, how can I solve this?
    upload_2022-5-9_19-11-37.png

    PS: My Custom Recorder Components just record the simple string, which should not be the problem.
     

    Attached Files:

  39. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    Are you able to show the serialize and deserialize methods for your custom recorder component? From the error message it looks like your component is trying to read more data than it saved, or possibly a bug in UR if that is not the case.
    Does this error happen all the time? At runtime and in editor?
     
  40. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    1.The warning sometime occurs even when I Add/Remove the builtin Replay Component, I have to Reset the ReplayObject Component to Fix this:
    upload_2022-5-10_10-21-22.png

    2.Here‘s the code, it just record the gameobject's name, and I only run it on Editor:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UltimateReplay;
    4. using UltimateReplay.Core;
    5. using UltimateReplay.Serializers;
    6. using UnityEngine;
    7.  
    8. [ReplaySerializer(typeof(TestReplayNameSerializer))]
    9. [DisallowMultipleComponent]
    10. public class TestReplayName : ReplayRecordableBehaviour
    11. {
    12.     // Private
    13.     private TestReplayNameSerializer sharedSerializer = new TestReplayNameSerializer();
    14.  
    15.  
    16.     // Methods
    17.     /// <summary>
    18.     /// Called by the replay system when recorded data should be captured.
    19.     /// </summary>
    20.     /// <param name="state">The <see cref="ReplayState"/> used to store the recorded data</param>
    21.     public override void OnReplaySerialize(ReplayState state)
    22.     {
    23.         // Save
    24.         sharedSerializer.PlayerName = gameObject.name;
    25.  
    26.         // Run serializer
    27.         sharedSerializer.OnReplaySerialize(state);
    28.     }
    29.  
    30.     /// <summary>
    31.     ///  Called by the replay stystem when replay data should be restored.
    32.     /// </summary>
    33.     /// <param name="state">The <see cref="ReplayState"/> containig the previously recorded data</param>
    34.     public override void OnReplayDeserialize(ReplayState state)
    35.     {
    36.         // Run serializer
    37.         sharedSerializer.OnReplayDeserialize(state);
    38.         gameObject.name = sharedSerializer.PlayerName;
    39.     }
    40.  
    41. }
    42. public sealed class TestReplayNameSerializer : IReplaySerialize
    43. {
    44.     [ReplayTextSerialize("PlayerName")]
    45.     private string playerName = "";
    46.  
    47.     // Properties
    48.     /// <summary>
    49.     /// The enabled state of the object.
    50.     /// </summary>
    51.     public string PlayerName
    52.     {
    53.         get { return playerName; }
    54.         set { playerName = value; }
    55.     }
    56.  
    57.     public void OnReplayDeserialize(ReplayState state)
    58.     {
    59.         state.Write(playerName);
    60.     }
    61.  
    62.     public void OnReplaySerialize(ReplayState state)
    63.     {
    64.         playerName = state.ReadString();
    65.     }
    66. }
    3.By the way, I just found out if I duplicate multi Prefabs with ReplayObject, it will show the following warning everytime I click save, still the program work as charm:
    upload_2022-5-10_16-36-17.png
     
    Last edited: May 10, 2022
  41. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Thanks. Looks like the replay component is fine and should not cause any problems at all.
    If the warning is displayed every time you save the scene then that sounds like it could be the problem. The warning is fine once when some replay objects have been copied, but UR should detect and fix the duplicate id's only once.
    I will test it out on my end when I have chance to see if I can reproduce it.
     
  42. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    I was able to take another look at this and test some things out on my end. I created a custom replay component using the script you provided and tried setting up some different replay objects using that component in Unity. I could not manage to reproduce the issue in a stripped down test scene so I think there must be something else going on. I still suspect that the replay id warning is probably related to this issue, maybe with multiple replay objects having conflicting id's assigned which could create undefined behaviour. I think maybe resolving the warning every time you save the scene might fix some of the other issues you are seeing.
    With that in mind, are you able to try some small code changes on your end to see if the problem can be resolved? If so, here is the diff that will hopefully solve that save scene warning and potentially resolve the incorrect id's that are being reported:

    UR-ReplayIdConflict-Diff.png
     
    Threeyes likes this.
  43. Threeyes

    Threeyes

    Joined:
    Jun 19, 2014
    Posts:
    80
    Thanks! After I add EditorUtility.SetDirty(XXX):
    1. The "Warning showup every time you save the scene" problem solved.
    2. The custom replay component still have the warning tips. I tried it on Unity 2019.4.8f1 and 2021.3.0f1, and just add it to a empty GameObject:
    upload_2022-5-12_10-53-31.png
    So I located the warning code and Log the error in ReplayStorageStats line47:
    upload_2022-5-12_11-10-23.png
    And here's the output:

    Refreshing error: System.InvalidOperationException: There is no data in the object state
    at UltimateReplay.ReplayState.ReadByte () [0x0003b] in XXX\Ultimate Replay 2.0\Scripts\Storage\ReplayState.Read.cs:67
     
  44. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi again,
    So I thought it was strange that you were getting the warning in a seemingly very simple test project but I could not recreate it on my end. As a result I had another closer look at your replay component script and I believe I can now see the problem. It looks like you have your serialize and deserialize methods the wrong way around. You are trying to read data within 'OnReplaySerialize' and write it in 'OnReplayDeserialize'. If you swap the implementation around I think everything should start working properly again.
    When I tried to repro on my end I saw that the replay component was a very simple record a string setup, so recreated it quickly by hand without the serializer implementation for quickness. I guess I should have just copied your script and I might have seen that issue sooner.
    Let me know if you are still having issues.
     
    Threeyes likes this.
  45. rimunasubi

    rimunasubi

    Joined:
    Mar 16, 2020
    Posts:
    11
    Hi.

    When the OnDestroy method is called, I have written a process to stop recording if recording is in progress, and there are two types of cases: one is when the process is executed straightforwardly, and the other is when the following error occurs (I do not know the conditions).
    It happens after a few tries, do you know the cause?

    The recording target is a file.

    Code (CSharp):
    1. if (ReplayManager.IsRecording(recordHandle))
    2. {
    3.     ReplayManager.StopRecording(ref recordHandle); // <- An error occurs here.
    4.     Debug.Log("Stop Recording");
    5. }
    ObjectDisposedException: Cannot access a disposed object.
    Object name: 'File target has been disposed'.
    UltimateReplay.Storage.ReplayFileBinaryTarget.CheckDisposed () (at Assets/Ultimate Replay 2.0/Scripts/Storage/File/ReplayFileBinaryTarget.cs:111)
    UltimateReplay.Storage.ReplayFileBinaryTarget.get_InitialStateBuffer () (at Assets/Ultimate Replay 2.0/Scripts/Storage/File/ReplayFileBinaryTarget.cs:50)
    UltimateReplay.ReplayManager.StopRecording (UltimateReplay.ReplayHandle& handle) (at Assets/Ultimate Replay 2.0/Scripts/ReplayManager.cs:582)
    MotionDetectionCamera.StopRecording () (at Assets/MotionDetectionCamera.cs:106)
    MotionDetectionCamera.OnDestroy () (at Assets/MotionDetectionCamera.cs:38)

    We will send you a sample project if needed.

    Thank you for releasing these wonderful assets.
     
  46. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi, This is sort of a known issue and it is really more of a timing issue than anything else. In this case the ReplayManager instance object is getting destroyed before your script has chance to run the OnDestroy method, and in doing so it will cleanup any open file streams to prevent file locking issues in the OS. Then the call to stop playback will try to close the finalize the replay file but the file has already been closed.
    We are currently looking for a suitable way to solve this issue but for now I believe you should be able to solve the problem using the script execution settings and making sure that the ReplayManager script executes after other scripts.
     
  47. rimunasubi

    rimunasubi

    Joined:
    Mar 16, 2020
    Posts:
    11
    I thought the order in which the scripts were executed was fine, am I missing something?

    screenshot.png

    Changed the policy to delete the recording when it is interrupted by ReplayManager's OnDestroy, since it cannot be played back.
    No reply is necessary as this matter has been resolved.
    Thank you very much.
     
    Last edited: Jul 13, 2022
    scottyboy805 likes this.
  48. rimunasubi

    rimunasubi

    Joined:
    Mar 16, 2020
    Posts:
    11
    Sorry for the repetition.

    I recorded a prefab registered in the settings in scene A and played it back in an empty scene B.
    When I record the prefab in scene A and play it back in an empty scene B, the prefab is generated, but it is not played back correctly because the ReplayIdentity of the ReplayTransform is different.
    The Identity of the ReplayObject is the same as when it was recorded.

    Am I using it wrong?

    EDIT:

    After a few tries, you will get a mixture of what is correct and what is not for each recording file.
    The ones that play correctly have the ReplayIdentity set to the same as the one in the recording.
     
    Last edited: Jul 13, 2022
  49. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Sounds like a bug from what you describe and I will be interested in taking a look if that is the case. Do you have any repeatable steps to reproduce the issue so I can check it out on my end. Alternatively you can send a reduced Unity project that exhibits this issue if you are willing/able to so that I can replicate and debug the issue. Either way I will try out a few things when I have chance to see if I can replicate it but can't think of any obvious reason why that would be the case at the moment, since the replay identities should be assigned from the replay file when the prefab is instantiated. I will see what I can find though and let me know if you can share any steps or projects to help with this issue.
     
  50. rimunasubi

    rimunasubi

    Joined:
    Mar 16, 2020
    Posts:
    11
    I just sent you the project file by email.
    I hope you got it.
     
    scottyboy805 likes this.