Alright, so at this point, I haven't actually started making the rewind system, but I have done a lot of thinking.
My vision for a really finished project would be to have:
- A character that can move left, right and jump and has at least left and right animations.
- A simple enemy that moves left and right with animations. (possibly player can die/kill)
- A platform that has a more complex path than just left and right, but has no animations.
- A key that the player can get that isn't affected by rewind, which opens a door that also is not affected by rewind.
So the rewind would affect the position and animations mostly, but if I find that I have some extra time, reversing the player and enemy deaths would be cool also. I would also like to have the sound effects that can be played backwards, but we will see how good I do with position and animations first.
Since I am here just to test my programming, I decided to take my art from RPG Maker, because they have simple animation sheets for characters and such. Here are some pictures that I will probably use in my system:
When I decided to go with the rewind system, I thought it would be impossible for me - it seemed like magic. But after a bit of Googling and talking with some other students, it has moved from impossible to just really hard.
A lot of the solutions I found on the internet were just keeping a big collection of the character's previous positions. That sounds easy, but if I were to have many moving platforms and enemies on the screen, these collections would add up very quickly. I don't know exactly how long Braid can rewind, but I would like to be able to rewind as much as possible, so keeping these collection sizes down will be the key.
Just today, when I was thinking about this, I came up with some ideas on not only how to keep the sizes down, but also how to possibly get rid of some of the collections. I thought I would need to keep arrays/lists of each object's position and animation frames. But, since the enemies and moving platforms are not going to have any crazy AI or randomness to them, I could just tell them to do what they are doing, but backwards when time is rewinding. It will probably take some more programming, and I may even have to do something unique for each object, but it seems to be a much more efficient way to do it.
I also think that for the player, I may only need to have an array/list for the positions, and not animations or anything else. I was thinking of many different ways to save where the player was: the player input, the forces acting on the object at that point, but I think positions will work just fine. As for getting the animations to play backwards, I am thinking of taking a look at the current and previous rewinding positions to see which direction the player was moving at that point, and then play the right animation according to that. My movement probably won't be very complex, so I should be able to put something along those lines together. It works well in my head, but I will have to try putting it into action before I will know how well it works. If it does work, then that will be one less thing to keep track of (making more room for saving the player position), because I will be replicating the animations instead of pulling them from a saved off collection.
If I do have time to mess with player and enemy death, I think I have a way to do it. When you kill the enemy (probably jump on its head), instead of deleting it, just disable its renderer, collider, and scripts. I figured this would be much easier than trying to remake a deleted object. When the player dies, it can just stop player movement until you rewind. Actually, it seemed a lot easier before I wrote that last sentence, because that would require a different state for the player, which may also need to be saved somewhere. I may be able to just have everything pause while you are dead, and if you rewind, you will no longer be colliding with the enemy, which means you are alive. Hmm… I will cross that bridge if I get there.
Alright, I think I have enough info at this point to start my project. I feel that rewinding time is a lot more possible than it was when I just started. Before I get started, though, I will need to get the boring stuff out of the way: making a simple platformer in Unity before I try to add the rewind system.
I'll see you again when I try putting this stuff together. I am foreseeing a lot of small things that I haven't thought of that are going to cause a lot of problems for me (it seems to always work that way).
(To see/play/download the project of final product, go to my website: http://derek.dittmer.com/please-be-kind.html)