it has been a while but the tutorials/topics covered here are always so high quality!
@tientam77929 күн бұрын
Well said!
@captainnoyauxАй бұрын
Braid (Anniversary edition is gorgeous) is an incredibly sophisticated rewind system (the game is based around that) one of the best system I ever saw
@neonmarblerustАй бұрын
Cool stuff. Aiming for replays can be a good way to ensure the game-play-system is well handled and cleanly implemented.
@Draxi_1Ай бұрын
I didn't really need to know how to make this kind of stuff but I enjoyed watching the video so much and it was so well put together I might add something like that to my game :D Thank you so much, amazing work.
@feyakutАй бұрын
What I instantly thought of was to save less frequently and fill in some of the frames by looking at the previous and next saved frames. This may look weird in some cases, but if you save frequently enough I think it can cut the save data size and the required processing power in half.
@evilbritishguy3581Ай бұрын
What about using Animation Curves i.e. each snapshot where data changes, a new key frame is created. Once a recording has completed, you can then optimise the animation curve to only contain the key frames you need to maintain the same animation curve so playback still works.
@AnEmortalKidАй бұрын
For the playback, you also have to disable/ignore user input right (just so a player can't tinker with it)? I guess maybe that's what you do when you press watch replay, the gameplaycontroller turns into 'replay mode' and a user can no longer control it.
@lounic8221Ай бұрын
Interresting choice, I would rather capture an initial state and record all inputs as event metrics as well as a used seed for randomization. Then recreate the initial state of captured scene and playback (simulate) all recorded input (events).
@gamesscowАй бұрын
to get the same behaviour every time the game engine physics would need to be deterministic though and I don't think Unities physics engine is
@libiroliАй бұрын
Daaaamn!! Super complicated and useful feature made accessible to us plebs. Appreciate it!! Just to review at a high level: 1) SnapshotInfo stores specific info of each snapshottable object 2) SnapshotData stores list of all SnapshotInfos 3) ReplayContainer stores all SnapshotDatas. But why did you make this an SO? Thank you again!!! Wishlisted CoC
@romancalderonАй бұрын
I'm thinking he went with an SO as the container as a way for the serialized data to be persisted between (editor) play sessions and so it can be viewable in the inspector. It's a good way to do it too since it's all built-in to the engine.
@GameDevGuideАй бұрын
Yep, exactly! As I mentioned in the voiceover it's basically just dealer's choice, I like it because I can see it independently in the project so it's useful for me for debugging (and for the video) How did you wishlist it? It doesn't have a steam page yet. Are you from the future?
@libiroliАй бұрын
@@GameDevGuide Thanks for the answer! Yeah I commented and then saw it has no Steam page. I will WL when it does. I've learned a lot from your videos over the years.
@Galaxy_WorldАй бұрын
insane
@AnEmortalKidАй бұрын
It's probably correct in your impl, but in the video i think LoadNextSnapshot was wrong, at least from the code you show here, it basically gets stuck in a loop at snapshot zero, since you have "m_hasNextSnasphot = replayContainer.GetSnapshot(snapshotIndex)" (the same index we just loaded), i think that should be snapshotIndex+1 (peek ahead 1 snapshot)
@k0cc425Ай бұрын
you could get extra performance by not using guids for object IDs, and instead only relying on ints,; his can be easily achieved by creating a singleton which issues these IDs - it's not the biggest optimization, but can rack up some frames when you record a large number of objects
@BlueJDevАй бұрын
I imagine this could be adjusted to add a "sands of time" function to the game for users to correct their mistakes?
@trecmthw27 күн бұрын
I've been looking for something like this for the longest time. I had a solution but the algorithm to find the snapshot was too slow.
@jankrajewski6170Ай бұрын
Giving that frame data for each object is a struct and mostly information are just prymitives, it realy asks for some parallelization using jobs and burst
@alexleonardkreaАй бұрын
Very cool!
@LoneLuminaryDevАй бұрын
gotchu man i think i was close tho
@expired___milkАй бұрын
why would you need to record velocity and angular velocity? Shouldn't position and rotation suffice?
@GameDevGuideАй бұрын
We want to make sure that the physics objects continue moving correctly between frames we've captured. If we just record the position and rotation alone, it could end up with the object behaving incorrectly.
@expired___milkАй бұрын
@ So the physics kind of act as interpolation to the incomplete set of snapshots?
@twinjukeАй бұрын
@@expired___milk yes, just like you would do for multiplayer games as well
@MeowzorsАй бұрын
I wonder how this would work for instantiated objects
@GameDevGuideАй бұрын
It's a little bit more work, but I'm actually using this for handling traffic that I instantiate at runtime. As long as you give your objects a unique id, you can use a manager to handle instantiating, and assigning the IDs in your saved replay to a fresh instance upon load.