REWIND TIME in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

If you're using a List<T> to store your time points you should add to the back of the list and then remove them from the end.

The way you're doing it every time you insert into the array (at position 0) requires shifting all other elements in the array up one index (requires traversing over the entire array and performing a per-item copy for each other item) and every time you remove from the array you pay the same performance penalty but in reverse (shifting down instead of up). Adding to and removing from the back of the list is a single operation.

But really you should look into using a deque data structure or anything else that supports efficient addition/removal from both ends of the list (to support both appending time points and discarding time points outside your recording window).

👍︎︎ 35 👤︎︎ u/AlternativeHistorian 📅︎︎ Jun 22 2017 🗫︎ replies

Just wanted to say that I thought this video was extremely well done. I had a project where I had to create this same system, and yours was definitely implemented much cleaner and easier to understand, which helped me think about my own! Really well explained and demonstrated, and it was succinct on top of that.

Very nice work! Hoping to see more of your stuff!

👍︎︎ 9 👤︎︎ u/phaseblue 📅︎︎ Jun 22 2017 🗫︎ replies

Cool tutorial for newbies, really clear and concise.

System.Collections.Generic has a class called Stack which is much more appropriate here.

You also might wanna consider using a struct instead of a class.

For more time control stuff, Chronos is a pretty decent asset store package.

👍︎︎ 5 👤︎︎ u/digitalsalmon 📅︎︎ Jun 22 2017 🗫︎ replies

I actually came up with a similar system some time ago when I was trying to visualize a concept that came to my mind after reading Steins;Gate. And then, as always, I gave up and never came back to this project.

Still, time manipulation is just a different level of amazing :D:D

Edit: Thanks for tuning in at Brackeys!

👍︎︎ 2 👤︎︎ u/MrReynevan2 📅︎︎ Jun 22 2017 🗫︎ replies

Nice simple explanation. Great job and thanks!👍

👍︎︎ 2 👤︎︎ u/daywalker2676 📅︎︎ Jun 22 2017 🗫︎ replies

Recommend Chronos for anyone who actually wants to use this in a game

👍︎︎ 2 👤︎︎ u/TWERK_WIZARD 📅︎︎ Jun 22 2017 🗫︎ replies

The real concern would be dealing with animations. I'm sure there's tutorials for a sports-like replay system.

👍︎︎ 1 👤︎︎ u/SayAllenthing 📅︎︎ Jun 22 2017 🗫︎ replies

With things like this is it more intensive on the game to record and store values each time step or instead store them at longer intervals and interpolate between the values when rewinding time?

Both of those operations are pretty quick on their own but I figure that constantly messing with a data structure is going to be slower than doing the interpolation math during a rewind only.

Is this assumption correct?

👍︎︎ 1 👤︎︎ u/gRntaus 📅︎︎ Jun 23 2017 🗫︎ replies

Was happy with myself, I had my first instance of thinking "wouldn't it be a good idea to make those pointsInTime variables a struct? I'm learning!

But I always think these sorts of tutorials should be taken as jumping off points. Things won't always be done efficiently or in the "best practices" way, but the point is more to get us noobies understanding the process and piecing together the tools available to get a result we can build off of.

The discussion about the lists has probably led me to learn more about the available options than if he simply used a Stack in the first place.

