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. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    Sounds good, thanks a lot! Amazing work, very likely that we are going to buy the paid version!
     
    scottyboy805 likes this.
  2. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    263
    Hey I just dug out an old prototype that used Ultimate Replay 1. I bought UR2 and want to go forward with it.

    Do you have any info on upgrade paths? I have no expectations, just wondering what I should do.
     
  3. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I recorded the test scene "CubeTest" and saved it locally. When I played back, the Cube created was at the position of 0,0,0, and would not change over time.This has nothing to do with the Animator.
     
  4. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I found the problem by looking at the source code. The BehaviourIdentity of the object created during playback was different from the one recorded, which resulted in a replay failure.Hope to repair it soon,
     
  5. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I found that not all parameters in Particle System playback were recorded. In my project, Start Lifetime, Emission(Rate over Time) and Shape(Position,Rotation,Scale) should be adjusted during the recording process. However, these parameters will not change in the playback, so I hope to add them in the playback,
     
  6. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    And the Collision parameter for Particle System.
     
  7. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    As an existing customer of the original asset, you will be entitled to a heavily reduced upgrade price for the new asset. If you go to the Ultimate Replay 2.0 asset page and login, you should see the applied discount price.
     
    Last edited: Oct 22, 2020
  8. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    This issue was fixed in update 1.0.3 (released a few days ago) so I would suggest that you try to update the asset as that should fix the issue. If you are still having trouble then let me know.

    Note that you will need to re-record the replay file with the new and now static replay identities assigned to scene objects.

    Particle system parameters are not recorded at the moment. The replay system will use the assigned particle system as is for playback and will not touch the properties at all. Support for replaying such properties could be added quite easily though although i am not sure how many properties we would want to support as there are alot. Obviously the more parameters that are recorded, the more storage space required which can quickly add up over frames.
     
  9. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I've updated it and remounted ReplayTransform, but it's not as recorded
     
  10. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I find the ReplayObject tracking code in the class DeserializeReplayComponents () method
      ReplayRecordableBehaviour behaviour = GetReplayBehaviour(componentData.BehaviourIdentity) as ReplayRecordableBehaviour;
    The behaviour returned here is empty.You can record the demo "CubeText" and save it locally, and then replay it in the new scene. The BehaviourIdentity of the created object is different from that of the recorded one.In version 1.0.3, I looked at the source code and found that only the ReplayIdentity for ReplayObject was assigned, whereas the ReplayIdentity for ReplayBehaviour was not assigned.
     
  11. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Are the ReplayObject or ReplayTransform identities changing when entering play mode? Have you also tried re-attaching the ReplayObject component? Are you able to send us a repro project to info(at)trivialinteractive.co.uk so we can debug the issue?
     
  12. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    The ReplayIdentity of ReplayObject does not change, but the ReplayIdentity of ReplayBehaviour does
     
  13. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    We have tested with some replay objects created before the 1.0.3 update and the replay identity does indeed change when entering play mode. The solution is to remove and re-add all replay components as this will refresh any stored data. It is best to remove all replay components from an offending object at once and then re-add via the 'Make Selection Replayable' menu.
     
  14. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    After Removing the ReplayObject and ReplayBehaviour, I added it again to UltimateReplaySettings and re-recorded and played back, but the result is the same
     
  15. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Ok, it sounds like something else is going on then as removing and re-adding replay components fixes the problem for us on objects created before the update. Can you send us a repro project to info(at)trivialinteractive.co.uk and we can look into it further.
     
  16. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    Hi scottyboy805, we are using the leap motion for the finger-tracking (rigged hands) and would like to record the entire hands so that we can replay it at a later stage. Unfortunately, I cannot record the hand. I tried to attach Replay Transform and Replay Object to all bones but that seems to not work. Any suggestions? Thanks a lot!
     
  17. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    In what way does the replay not work as expected? Does anything happen at all or do the bones not appear to move? You say that you added a ReplayTransform component and a ReplayObject to each bone? That is not the ideal setup and can cause issues. Ideally you would have a single ReplayObject component attached to the highest level game object in the hierarchy that you intend to record. In the case of animated characters, this is usually the very root object where the Animator component is atached but may be different for you ij you are just recording fingers. You can then add a ReplayTransform component to each finger bone with the position and rotation record space set to 'Local'. If you then go back to the ReplayObject component, you should see that all ReplayTransform components for the bones have been registered under the 'Observed Components' collection. That should result in a fully replayable setup using the Animator, IK or physics based movements.

    The easiest way to setup would to select the root object and go to 'Tools -> Ultimate Replay 2.0 -> Make Selection Replayable -> ReplayObject'. Then for each bone go to 'Tools -> Ultimate Replay 2.0 -> Make Selection Replayable -> ReplayTransform'. Note that the parent ReplayObject component will be detected and will mean that a ReplayObject component is not attached to the bone object.
     
  18. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    Hi, the hand is not visible in the replay file but I'm going to try it again and report back what happened!

    Update: Lovely @scottybod - that works brilliant! I just realised that my gameobject was disabled during the playback because of the leap. Amazing support!
     
    Last edited: Oct 22, 2020
    scottyboy805 likes this.
  19. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    No problem. Glad to hear it is working for you.
    Let me know if there is anything else.
     
    flomaaa likes this.
  20. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    263
    Hey yeah I wasn't meaning about price. I was pleased to see the discount on 2.0... thanks!

    What I meant was what is the upgrade path, if any, to replacing the code from 1.0 with 2.0. I'm guessing that there is nothing automatic and I'll need to re-wire up everything. That's okay if so, I just want to avoid any needless work. Cheers.
     
  21. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Ahh I see.
    There is no auto upgrade feature mainly because so much changed between versions. It should not take long to update replay objects in your scenes as it is now a single operation (Tools -> Ultimate Replay 2.0 -> Make Selection Replayable -> <Replay Component of choice>). Recording and replaying is now a completely different implementation but the user guide will help you with that.

    Let me know if there is anything else.
     
  22. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    263
    Oh wow the docs are good. Sorry I should've looked at them first. Good stuff, thanks.
     
    scottyboy805 likes this.
  23. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    No problem. Glad you like the user guide. A lot of time went into it :)
     
  24. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    263
    So, I'm having pretty good luck with the upgrade. One gotcha so far is that using the ReplayControls script, when I reload the same scene (which I do to restart my prototype), I get some exceptions from the Replay system.

    What should I do to prevent these? How would I clear the target manually before reloading scene?



    InvalidOperationException: The memory storage target already has data stored. You must clear the data to begin new writing operations
    UltimateReplay.Storage.ReplayMemoryTarget.PrepareTarget (UltimateReplay.Storage.ReplayTargetTask mode) (at Assets/Ultimate Replay 2.0/Scripts/Storage/Memory/ReplayMemoryTarget.cs:334)
    UltimateReplay.ReplayManager.BeginRecording (UltimateReplay.Storage.ReplayStorageTarget recordTarget, UltimateReplay.ReplayScene recordScene, System.Boolean cleanRecording, System.Boolean allowEmptyScene, UltimateReplay.ReplayRecordOptions recordOptions) (at Assets/Ultimate Replay 2.0/Scripts/ReplayManager.cs:378)
    UltimateReplay.ReplayControls.Start () (at Assets/Ultimate Replay 2.0/Scripts/ReplayControls.cs:115)

    AccessViolationException: The specified replay storage target is in use by another replay operation
    UltimateReplay.ReplayManager.BeginPlayback (UltimateReplay.Storage.ReplayStorageTarget replaySource, UltimateReplay.ReplayScene playbackScene, UltimateReplay.ReplayPlaybackOptions playbackOptions, System.Boolean allowEmptyScene, System.Boolean fixedFrame) (at Assets/Ultimate Replay 2.0/Scripts/ReplayManager.cs:678)
    UltimateReplay.ReplayManager.BeginPlayback (UltimateReplay.Storage.ReplayStorageTarget replaySource, UltimateReplay.ReplayScene playbackScene, System.Boolean allowEmptyScene, UltimateReplay.ReplayPlaybackOptions playbackOptions) (at Assets/Ultimate Replay 2.0/Scripts/ReplayManager.cs:644)
    UltimateReplay.ReplayControls.OnGUI () (at Assets/Ultimate Replay 2.0/Scripts/ReplayControls.cs:225)
     
  25. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    263
    Yeah even in a very simple use case I'm running into a lot of conflicts between storage targets. This should probably manage itself a bit better in the default case. Like, why would I ever not want to Stop/Clear/Restart a target by default? I think that if you made that the normal case a lot of these newbie issues would disappear.

    It's a very cool system, don't get me wrong. But this has been a confusion point as I've spun it up.
     
  26. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I tried to send an email, but it failed and was rejected, so I recorded a video of the operation, and because the video was large, I split it into four and uploaded it, plus I uploaded another project
     

    Attached Files:

    • 1.rar
      File size:
      4.4 MB
      Views:
      311
    • 2.rar
      File size:
      3 MB
      Views:
      312
    • 3.rar
      File size:
      7.7 MB
      Views:
      312
    • 4.rar
      File size:
      6.9 MB
      Views:
      311
    • Test.rar
      File size:
      7.4 MB
      Views:
      316
  27. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I found that when I played it back, the particles I created didn't play, and it didn't work if I manually clicked play
     
  28. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I found in the playback create object code, restore data observedComponentIdentities is empty, thus lead to not give ReplayIdentity value of the behaviour
     
  29. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I noticed that in the ReplayInitialDataBuffer class, a line in the deserialize method OnReplayDeserialize called OnReplayDeserialize in the ReplayIdentity class, but it was all commented out. I don't know if this is the cause
     
  30. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi again,
    Thanks for reporting this issue. It looks like some sanity checks were missing allowing you to do things with the replay controls buttons that are not allowed. The problems have now been fixed and will be included in update 1.0.4
     
    Last edited: Oct 23, 2020
  31. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    Hi scottyboy805, it's me again. Everything works fine on my side except one thing that I couldn't figure out how to do. I have some material changes and some new elements during runtime that the recorder (through Replay Transform) doesn't catch. It indeed tracks the end state of the new elements, but not the transition. For example, let's say I have an element A that is black. After touching element A with the controller I apply some red material to it and a second element (element B) appears. Is there a way to also record such situations? I am only able to capture the last state of the new elements. Note that I am creating this new elements through code (e.g., Line Renderer, changing the material of gameObjects etc) and I'm still using V1.0. Thanks again!
     
    Last edited: Oct 23, 2020
  32. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Thanks for the video and the repro project. They were very useful and we were able to reproduce the problem after trying a few things. There was a proplem with replay identities changing in some cases when using prefab instances which may have been causing an issue and there was also a problem with the ReplayInitialStateBuffer as you suspected. These issues will fix fixed in an update which is hopefully coming by the end of the day.

    The observed components collection should be automatically updated when changes are made. If you still have this issue, I would ask that you try the update when it becomes available and if the issue persists, I will look into it further.

    Thanks again for reporting these issues.
     
  33. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi again,
    So it sounds like you want to record material changes of a renderer and also new items that you spawn in? What exactly do you mean by the "recorder doesn't catch" part refering to the ReplayTransform? Do you mean that you spawn in a new element while recording but it does not get recorded or am I completley misunderstanding?

    We actually have a material recorder component half finished which we will be adding in an update. This component works by having a collection of materials that you can assign. This collection should contain any materials that could be assigned to the renderer. The component will then monitor the active material and save an index value when OnReplaySerialize is called which represents the material index. Perhaps you could use a similar approach as it seems to work just fine for us, although we are still testing it.
     
  34. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Ultimate Replay 2.0.4 has been submitted to the asset store and should be available in the next few days. This version includes a number of bug ifxes and optimizations:
    • Changed version numbering to 2.x.x to avoid confusion between the legacy asset.
    • Fixed a bug where prefab instances could sometimes have different replay identities when entering play mode.
    • Optimizations to core systems and serialization to reduce the processing requirements of replay components. (1000 replay cubes tested at a solid 70fps for both recording and playback on mid-high end hardware).
    • Optimizations to reduce non-essential allocations for improved performance.
    • Fixed a bug in the ReplayFileTarget where initial state information for dynamically spawned objects was not serialized correctly causing incorrect playback in different sessions.
    • Fixed a bug in the ReplayAudio component where the start of some sounds could be cut off causing audible glitches.
    • Fixed a bug in the ReplayAudio component where playback could attempt to play a sound with an invalid seek index causing a Unity exception.
    • Fixed a bug in the ReplayControls script where it is possible to generate exceptions when switching between playback and record modes.
    • Fixed a bug in the ReplayAnimator component where the observed animator could be disabled by the state perparation system meaning that animations could also not be replayed.
    • Fixed a bug in the ReplayAnimator component where exceptions could be throw when serializing parameters.
     
  35. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    Hi scotty,

    Yes, more or less. I have some dynamic elements in my scene such as material changes or new GameObjects that I create during runtime. Unfortunately, what I see in the replay is the final state but it does not show me all the steps.

    I attached an example to make this more tangible. The blue lines show the overall path of the finger (LineRenderer). So what I use here are new materials that I assign to the GameObjects and I also add a LineRenderer GameObject during runtime and set the positions of the vertices. I think the material recorder would solve the material problem (i.e., the blue material for the spheres), but I am not entirely sure about the 2nd part: the generation and modification (beyond material) of new GameObjects during runtime. Should this already work? For example, having a counter that counts +1 every time something collides. This could be done through TextMeshPro and the setText method. But right now I do not think that UltimateReplay 2.0 is capable of recording such changes? After the recording, I can only see the last state (e.g., "4" after 4 collisions, but I do not see the entire sequence (1,2,3,4)). Do you have a rough idea when these two features (material, new objects) are available or how difficult it would be to set this up on my own? Is a quick fix to add Replaytransform to the newly created GameObjects through an additional line of code that adds the script to the corresponding GameObject? I am not sure whether or not it would require major changes, but that could probably work? Happy to contribute to the material one and test it even though it's not entirely ready yet - this project is really great and helpful in many ways!

     
    Last edited: Oct 23, 2020
  36. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Thanks for the info.
    The ReplayMaterial component will likley be coming in the next update so not too far away.
    Creating new game objects during recording is indeed supported as demonstrated in the simple cubes demo. Each cube is created using Instantiate and Ultimate Replay tracks the movement and creation of these cubes during playback. In order for this to work, there are a couple of extra things that need to be done as detailed in the user guide. The first or which is to setup your prefab with replay components, and then register the object as a 'Replay Prefab' via the Ultimate Replay 2.0 settings. Once you have done that, you can then call 'Instantiate' for that prefab while recording to create an instance. The final step after creating your instance is to add the resulting object to the associated replay scene. There is a convenience method called 'ReplayManager.AddReplayObjectToRecordScenes' for this or alternativley if you have a replay scene reference, you can use: 'someReplayScene.AddReplayObject(...)'.

    For your example of incrementing a text counter, you would need to record that value manually. You can either create a custom ReplayRecordableBehaviour for this and then implement 'OnReplaySerialize' and 'OnReplayDeserialize', or you could create a script deriving from 'ReplayBehaviour' and make use of the replay variables feature using the 'ReplayVar' attribute. More info about this feature can be found in the user guide.

    I hope that helps you. Let me know if something is not working as expected or if ou have any more questions.
     
  37. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    Thanks Scotty! Going to buy the 2.0 version on Monday and then start implementing this!
     
    scottyboy805 likes this.
  38. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    No problem. let me know if there is anything else.
     
    flomaaa likes this.
  39. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    thanks scotty, I've just bought 2.0 and tried to move my existing project to the new Ultimate Replay version. I followed the same steps as in 1.0 but can't get the fingers recorded (movement of the fingers doesn't get tracked at all, I can only see the static hand). Can you please have a look at the attached image to see whether I did something wrong? I am quite sure that it worked like this the last time. Replay Transform are set to position/rotation [x,y,z], local, lerp.
     
  40. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi again,
    That setup all sounds fine to me.
    You don't have a ReplayAnimator component attached do you? Is the Animator component enabled when in playback mode as this could be overriding the replay positioning?
     
  41. sherzhen

    sherzhen

    Joined:
    Jun 28, 2015
    Posts:
    13
    Hello! First, I'd like to thank you for this super useful asset.
    I ran into one small problem (maybe it's just that I didn't understand something). If you record a method call without arguments (ex. RecordMethodCall(DoSomething)), then during the playback of the recording, "Object reference not set to an instance of an object" appears in DeserializeMethodArguments (), because it tries to pull arguments from a method that does not have them. upload_2020-10-25_0-12-4.png
     
  42. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    No, there is no ReplayAnimator attached and the animator component is disabled when in playback mode.
     
  43. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    OK, thanks for checking.
    In that case, it should record and replay as expected so somethijng else must be going on. If you select the gameobject with the ReplayObject component attached, does the ReplayIdentity change when entering play mode? Is is possible that any other scripts (perhaps attached to different game obejcts) could be modifying the bones during playback? Would it be possible to send a repro project to info(at)trivialinteractive.co.uk and we will be happy to take a look at what the problem might be.
     
  44. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    Thanks for reporting this issue.
    The stack trace you posted can only mean that the MethodInfo for the target method was not found, although that should not cause an exception. Does the method have a 'ReplayMethod' attribute? Does your defining class inherit from 'ReplayBehaviour'? Do you get any warnings relating to the replay method when recording? We ran a few tests and parameterless method recording seems to work well for us. This is one of the scripts we tested:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. namespace UltimateReplay.Example
    5. {
    6.     /// <summary>
    7.     /// An example script that shows how a meshod call can be recorded and replayed similar to a networked RPC call.
    8.     /// </summary>
    9.     public class Ex_RecordMethodExample : ReplayBehaviour
    10.     {
    11.         // Methods
    12.         public IEnumerator Start()
    13.         {
    14.             while(true)
    15.             {
    16.                 yield return new WaitForSeconds(1f);
    17.  
    18.                 // Only record methods when this object is recording
    19.                 if (IsRecording == true)
    20.                 {
    21.                     // This will cause the method to be called immediatley and also at the corrosponding time during playback
    22.                     RecordMethodCall(MyExampleMethod);
    23.                 }
    24.             }
    25.         }
    26.  
    27.         [ReplayMethod]
    28.         public void MyExampleMethod()
    29.         {
    30.             Debug.Log("Replay Method");
    31.         }
    32.     }
    33. }
    34.  
    Would you be able to try the script in your project to see if it works as expected? Just save the script in your project and setup a new scene with the script above and the replay controls script 'Tools -> Ultimate Spawner 2.0 -> Replay Controils'. For us, the method is called as expected ruing recording and during playback with a message logged to the console.
     
  45. flomaaa

    flomaaa

    Joined:
    Apr 12, 2019
    Posts:
    24
    Thanks scotty. The ReplayIdentity does not change when entering play mode. There is a chance that the animator (leap motion etc) modifies the objects again, but that did not happen in the trial version of 1.0. The only difference to my current version is that I do not store/replay the recordings - maybe this causes the problem. I sent you an email and uploaded the zipped project to a shared folder. Thanks for taking a look!
     
  46. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Ok, thanks for checking that for me and for sending a repro project. I will take a look first thing in the morning when we are back in the office and get back to you.
     
    Last edited: Oct 25, 2020
    flomaaa likes this.
  47. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I want to know when the new version can be updated, because my project needs to be used and it is urgent.thank you!
     
  48. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    Hi,
    Update 2.0.4 is still pending approval by the asset store team. If you need the update urgently then feel free to contact us by email (info(at)trivialinteractive.co.uk) with your invoice number and we can send you the update direct.
     
  49. MyCatEatNoFish

    MyCatEatNoFish

    Joined:
    Oct 20, 2020
    Posts:
    19
    I updated version 2.0.4 and tested it. I think it can meet my project for the time being. Thank you!
     
    scottyboy805 likes this.
  50. scottyboy805

    scottyboy805

    Joined:
    Apr 10, 2013
    Posts:
    1,193
    No problem. Let me know if you have any more issues.