TrueSync: TrueSyncManager.cs Source File

TrueSync

TrueSyncManager.cs
1 using UnityEngine;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Reflection;
5 
6 namespace TrueSync {
10  [AddComponentMenu("")]
11  public class TrueSyncManager : MonoBehaviour {
12 
13  private const float JitterTimeFactor = 0.001f;
14 
15  private const string serverSettingsAssetFile = "TrueSyncGlobalConfig";
16 
17  private enum StartState { BEHAVIOR_INITIALIZED, FIRST_UPDATE, STARTED };
18 
19  private StartState startState;
20 
24  public GameObject[] playerPrefabs;
25 
26  public static TrueSyncConfig _TrueSyncGlobalConfig;
27 
28  public static TrueSyncConfig TrueSyncGlobalConfig {
29  get {
30  if (_TrueSyncGlobalConfig == null) {
31  _TrueSyncGlobalConfig = (TrueSyncConfig) Resources.Load(serverSettingsAssetFile, typeof(TrueSyncConfig));
32  }
33 
34  return _TrueSyncGlobalConfig;
35  }
36  }
37 
38  public static TrueSyncConfig TrueSyncCustomConfig = null;
39 
40  public TrueSyncConfig customConfig;
41 
42  private Dictionary<int, List<GameObject>> gameOjectsSafeMap = new Dictionary<int, List<GameObject>>();
43 
47  private AbstractLockstep lockstep;
48 
49  private FP lockedTimeStep;
50 
54  private List<TrueSyncManagedBehaviour> generalBehaviours = new List<TrueSyncManagedBehaviour>();
55 
59  private Dictionary<byte, List<TrueSyncManagedBehaviour>> behaviorsByPlayer;
60 
64  private CoroutineScheduler scheduler;
65 
69  private List<TrueSyncManagedBehaviour> queuedBehaviours = new List<TrueSyncManagedBehaviour>();
70 
71  private Dictionary<ITrueSyncBehaviour, TrueSyncManagedBehaviour> mapBehaviorToManagedBehavior = new Dictionary<ITrueSyncBehaviour, TrueSyncManagedBehaviour>();
72 
73  private FP time = 0;
74 
78  public static FP DeltaTime {
79  get {
80  if (instance == null) {
81  return 0;
82  }
83 
84  return instance.lockedTimeStep;
85  }
86  }
87 
91  public static FP Time {
92  get {
93  if (instance == null || instance.lockstep == null) {
94  return 0;
95  }
96 
97  return instance.time;
98  }
99  }
100 
104  public static int Ticks {
105  get {
106  if (instance == null || instance.lockstep == null) {
107  return 0;
108  }
109 
110  return instance.lockstep.Ticks;
111  }
112  }
113 
117  public static int LastSafeTick {
118  get {
119  if (instance == null || instance.lockstep == null) {
120  return 0;
121  }
122 
123  return instance.lockstep.LastSafeTick;
124  }
125  }
126 
130  public static TSVector Gravity {
131  get {
132  if (instance == null) {
133  return TSVector.zero;
134  }
135 
136  return instance.ActiveConfig.gravity3D;
137  }
138  }
139 
143  public static List<TSPlayerInfo> Players {
144  get {
145  if (instance == null || instance.lockstep == null) {
146  return null;
147  }
148 
149  List<TSPlayerInfo> allPlayers = new List<TSPlayerInfo>();
150  foreach (TSPlayer tsp in instance.lockstep.Players.Values) {
151  if (!tsp.dropped) {
152  allPlayers.Add(tsp.playerInfo);
153  }
154  }
155 
156  return allPlayers;
157  }
158  }
159 
163  public static TSPlayerInfo LocalPlayer {
164  get {
165  if (instance == null || instance.lockstep == null) {
166  return null;
167  }
168 
169  return instance.lockstep.LocalPlayer.playerInfo;
170  }
171  }
172 
176  public static TrueSyncConfig Config {
177  get {
178  if (instance == null) {
179  return null;
180  }
181 
182  return instance.ActiveConfig;
183  }
184  }
185 
186  private static TrueSyncManager instance;
187 
188  private TrueSyncConfig ActiveConfig {
189  get {
190  if (TrueSyncCustomConfig != null) {
191  customConfig = TrueSyncCustomConfig;
192  TrueSyncCustomConfig = null;
193  }
194 
195  if (customConfig != null) {
196  return customConfig;
197  }
198 
199  return TrueSyncGlobalConfig;
200  }
201  }
202 
203  void Awake() {
204  TrueSyncConfig currentConfig = ActiveConfig;
205  lockedTimeStep = currentConfig.lockedTimeStep;
206 
207  StateTracker.Init(currentConfig.rollbackWindow);
208  TSRandom.Init();
209 
210  if (currentConfig.physics2DEnabled || currentConfig.physics3DEnabled) {
211  PhysicsManager.New(currentConfig);
212  PhysicsManager.instance.LockedTimeStep = lockedTimeStep;
213  PhysicsManager.instance.Init();
214  }
215 
216  StateTracker.AddTracking(this, "time");
217  }
218 
219  void Start() {
220  instance = this;
221  Application.runInBackground = true;
222 
223  ICommunicator communicator = null;
224  if (!PhotonNetwork.connected || !PhotonNetwork.inRoom) {
225  Debug.LogWarning("You are not connected to Photon. TrueSync will start in offline mode.");
226  } else {
227  communicator = new PhotonTrueSyncCommunicator(PhotonNetwork.networkingPeer);
228  }
229 
230  TrueSyncConfig activeConfig = ActiveConfig;
231 
232  lockstep = AbstractLockstep.NewInstance(
233  lockedTimeStep.AsFloat(),
234  communicator,
236  activeConfig.syncWindow,
237  activeConfig.panicWindow,
238  activeConfig.rollbackWindow,
239  OnGameStarted,
240  OnGamePaused,
241  OnGameUnPaused,
242  OnGameEnded,
243  OnPlayerDisconnection,
244  OnStepUpdate,
245  GetLocalData,
246  ProvideInputData
247  );
248 
249  if (ReplayRecord.replayMode == ReplayMode.LOAD_REPLAY) {
250  ReplayPicker.replayToLoad.Load();
251 
252  ReplayRecord replayRecord = ReplayRecord.replayToLoad;
253  if (replayRecord == null) {
254  Debug.LogError("Replay Record can't be loaded");
255  gameObject.SetActive(false);
256  return;
257  } else {
258  lockstep.ReplayRecord = replayRecord;
259  }
260  }
261 
262  if (activeConfig.showStats) {
263  this.gameObject.AddComponent<TrueSyncStats>().Lockstep = lockstep;
264  }
265 
266  scheduler = new CoroutineScheduler(lockstep);
267 
268  if (ReplayRecord.replayMode != ReplayMode.LOAD_REPLAY) {
269  if (communicator == null) {
270  lockstep.AddPlayer(0, "Local_Player", true);
271  } else {
272  List<PhotonPlayer> players = new List<PhotonPlayer>(PhotonNetwork.playerList);
273  players.Sort(UnityUtils.playerComparer);
274 
275  for (int index = 0, length = players.Count; index < length; index++) {
276  PhotonPlayer p = players[index];
277  lockstep.AddPlayer((byte) p.ID, p.NickName, p.IsLocal);
278  }
279  }
280  }
281 
282  TrueSyncBehaviour[] behavioursArray = FindObjectsOfType<TrueSyncBehaviour>();
283  for (int index = 0, length = behavioursArray.Length; index < length; index++) {
284  generalBehaviours.Add(NewManagedBehavior(behavioursArray[index]));
285  }
286 
287  initBehaviors();
288  initGeneralBehaviors(generalBehaviours, false);
289 
290  PhysicsManager.instance.OnRemoveBody(OnRemovedRigidBody);
291 
292  startState = StartState.BEHAVIOR_INITIALIZED;
293  }
294 
295  private TrueSyncManagedBehaviour NewManagedBehavior(ITrueSyncBehaviour trueSyncBehavior) {
296  TrueSyncManagedBehaviour result = new TrueSyncManagedBehaviour(trueSyncBehavior);
297  mapBehaviorToManagedBehavior[trueSyncBehavior] = result;
298 
299  return result;
300  }
301 
302  private void initBehaviors() {
303  behaviorsByPlayer = new Dictionary<byte, List<TrueSyncManagedBehaviour>>();
304 
305  var playersEnum = lockstep.Players.GetEnumerator();
306  while (playersEnum.MoveNext()) {
307  TSPlayer p = playersEnum.Current.Value;
308 
309  List<TrueSyncManagedBehaviour> behaviorsInstatiated = new List<TrueSyncManagedBehaviour>();
310 
311  for (int index = 0, length = playerPrefabs.Length; index < length; index++) {
312  GameObject prefab = playerPrefabs[index];
313 
314  GameObject prefabInst = Instantiate(prefab);
315  InitializeGameObject(prefabInst, prefabInst.transform.position.ToTSVector(), prefabInst.transform.rotation.ToTSQuaternion());
316 
317  TrueSyncBehaviour[] behaviours = prefabInst.GetComponentsInChildren<TrueSyncBehaviour>();
318  for (int index2 = 0, length2 = behaviours.Length; index2 < length2; index2++) {
319  TrueSyncBehaviour behaviour = behaviours[index2];
320 
321  behaviour.owner = p.playerInfo;
322  behaviour.localOwner = lockstep.LocalPlayer.playerInfo;
323  behaviour.numberOfPlayers = lockstep.Players.Count;
324 
325  TrueSyncManagedBehaviour tsmb = NewManagedBehavior(behaviour);
326  tsmb.owner = behaviour.owner;
327  tsmb.localOwner = behaviour.localOwner;
328 
329  behaviorsInstatiated.Add(tsmb);
330  }
331  }
332 
333  behaviorsByPlayer.Add(p.ID, behaviorsInstatiated);
334  }
335  }
336 
337  private void initGeneralBehaviors(IEnumerable<TrueSyncManagedBehaviour> behaviours, bool realOwnerId) {
338  List<TSPlayer> playersList = new List<TSPlayer>(lockstep.Players.Values);
339  List<TrueSyncManagedBehaviour> itemsToRemove = new List<TrueSyncManagedBehaviour>();
340 
341  var behavioursEnum = behaviours.GetEnumerator();
342  while (behavioursEnum.MoveNext()) {
343  TrueSyncManagedBehaviour tsmb = behavioursEnum.Current;
344 
345  if (!(tsmb.trueSyncBehavior is TrueSyncBehaviour)) {
346  continue;
347  }
348 
349  TrueSyncBehaviour bh = (TrueSyncBehaviour)tsmb.trueSyncBehavior;
350 
351  if (realOwnerId) {
352  bh.ownerIndex = bh.owner.Id;
353  } else {
354  if (bh.ownerIndex >= 0 && bh.ownerIndex < playersList.Count) {
355  bh.ownerIndex = playersList[bh.ownerIndex].ID;
356  }
357  }
358 
359  if (behaviorsByPlayer.ContainsKey((byte)bh.ownerIndex)) {
360  bh.owner = lockstep.Players[(byte)bh.ownerIndex].playerInfo;
361 
362  behaviorsByPlayer[(byte)bh.ownerIndex].Add(tsmb);
363  itemsToRemove.Add(tsmb);
364  } else {
365  bh.ownerIndex = -1;
366  }
367 
368  bh.localOwner = lockstep.LocalPlayer.playerInfo;
369  bh.numberOfPlayers = lockstep.Players.Count;
370 
371  tsmb.owner = bh.owner;
372  tsmb.localOwner = bh.localOwner;
373  }
374 
375  for (int index = 0, length = itemsToRemove.Count; index < length; index++) {
376  generalBehaviours.Remove(itemsToRemove[index]);
377  }
378  }
379 
380  private void CheckQueuedBehaviours() {
381  if (queuedBehaviours.Count > 0) {
382  generalBehaviours.AddRange(queuedBehaviours);
383  initGeneralBehaviors(queuedBehaviours, true);
384 
385  for (int index = 0, length = queuedBehaviours.Count; index < length; index++) {
386  TrueSyncManagedBehaviour tsmb = queuedBehaviours[index];
387 
388  tsmb.SetGameInfo(lockstep.LocalPlayer.playerInfo, lockstep.Players.Count);
389  tsmb.OnSyncedStart();
390  }
391 
392  queuedBehaviours.Clear();
393  }
394  }
395 
396  void Update() {
397  if (lockstep != null && startState != StartState.STARTED) {
398  if (startState == StartState.BEHAVIOR_INITIALIZED) {
399  startState = StartState.FIRST_UPDATE;
400  } else if (startState == StartState.FIRST_UPDATE) {
401  lockstep.RunSimulation(true);
402  startState = StartState.STARTED;
403  }
404  }
405  }
406 
410  public static void RunSimulation() {
411  if (instance != null && instance.lockstep != null) {
412  instance.lockstep.RunSimulation(false);
413  }
414  }
415 
419  public static void PauseSimulation() {
420  if (instance != null && instance.lockstep != null) {
421  instance.lockstep.PauseSimulation();
422  }
423  }
424 
428  public static void EndSimulation() {
429  if (instance != null && instance.lockstep != null) {
430  instance.lockstep.EndSimulation();
431  }
432  }
433 
437  public static void UpdateCoroutines() {
438  if (instance != null && instance.lockstep != null) {
439  instance.scheduler.UpdateAllCoroutines();
440  }
441  }
442 
448  public static void SyncedStartCoroutine(IEnumerator coroutine) {
449  if (instance != null && instance.lockstep != null) {
450  instance.scheduler.StartCoroutine(coroutine);
451  }
452  }
453 
459  public static GameObject SyncedInstantiate(GameObject prefab) {
460  return SyncedInstantiate(prefab, prefab.transform.position.ToTSVector(), prefab.transform.rotation.ToTSQuaternion());
461  }
462 
470  public static GameObject SyncedInstantiate(GameObject prefab, TSVector position, TSQuaternion rotation) {
471  if (instance != null && instance.lockstep != null) {
472  GameObject go = GameObject.Instantiate(prefab, position.ToVector(), rotation.ToQuaternion()) as GameObject;
473 
474  if (ReplayRecord.replayMode != ReplayMode.LOAD_REPLAY) {
475  AddGameObjectOnSafeMap(go);
476  }
477 
478  MonoBehaviour[] monoBehaviours = go.GetComponentsInChildren<MonoBehaviour>();
479  for (int index = 0, length = monoBehaviours.Length; index < length; index++) {
480  MonoBehaviour bh = monoBehaviours[index];
481 
482  if (bh is ITrueSyncBehaviour) {
483  instance.queuedBehaviours.Add(instance.NewManagedBehavior((ITrueSyncBehaviour)bh));
484  }
485  }
486 
487  InitializeGameObject(go, position, rotation);
488 
489  return go;
490  }
491 
492  return null;
493  }
494 
495  private static void AddGameObjectOnSafeMap(GameObject go) {
496 
497  Dictionary<int, List<GameObject>> safeMap = instance.gameOjectsSafeMap;
498 
499  int currentTick = TrueSyncManager.Ticks + 1;
500  if (!safeMap.ContainsKey(currentTick)) {
501  safeMap.Add(currentTick, new List<GameObject>());
502  }
503 
504  safeMap[currentTick].Add(go);
505  }
506 
507  private static void CheckGameObjectsSafeMap() {
508  Dictionary<int, List<GameObject>> safeMap = instance.gameOjectsSafeMap;
509 
510  int currentTick = TrueSyncManager.Ticks + 1;
511  if (safeMap.ContainsKey(currentTick)) {
512  List<GameObject> gos = safeMap[currentTick];
513  for (int i = 0, l = gos.Count; i < l; i++) {
514  GameObject go = gos[i];
515  if (go != null) {
516  Renderer rend = go.GetComponent<Renderer>();
517  if (rend != null) {
518  rend.enabled = false;
519  }
520 
521  GameObject.Destroy(go);
522  }
523  }
524 
525  gos.Clear();
526  }
527 
528  safeMap.Remove(TrueSyncManager.LastSafeTick);
529  }
530 
531  private static void InitializeGameObject(GameObject go, TSVector position, TSQuaternion rotation) {
532  ICollider[] tsColliders = go.GetComponentsInChildren<ICollider>();
533  if (tsColliders != null) {
534  for (int index = 0, length = tsColliders.Length; index < length; index++) {
535  PhysicsManager.instance.AddBody(tsColliders[index]);
536  }
537  }
538 
539  TSTransform rootTSTransform = go.GetComponent<TSTransform>();
540  if (rootTSTransform != null) {
541  rootTSTransform.Initialize();
542 
543  rootTSTransform.position = position;
544  rootTSTransform.rotation = rotation;
545  }
546 
547  TSTransform[] tsTransforms = go.GetComponentsInChildren<TSTransform>();
548  if (tsTransforms != null) {
549  for (int index = 0, length = tsTransforms.Length; index < length; index++) {
550  TSTransform tsTransform = tsTransforms[index];
551 
552  if (tsTransform != rootTSTransform) {
553  tsTransform.Initialize();
554  }
555  }
556  }
557 
558  TSTransform2D rootTSTransform2D = go.GetComponent<TSTransform2D>();
559  if (rootTSTransform2D != null) {
560  rootTSTransform2D.Initialize();
561 
562  rootTSTransform2D.position = new TSVector2(position.x, position.y);
563  rootTSTransform2D.rotation = rotation.ToQuaternion().eulerAngles.z;
564  }
565 
566  TSTransform2D[] tsTransforms2D = go.GetComponentsInChildren<TSTransform2D>();
567  if (tsTransforms2D != null) {
568  for (int index = 0, length = tsTransforms2D.Length; index < length; index++) {
569  TSTransform2D tsTransform2D = tsTransforms2D[index];
570 
571  if (tsTransform2D != rootTSTransform2D) {
572  tsTransform2D.Initialize();
573  }
574  }
575  }
576  }
577 
585  public static GameObject SyncedInstantiate(GameObject prefab, TSVector2 position, TSQuaternion rotation) {
586  return SyncedInstantiate(prefab, new TSVector(position.x, position.y, 0), rotation);
587  }
588 
596  public static void SyncedDestroy(GameObject gameObject) {
597  if (instance != null && instance.lockstep != null) {
598  SyncedDisableBehaviour(gameObject);
599 
600  TSCollider[] tsColliders = gameObject.GetComponentsInChildren<TSCollider>();
601  if (tsColliders != null) {
602  for (int index = 0, length = tsColliders.Length; index < length; index++) {
603  TSCollider tsCollider = tsColliders[index];
604  DestroyTSRigidBody(tsCollider.gameObject, tsCollider.Body);
605  }
606  }
607 
608  TSCollider2D[] tsColliders2D = gameObject.GetComponentsInChildren<TSCollider2D>();
609  if (tsColliders2D != null) {
610  for (int index = 0, length = tsColliders2D.Length; index < length; index++) {
611  TSCollider2D tsCollider2D = tsColliders2D[index];
612  DestroyTSRigidBody(tsCollider2D.gameObject, tsCollider2D.Body);
613  }
614  }
615  }
616  }
617 
621  public static void SyncedDisableBehaviour(GameObject gameObject) {
622  MonoBehaviour[] monoBehaviours = gameObject.GetComponentsInChildren<MonoBehaviour>();
623 
624  for (int index = 0, length = monoBehaviours.Length; index < length; index++) {
625  MonoBehaviour tsb = monoBehaviours[index];
626 
627  if (tsb is ITrueSyncBehaviour && instance.mapBehaviorToManagedBehavior.ContainsKey((ITrueSyncBehaviour)tsb)) {
628  instance.mapBehaviorToManagedBehavior[(ITrueSyncBehaviour)tsb].disabled = true;
629  }
630  }
631  }
632 
638  private static void DestroyTSRigidBody(GameObject tsColliderGO, IBody body) {
639  tsColliderGO.gameObject.SetActive(false);
640  instance.lockstep.Destroy(body);
641  }
642 
648  public static void RegisterITrueSyncBehaviour(ITrueSyncBehaviour trueSyncBehaviour) {
649  if (instance != null && instance.lockstep != null) {
650  instance.queuedBehaviours.Add(instance.NewManagedBehavior(trueSyncBehaviour));
651  }
652  }
653 
659  public static void RegisterIsReadyChecker(TrueSyncIsReady IsReadyChecker) {
660  if (instance != null && instance.lockstep != null) {
661  instance.lockstep.GameIsReady += IsReadyChecker;
662  }
663  }
664 
670  public static void RemovePlayer(int playerId) {
671  if (instance != null && instance.lockstep != null) {
672  List<TrueSyncManagedBehaviour> behaviorsList = instance.behaviorsByPlayer[(byte)playerId];
673 
674  for (int index = 0, length = behaviorsList.Count; index < length; index++) {
675  TrueSyncManagedBehaviour tsmb = behaviorsList[index];
676  tsmb.disabled = true;
677 
678  TSCollider[] tsColliders = ((TrueSyncBehaviour)tsmb.trueSyncBehavior).gameObject.GetComponentsInChildren<TSCollider>();
679  if (tsColliders != null) {
680  for (int index2 = 0, length2 = tsColliders.Length; index2 < length2; index2++) {
681  TSCollider tsCollider = tsColliders[index2];
682 
683  if (!tsCollider.Body.TSDisabled) {
684  DestroyTSRigidBody(tsCollider.gameObject, tsCollider.Body);
685  }
686  }
687  }
688 
689  TSCollider2D[] tsCollider2Ds = ((TrueSyncBehaviour)tsmb.trueSyncBehavior).gameObject.GetComponentsInChildren<TSCollider2D>();
690  if (tsCollider2Ds != null) {
691  for (int index2 = 0, length2 = tsCollider2Ds.Length; index2 < length2; index2++) {
692  TSCollider2D tsCollider2D = tsCollider2Ds[index2];
693 
694  if (!tsCollider2D.Body.TSDisabled) {
695  DestroyTSRigidBody(tsCollider2D.gameObject, tsCollider2D.Body);
696  }
697  }
698  }
699  }
700  }
701  }
702 
703  private FP tsDeltaTime = 0;
704 
705  void FixedUpdate() {
706  if (lockstep != null) {
707  tsDeltaTime += UnityEngine.Time.deltaTime;
708 
709  if (tsDeltaTime >= (lockedTimeStep - JitterTimeFactor)) {
710  tsDeltaTime = 0;
711 
712  instance.scheduler.UpdateAllCoroutines();
713  lockstep.Update();
714  }
715  }
716  }
717 
718  InputDataBase ProvideInputData() {
719  return new InputData();
720  }
721 
722  void GetLocalData(InputDataBase playerInputData) {
723  TrueSyncInput.CurrentInputData = (InputData) playerInputData;
724 
725  if (behaviorsByPlayer.ContainsKey(playerInputData.ownerID)) {
726  List<TrueSyncManagedBehaviour> managedBehavioursByPlayer = behaviorsByPlayer[playerInputData.ownerID];
727  for (int index = 0, length = managedBehavioursByPlayer.Count; index < length; index++) {
728  TrueSyncManagedBehaviour bh = managedBehavioursByPlayer[index];
729 
730  if (bh != null && !bh.disabled) {
731  bh.OnSyncedInput();
732  }
733  }
734  }
735 
736  TrueSyncInput.CurrentInputData = null;
737  }
738 
739  void OnStepUpdate(List<InputDataBase> allInputData) {
740  time += lockedTimeStep;
741 
742  if (ReplayRecord.replayMode != ReplayMode.LOAD_REPLAY) {
743  CheckGameObjectsSafeMap();
744  }
745 
746  TrueSyncInput.SetAllInputs(null);
747 
748  for (int index = 0, length = generalBehaviours.Count; index < length; index++) {
749  TrueSyncManagedBehaviour bh = generalBehaviours[index];
750 
751  if (bh != null && !bh.disabled) {
752  bh.OnPreSyncedUpdate();
753  instance.scheduler.UpdateAllCoroutines();
754  }
755  }
756 
757  for (int index = 0, length = allInputData.Count; index < length; index++) {
758  InputDataBase playerInputData = allInputData[index];
759 
760  if (behaviorsByPlayer.ContainsKey(playerInputData.ownerID)) {
761  List<TrueSyncManagedBehaviour> managedBehavioursByPlayer = behaviorsByPlayer[playerInputData.ownerID];
762  for (int index2 = 0, length2 = managedBehavioursByPlayer.Count; index2 < length2; index2++) {
763  TrueSyncManagedBehaviour bh = managedBehavioursByPlayer[index2];
764 
765  if (bh != null && !bh.disabled) {
766  bh.OnPreSyncedUpdate();
767  instance.scheduler.UpdateAllCoroutines();
768  }
769  }
770  }
771  }
772 
773  TrueSyncInput.SetAllInputs(allInputData);
774 
775  TrueSyncInput.CurrentSimulationData = null;
776  for (int index = 0, length = generalBehaviours.Count; index < length; index++) {
777  TrueSyncManagedBehaviour bh = generalBehaviours[index];
778 
779  if (bh != null && !bh.disabled) {
780  bh.OnSyncedUpdate();
781  instance.scheduler.UpdateAllCoroutines();
782  }
783  }
784 
785  for (int index = 0, length = allInputData.Count; index < length; index++) {
786  InputDataBase playerInputData = allInputData[index];
787 
788  if (behaviorsByPlayer.ContainsKey(playerInputData.ownerID)) {
789  TrueSyncInput.CurrentSimulationData = (InputData) playerInputData;
790 
791  List<TrueSyncManagedBehaviour> managedBehavioursByPlayer = behaviorsByPlayer[playerInputData.ownerID];
792  for (int index2 = 0, length2 = managedBehavioursByPlayer.Count; index2 < length2; index2++) {
793  TrueSyncManagedBehaviour bh = managedBehavioursByPlayer[index2];
794 
795  if (bh != null && !bh.disabled) {
796  bh.OnSyncedUpdate();
797  instance.scheduler.UpdateAllCoroutines();
798  }
799  }
800  }
801 
802  TrueSyncInput.CurrentSimulationData = null;
803  }
804 
805  CheckQueuedBehaviours();
806  }
807 
808  private void OnRemovedRigidBody(IBody body) {
809  GameObject go = PhysicsManager.instance.GetGameObject(body);
810 
811  if (go != null) {
812  List<TrueSyncBehaviour> behavioursToRemove = new List<TrueSyncBehaviour>(go.GetComponentsInChildren<TrueSyncBehaviour>());
813  RemoveFromTSMBList(queuedBehaviours, behavioursToRemove);
814  RemoveFromTSMBList(generalBehaviours, behavioursToRemove);
815 
816  var behaviorsByPlayerEnum = behaviorsByPlayer.GetEnumerator();
817  while (behaviorsByPlayerEnum.MoveNext()) {
818  List<TrueSyncManagedBehaviour> listBh = behaviorsByPlayerEnum.Current.Value;
819  RemoveFromTSMBList(listBh, behavioursToRemove);
820  }
821  }
822  }
823 
824  private void RemoveFromTSMBList(List<TrueSyncManagedBehaviour> tsmbList, List<TrueSyncBehaviour> behaviours) {
825  List<TrueSyncManagedBehaviour> toRemove = new List<TrueSyncManagedBehaviour>();
826  for (int index = 0, length = tsmbList.Count; index < length; index++) {
827  TrueSyncManagedBehaviour tsmb = tsmbList[index];
828 
829  if ((tsmb.trueSyncBehavior is TrueSyncBehaviour) && behaviours.Contains((TrueSyncBehaviour)tsmb.trueSyncBehavior)) {
830  toRemove.Add(tsmb);
831  }
832  }
833 
834  for (int index = 0, length = toRemove.Count; index < length; index++) {
835  TrueSyncManagedBehaviour tsmb = toRemove[index];
836  tsmbList.Remove(tsmb);
837  }
838  }
839 
843  public static void CleanUp() {
844  ResourcePool.CleanUpAll();
845  StateTracker.CleanUp();
846  instance = null;
847  }
848 
849  void OnPlayerDisconnection(byte playerId) {
850  TrueSyncManagedBehaviour.OnPlayerDisconnection(generalBehaviours, behaviorsByPlayer, playerId);
851  }
852 
853  void OnGameStarted() {
854  TrueSyncManagedBehaviour.OnGameStarted(generalBehaviours, behaviorsByPlayer);
855  instance.scheduler.UpdateAllCoroutines();
856 
857  CheckQueuedBehaviours();
858  }
859 
860  void OnGamePaused() {
861  TrueSyncManagedBehaviour.OnGamePaused(generalBehaviours, behaviorsByPlayer);
862  instance.scheduler.UpdateAllCoroutines();
863  }
864 
865  void OnGameUnPaused() {
866  TrueSyncManagedBehaviour.OnGameUnPaused(generalBehaviours, behaviorsByPlayer);
867  instance.scheduler.UpdateAllCoroutines();
868  }
869 
870  void OnGameEnded() {
871  TrueSyncManagedBehaviour.OnGameEnded(generalBehaviours, behaviorsByPlayer);
872  instance.scheduler.UpdateAllCoroutines();
873  }
874 
875  void OnApplicationQuit() {
876  EndSimulation();
877  }
878 
879  }
880 
881 }
int rollbackWindow
Rollback window size.
Manages creation of player prefabs and lockstep execution.
TSPlayerInfo owner
Basic info about the owner of this behaviour.
TSPlayerInfo localOwner
Basic info about the local player.
static void UpdateCoroutines()
Update all coroutines created.
static void RegisterITrueSyncBehaviour(ITrueSyncBehaviour trueSyncBehaviour)
Registers an implementation of ITrueSyncBehaviour to be included in the simulation.
static List< TSPlayerInfo > Players
Returns the list of players connected.
Provides a few utilities to be used on TrueSync exposed classes.
Definition: UnityUtils.cs:10
GameObject[] playerPrefabs
Player prefabs to be instantiated in each machine.
A deterministic version of Unity&#39;s Transform component for 2D physics.
Definition: TSTransform2D.cs:9
static FP Time
Returns the time elapsed since the beginning of the simulation.
static void RemovePlayer(int playerId)
Removes objets related to a provided player.
static int LastSafeTick
Returns the last safe simulated tick.
TSVector2 position
Property access to position.
static void RegisterIsReadyChecker(TrueSyncIsReady IsReadyChecker)
Register a TrueSyncIsReady delegate to that returns true if the game can proceed or false otherwise...
A deterministic version of Unity&#39;s Transform component for 3D physics.
Definition: TSTransform.cs:9
Represents each player&#39;s behaviour simulated on every machine connected to the game.
static IPhysicsManager instance
Returns a proper implementation of IPhysicsManager.
static TrueSyncConfig Config
Returns the active TrueSyncConfig used by the TrueSyncManager.
static PlayerComparer playerComparer
Instance of a PlayerComparer.
Definition: UnityUtils.cs:26
Truesync&#39;s ICommunicator implementation based on PUN.
TSQuaternion rotation
Property access to rotation.
Definition: TSTransform.cs:50
bool physics3DEnabled
Indicates if the 3D physics engine should be enabled.
FP rotation
Property access to rotation.
TSVector gravity3D
Represents the simulated gravity.
static TSPlayerInfo LocalPlayer
Returns the local player.
static IPhysicsManager New(TrueSyncConfig trueSyncConfig)
Instantiates a new IPhysicsManager.
static int Ticks
Returns the number of the last simulated tick.
Abstract collider for 3D shapes.
Definition: TSCollider.cs:13
Represents a set of configurations for TrueSync.
static TSVector Gravity
Returns the simulated gravity.
static void SyncedStartCoroutine(IEnumerator coroutine)
Starts a new coroutine.
int numberOfPlayers
Number of players connected to the game.
int panicWindow
Maximum number of ticks to wait until all other players inputs arrive.
bool showStats
When true shows a debug interface with a few information.
TSVector position
Property access to position.
Definition: TSTransform.cs:23
void Initialize()
Initializes internal properties based on whether there is a TSCollider2D attached.
void Initialize()
Initializes internal properties based on whether there is a TSCollider attached.
Definition: TSTransform.cs:314
FP lockedTimeStep
Time between each TrueSync&#39;s frame.
TrueSync&#39;s communicator interface.
Definition: ICommunicator.cs:9
Manages physics simulation.
static GameObject SyncedInstantiate(GameObject prefab)
Instantiate a new prefab in a deterministic way.
static void PauseSimulation()
Pauses the game simulation.
int ownerIndex
Index of the owner at initial players list.
static GameObject SyncedInstantiate(GameObject prefab, TSVector position, TSQuaternion rotation)
Instantiates a new prefab in a deterministic way.
IBody3D Body
Returns the body linked to this collider.
Definition: TSCollider.cs:114
Abstract collider for 2D shapes.
Definition: TSCollider2D.cs:12
static FP DeltaTime
Returns the deltaTime between two simulation calls.
static void RunSimulation()
Run/Unpause the game simulation.
bool physics2DEnabled
Indicates if the 2D physics engine should be enabled.
static void EndSimulation()
End the game simulation.
static void CleanUp()
Clean up references to be collected by gc.
int syncWindow
Synchronization window size.
IBody2D Body
Returns RigidBody associated to this TSRigidBody.
Definition: TSCollider2D.cs:70
static void SyncedDisableBehaviour(GameObject gameObject)
Disables &#39;OnSyncedInput&#39; and &#39;OnSyncUpdate&#39; calls to every ITrueSyncBehaviour attached.
Represents a common interface to 2D and 3D bodies.
Definition: IBody.cs:6
static void SyncedDestroy(GameObject gameObject)
Destroys a GameObject in a deterministic way.
static GameObject SyncedInstantiate(GameObject prefab, TSVector2 position, TSQuaternion rotation)
Instantiates a new prefab in a deterministic way.
Generated by   doxygen 1.8.11