👍︎︎ 1 👤︎︎ u/dslybrowse 📅︎︎ Jun 23 2017 🗫︎ replies
Captions
this video will have a look at reversing time mister of you because of a hell way to find we're done it's going to look something like this let's get into it so here we have a simple scene with the first person character and a bunch of red cubes stacked on top of each other each one of these cubes has a box Collider and a rigidbody so if we go ahead and hit play we can run around the scene and we can click to create explosions I'll have a download link for the project in the description so in order to create the effect that time is rewinding let's go ahead and add a script to each one of our cubes to do that I'll go under prefabs and find the red box prefab you'll add a new component let's call it time body you're going to choose C sharp and a crane ad let's now double click this to open it up in Visual Studio and the first thing that we want is a way to keep track of whether or not we want to rewind time to do that let's use some keyboard input let's first off create a variable at the top let's make this public so it shows up in the inspector let's make it of type bold and it's called it is rewinding by default it's going to be false then inside of our update method let's go ahead and make an if statement that checks if we are pressing a rewind button so we go input dot get key down and you can use any key here the key that I'll be using is the return key otherwise known as enter so to get that key we write key code return so when we first press the key we want to set is rewinding equal to true but we also want to modify some settings on our rigidbody so let's go ahead and wrap this in a function called start rewind then we also want to check when we release the key so we write if input don't get key up and again checking for key code dot return so when we stop pressing the key we want to stop rewind now let's create these two methods that's first off create void start rewind and in here we want to set its rewinding equal to true and in our other method which is going to be called stop rewind we'll set its rewinding equal to false if you want you can go ahead and make these two methods public this way we can access them from other scripts and this is going to allow us to rewind each individual object through another script we could for example create a line gun that would rewind the time for any object hit with it we would simply go ahead and make these two public it's probably also a good idea to go and make this variable private but for now we want to see it in the inspector so now when we save this and hit into unity we should see that each and every one of our cubes has the time body script and that when we play and hold down enter it's going to be marked as true and when we then again release it shifts back to false now in order to actually rewind the position and rotation of an object we first have to keep track of it in other words we have to record some information to do that we'll use a list remember that whenever we use lists we have to make sure that the system that collections that generic namespace is included at the top so let's begin simple let's keep track of only our objects position to do that we create a list that is going to store vector threes for positional data and we can go ahead and call it positions at the start of our game will then set positions equal to a new list of vector threes so by default there is nothing in our list while we're not rewinding we want to add new elements to it this list is going to store the object's position over time meaning that each element in the list is going to be the position at a given point in time we refer to these points in time as frames but instead of updating it every single frame we can instead updated every physics iteration that means that instead of adding new elements inside of update we'll add it inside of fixed update this is better because fixed update most often will run slower than update and also on a fixed timer so we won't get any issues with playback speed let's go in here and write void fixed update in here we want to check if we are currently rewinding if we are we want to go ahead and do the logic related to rewinding and so we can call some kind of method called say rewind and if we're not we want to record some information so let's go ahead and make another method for that called record will create a rewrite method in a second let's create a method called record and in here we want to go ahead and add new elements to our list to do that we go positions dot add now this adds an element to the end of the list that means that in the beginning of our list we'll have the oldest positions at the end we'll have the newest ones you can definitely do it this way but I like doing it the opposite way we're the newest positions are those at index zero because I'd like to think of it kind of like stacking positions on top of each other where the newest place item is always going to be at the top and so instead of using add to add it to the end of the list let's use insert and the index that we want to insert at is zero which means at the very start the item that we want to insert it's our composition which is of course transform dot position so now each fistic iteration we are calling the record method and our record method make sure to insert a log of our position at the current time so now we're ready to create the rewind method all we need to do each physically duration is read the next element in the list let's go ahead and create that method here we want to set our current position meaning transform drop position equal to the first element in our list which is our positions list of index 0 and then after getting that position we want to remove that element and so we'll go positions dot remove add and we want to remove at index 0 so if we now save this and hit enter unity you should get no errors and when we now play shoot and then hold down return we see all of our objects returning to their previous positions however there are few problems the first one is of course we're not keeping track of the object's rotation and so will things look a bit weird the second one is that while we're rewinding unity still trying to apply physics on top and so it's probably better that we set our rigidbody as kinematic while rewinding and the final thing is that when we reach the end of our list we get an argument out of range exception because we've gone through all of our positional data let's start by fixing the error what we need to do here is simply add an if statement if and we want to check if there are more elements in our list so we'll check if positions dot count is greater than zero if it is well then we can go ahead and continue rewinding however if it is not well then we want to stop rewinding immediately that should get rid of that error force so let's just try hitting play shooting and winding back time and we should see no more errors let's also make sure to set a rigid body as kinematic while rewinding to do that we need a red two rigid bodies so let's go ahead and create a rigid body call it OB and inside of our start method we'll set our be equal to get component of type rigid body of course if your object doesn't have a rigid body you can simply skip this step we can then go to where we start and stop rewinding when we start we want to set our P that is kinematic equal to true and when we stop we want to set our be that is kinematic to false now if we watch our rigid body to the right here we can see that when I hold down enter it is true and when I let go it's false finally we can start keeping track of rotation as well to do that we could go in here and add another list fall of our rotations however I think a better way is have one list store objects that keep track of both position and rotation let's go ahead and create such a class to do that we're going to unity we right click in the project panel hit create c-sharp script and now this class is going to store it to values our position and our rotation let's call it point in time now let's double click on point in time and let's modify this a bit first of all we don't need to be using any of the system stuff we don't need this to derive from monobehaviour and we don't need any methods instead what we need is a public vector three storing our position and a public quaternion storing our rotation we then create a constructor for this class that makes it easier to set these values when they gave public point in time this is going to take in a victor three let's write underscore position so that we can distinguish this from the position up here and a rotation let's write Kryptonian underscore rotation now in this constructor that set position equal to underscore position and rotation equal to underscore rotation now when we save this and go into our time body script instead of storing a list of vector threes let's store a list of points in time of course make sure to change the type down here as well and let's rename the variables from positions to points in time by the way to do quick refractory in visual studio I hold down control and press R twice it's a pretty handy shortcut now if we scroll down to a rewind mess we can set up position equal to this point in time directly so let's instead get our first point in time and store it in a temporary variable the variable is of course going to be of type point in time and it's call it point in time with a non capital P it's going to be equal to the first element in our list then we can set our position equal to that point in time dub position and our rotation equal to that point in time dot notation we have the same issue when recording we can't record our position directly instead we have to go in here and create a new point in time and we want to feed it first our position transform dot position and then our rotation transform dot rotation and by the way this is also why we created a constructor the constructor allows us to simply insert our position and our rotation was creating the object otherwise we would have to create it in a temporary variable and then change each value one by one so now if we save this and head into unity we should see that our objects will keep track of both position and rotation and so our rewind starts to look really smooth awesome of course you want to be careful that we don't try and keep track of too many point in time currently I have about 50 cubes in my scene and each of them now have a list where every single physics iteration which normally sits around fifty times a second a new point in time gets recorded that means in one second will already have recorded about 2500 values let's in one second and so you can imagine that if you leave this for say a minute this value quickly becomes ridiculous so what we probably want to do is put a limit on how far back in time we can go now most games have this as a gameplay thing you can't win back time more than five seconds but you can see now that there's also a very practical reason why so let's now go into visual studio and try and add this and the best way we can do this is by keeping track of how many values are currently in a point in time list so inside of our record method we can check if points in time dot count is greater than some value now normally fixedupdate will run fifty times a second and so if we insert 50 here we check if more than one second has gone by and so if you want to check for five seconds we'll insert two on and fifty but of course your fixedupdate might run on a different timer and sometimes we even have to adjust this during a game so what one stud do is going here and make a quick calculation first we can use time dot fix Delta time to get the time between each fixed object call and so one divided by that it's going to be the amount of time so fixed update runs a second so normally this is going to say 1 divided by 0.02 which is going to equal 50 of course we can now multiply this number if you want to record for more than one second we could for example simply multiply this with five so now if this value here is 50 this is going to multiply with five and so this side is going to say 250 now some of you might notice that this can be written either by simply multiplying this number into this number and so we can actually simply write 5 divided by fixed at a time however this is currently a floating point number and so we need to convert this into an integer because the number of points in time we have is an integer value and so let's write mass dot round this is going to round the float that we insert to the nearest integer we want to insert the result of our calculation so if you got confused along the way here's what we're doing we're checking if you have more points in time that we would get during 5 seconds and if we do well then more than 5 seconds have elapsed that means that we need to start over writing and so inside these brackets would then start removing from our list so that's called points in time dot remove add and the index that we want to remove at is the bottom of a list because remember our oldest entries are at the bottom and so to remove from the bottom of a list will go point in time count minus 1 so now during the first 5 seconds of our record will simply add new elements to a point in time and when we get past 2 5 seconds we'll start removing from the bottom of our list and adding to the top so when we now save this and head into unity and hit play we can play around with these red cubes for about five seconds and when we then start rewinding we should see that after 5 seconds of rewind stops because our system has no information about what happened before of course you can tweak this value in any way you want I'm just going to make it into a variable at the top so you can do that easily let's make it a public float called record time and then fold it to five seconds it's then put record time down here and finally at the top that's also turn or rewinding into a private variable so we can't edit it through the inspector from here I just encourage you to have fun with the rewind system there's lots of stuff you can do with this lets pretty much it for this video if you enjoyed it make sure to subscribe to the Dome it's a future one also if you're interested in more time related stuff check out my video on creating a bullet time effect on that thanks for watching and I will see you in the next video thanks to of the awesome patreon supporters who donated in May and a special thanks to Derek huge jerk face of Mara Phi stoned gamer gmvi feinstone 38 Thomas Roy Lee James Calhoun cyborg Romney and Jason the teeter if you want to become a picture in yourself you can do so at patreon.com slash brekkie
Info
Channel: Brackeys
Views: 288,134
Rating: undefined out of 5
Keywords: brackeys, unity, unity3d, asset, assets, model, models, beginner, easy, how, to, howto, learn, course, series, tutorial, tutorials, fix, tip, game, development, develop, games, programming, coding, basic, basics, C#, reverse, rewind, winding, back, time, reversing, rewinding, control, manager, manage
Id: eqlHpPzS22U
Channel Id: undefined
Length: 14min 15sec (855 seconds)
Published: Wed Jun 21 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.