FirstGearGames / FishNet

FishNet: Unity Networking Evolved.
Other
1.37k stars 147 forks source link

SyncTimer finishes immediately on client #807

Open gregharding opened 3 days ago

gregharding commented 3 days ago

General Unity version: 6.0.25 (6000.0.25) Fish-Networking version: 4.5.4hf0R Discord link: Discord message

Description SyncTimers seem to finish immediately on clients but not servers/hosts. The cause seems to be that the internal _updateTime is only reset using SetUpdateTime() by the caller which in this case is the server in StartTimer() and UnpauseTimer(). When the timer operations are replicated to clients SetUpdateTime() is not called (eg. in a matching .Start or .Unpause operation) so when the client calls myTimer.Update() the elapsed time can be big enough to immediately finish the timer.

Replication Steps to reproduce the behavior:

  1. Create a SyncTimer as per the docs.
  2. Start the timer with 5 second duration at least 5 seconds after the client connects.
  3. Log the finish on the server and the client.
  4. Observe that the server runs the timer as expected and it finishes after 5 seconds, but clients can finish immediately due the internal deltaTime being larger than the timer duration.

Expected behavior Client should run the time for 5 second duration like the server.

FirstGearGames commented 3 days ago

Reviewing the code it looks like you're right in that SetUpdateTime is not calling in a read.

Can you please test a fix which sets the update time during a read.

Find this line in SyncTimer.cs

                if (op == SyncTimerOperation.Start)
                {

Change the if statement just below to this...

                    if (canModifyValues)
                    {
                        SetUpdateTime();
                        Paused = false;
                        Remaining = next;
                        Duration = duration;
                    }

PS: you can work around this by using timer.Update(Time.deltaTime);//or tickdelta is updating onTick. But the preferred method is no parameters because Unity limits maximum delta which can cause desyncs during low frame rates.

Edit: change seems to be working in my tests. Let me know!

gregharding commented 3 days ago

Yeah, I had tested a fix like that and also added a similar update to the .Unpause operation as well. Please check out the PR in https://github.com/FirstGearGames/FishNet/pull/808 and see if that does what it should.