void LateUpdate() { if (_mode == InputVCRMode.Playback) { // update last frame and this frame // this way, all changes are transmitted, even if a button press lasts less than a frame (like in Input) lastFrameInputs = thisFrameInputs; int lastFrame = currentFrame; currentFrame = currentRecording.GetClosestFrame(playbackTime); if (currentFrame > currentRecording.totalFrames) { // end of recording if (finishedPlayback != null) { finishedPlayback( ); } Stop(); } else { // go through all changes in recorded input since last frame var changedInputs = new Dictionary <string, Recording.InputInfo>(); for (int frame = lastFrame + 1; frame <= currentFrame; frame++) { foreach (var input in currentRecording.GetInputs(frame)) { // thisFrameInputs only updated once per game frame, so all changes, no matter how brief, will be marked // if button has changed if (!thisFrameInputs.ContainsKey(input.inputName) || !thisFrameInputs[input.inputName].Equals(input)) { if (changedInputs.ContainsKey(input.inputName)) { changedInputs[input.inputName] = input; } else { changedInputs.Add(input.inputName, input); } } } if (snapToSyncedLocation) // custom code more effective, but this is enough sometimes { string posString = currentRecording.GetProperty(frame, "position"); if (!string.IsNullOrEmpty(posString)) { transform.position = ParseVector3(posString); } string rotString = currentRecording.GetProperty(frame, "rotation"); if (!string.IsNullOrEmpty(rotString)) { transform.eulerAngles = ParseVector3(rotString); } } } // update input to be used tihs frame foreach (var changedInput in changedInputs) { if (thisFrameInputs.ContainsKey(changedInput.Key)) { thisFrameInputs[changedInput.Key] = changedInput.Value; } else { thisFrameInputs.Add(changedInput.Key, changedInput.Value); } } playbackTime += Time.deltaTime; } } else if (_mode == InputVCRMode.Record) { realRecordingTime += Time.deltaTime; // record current input to frames, until recording catches up with realtime while (currentTime < realRecordingTime) { // mouse position & buttons if required if (recordMouseEvents) { currentRecording.AddProperty(currentFrame, "mousePos", Input.mousePosition.x.ToString() + "," + Input.mousePosition.y); for (int i = 0; i < 3; i++) { var mouseInput = new Recording.InputInfo(); mouseInput.inputType = Recording.InputInfo.InputType.Mouse; mouseInput.inputName = "mousebutton" + i; mouseInput.mouseButtonNum = i; mouseInput.buttonState = Input.GetMouseButton(i); currentRecording.AddInput(currentFrame, mouseInput); } } // and keycodes & buttons defined in inputsToRecord foreach (var input in inputsToRecord) { switch (input.inputType) { case Recording.InputInfo.InputType.Axis: input.axisValue = Input.GetAxis(input.inputName); break; case Recording.InputInfo.InputType.Button: input.buttonState = Input.GetButton(input.inputName); break; case Recording.InputInfo.InputType.Key: input.buttonState = Input.GetKey(input.inputName); break; default: Debug.Log("Unsupported input type : " + input.inputType); break; } currentRecording.AddInput(currentFrame, input); } // synced location if (syncRecordLocations && Time.time > nextPosSyncTime) { SyncPosition(); // add position to properties nextPosSyncTime = Time.time + 1f / autoSyncLocationRate; } // and any other properties foreach (var prop in nextPropertiesToRecord) { currentRecording.AddProperty(currentFrame, prop.name, prop.property); } nextPropertiesToRecord.Clear(); currentFrame++; } } }
void LateUpdate() { if ( _mode == InputVCRMode.Playback ) { // update last frame and this frame // this way, all changes are transmitted, even if a button press lasts less than a frame (like in Input) lastFrameInputs = thisFrameInputs; int lastFrame = currentFrame; currentFrame = currentRecording.GetClosestFrame ( playbackTime ); if ( currentFrame > currentRecording.totalFrames ) { // end of recording if ( finishedPlayback != null ) finishedPlayback( ); Stop (); } else { // go through all changes in recorded input since last frame var changedInputs = new Dictionary<string, Recording.InputInfo>(); for( int frame = lastFrame + 1; frame <= currentFrame; frame++ ) { foreach( var input in currentRecording.GetInputs ( frame ) ) { // thisFrameInputs only updated once per game frame, so all changes, no matter how brief, will be marked // if button has changed if ( !thisFrameInputs.ContainsKey ( input.inputName ) || !thisFrameInputs[input.inputName].Equals( input ) ) { if ( changedInputs.ContainsKey ( input.inputName ) ) changedInputs[input.inputName] = input; else changedInputs.Add( input.inputName, input ); } } if ( snapToSyncedLocation ) // custom code more effective, but this is enough sometimes { string posString = currentRecording.GetProperty ( frame, "position" ); if ( !string.IsNullOrEmpty ( posString ) ) transform.position = ParseVector3 ( posString ); string rotString = currentRecording.GetProperty ( frame, "rotation" ); if ( !string.IsNullOrEmpty( rotString ) ) transform.eulerAngles = ParseVector3 ( rotString ); } } // update input to be used tihs frame foreach( var changedInput in changedInputs ) { if ( thisFrameInputs.ContainsKey ( changedInput.Key ) ) thisFrameInputs[changedInput.Key] = changedInput.Value; else thisFrameInputs.Add ( changedInput.Key, changedInput.Value ); } playbackTime += Time.deltaTime; } } else if ( _mode == InputVCRMode.Record ) { realRecordingTime += Time.deltaTime; // record current input to frames, until recording catches up with realtime while ( currentTime < realRecordingTime ) { // mouse position & buttons if required if ( recordMouseEvents ) { currentRecording.AddProperty( currentFrame, "mousePos", Input.mousePosition.x.ToString() + "," + Input.mousePosition.y ); for( int i = 0; i < 3; i++ ) { var mouseInput = new Recording.InputInfo(); mouseInput.inputType = Recording.InputInfo.InputType.Mouse; mouseInput.inputName = "mousebutton" + i; mouseInput.mouseButtonNum = i; mouseInput.buttonState = Input.GetMouseButton( i ); currentRecording.AddInput ( currentFrame, mouseInput ); } } // and keycodes & buttons defined in inputsToRecord foreach( var input in inputsToRecord ) { switch ( input.inputType ) { case Recording.InputInfo.InputType.Axis: input.axisValue = Input.GetAxis( input.inputName ); break; case Recording.InputInfo.InputType.Button: input.buttonState = Input.GetButton( input.inputName ); break; case Recording.InputInfo.InputType.Key: input.buttonState = Input.GetKey( input.inputName ); break; default: Debug.Log( "Unsupported input type : " + input.inputType ); break; } currentRecording.AddInput ( currentFrame, input ); } // synced location if ( syncRecordLocations && Time.time > nextPosSyncTime ) { SyncPosition (); // add position to properties nextPosSyncTime = Time.time + 1f / autoSyncLocationRate; } // and any other properties foreach( var prop in nextPropertiesToRecord ) currentRecording.AddProperty ( currentFrame, prop.name, prop.property ); nextPropertiesToRecord.Clear (); currentFrame++; } } }