浏览代码

Merge pull request #7 from Unity-Technologies/dev

Latest class renaming and Doc updates.
/main
GitHub 4 年前
当前提交
a41d97a0
共有 127 个文件被更改,包括 6015 次插入5290 次删除
  1. 3
      .gitignore
  2. 4
      Assets/Prefabs/UI/JoinContent.prefab
  3. 7
      Assets/Prefabs/UI/LobbyButtonUI.prefab
  4. 16
      Assets/Prefabs/UI/LobbyCodeCanvas.prefab
  5. 22
      Assets/Prefabs/UI/LobbyGameCanvas.prefab
  6. 42
      Assets/Prefabs/UI/LobbyUserList.prefab
  7. 4
      Assets/Prefabs/UI/PlayerInteractionPanel.prefab
  8. 17
      Assets/Prefabs/UI/RelayCodeCanvas.prefab
  9. 283
      Assets/Scenes/mainScene.unity
  10. 2
      Assets/Scripts/Auth/Identity.cs
  11. 2
      Assets/Scripts/Auth/SubIdentity_Authentication.cs
  12. 159
      Assets/Scripts/Entities/GameStateManager.cs
  13. 6
      Assets/Scripts/Entities/LobbyServiceData.cs
  14. 14
      Assets/Scripts/Entities/LobbyUser.cs
  15. 542
      Assets/Scripts/Entities/LocalLobby.cs
  16. 24
      Assets/Scripts/Tests/Editor/LobbyTests.cs
  17. 6
      Assets/Scripts/Tests/Editor/ObserverTests.cs
  18. 2
      Assets/Scripts/Tests/Editor/Tests.Editor.asmdef
  19. 2
      Assets/Scripts/Tests/PlayMode/Tests.Play.asmdef
  20. 3
      Assets/Scripts/UI/BackButtonUI.cs
  21. 7
      Assets/Scripts/UI/CountdownUI.cs
  22. 7
      Assets/Scripts/UI/CreateMenuUI.cs
  23. 3
      Assets/Scripts/UI/EmoteButtonUI.cs
  24. 5
      Assets/Scripts/UI/EndGameButtonUI.cs
  25. 3
      Assets/Scripts/UI/ExitButtonUI.cs
  26. 3
      Assets/Scripts/UI/GameStateVisibilityUI.cs
  27. 61
      Assets/Scripts/UI/JoinMenuUI.cs
  28. 15
      Assets/Scripts/UI/LobbyButtonUI.cs
  29. 2
      Assets/Scripts/UI/MainMenuUI.cs
  30. 2
      Assets/Scripts/UI/NameChangeUI.cs
  31. 5
      Assets/Scripts/UI/ObserverPanel.cs
  32. 3
      Assets/Scripts/UI/PlayerNameUI.cs
  33. 3
      Assets/Scripts/UI/ReadyCheckUI.cs
  34. 3
      Assets/Scripts/UI/SpinnerUI.cs
  35. 3
      Assets/Scripts/UI/UIPanelBase.cs
  36. 5
      Assets/Scripts/UI/UserStateVisibilityUI.cs
  37. 42
      Assets/Scripts/UI/JoinCreateLobbyUI.cs
  38. 4
      Assets/Scripts/UI/InLobbyUserUI.cs
  39. 2
      Assets/Scripts/LobbyRelaySample.asmdef
  40. 61
      README.md
  41. 999
      ~Documentation/Images/dashboard1_beta.png
  42. 999
      ~Documentation/Images/services1.PNG
  43. 999
      ~Documentation/Images/services2.PNG
  44. 251
      ~Documentation/Images/tutorial_1_lobbyList.png
  45. 353
      ~Documentation/Images/tutorial_2_createMenu.png
  46. 565
      ~Documentation/Images/tutorial_3_HostGame.png
  47. 352
      ~Documentation/Images/tutorial_4_newLobby.png
  48. 947
      ~Documentation/Images/tutorial_5_editorCow.png
  49. 803
      ~Documentation/Images/tutorial_6_countDown.png
  50. 971
      ~Documentation/Images/tutorial_7_ingame.png
  51. 200
      Assets/Scripts/Infrastructure/Locator.cs
  52. 126
      Assets/Scripts/Infrastructure/LogHandler.cs
  53. 176
      Assets/Scripts/Infrastructure/Messenger.cs
  54. 5
      Assets/Scripts/Auth/NameGenerator.cs
  55. 276
      Assets/Scripts/Infrastructure/UpdateSlow.cs
  56. 4
      Assets/Scripts/Entities/LocalLobbyObserver.cs
  57. 130
      Assets/Scripts/Tests/PlayMode/LobbyReadyCheckTests.cs
  58. 163
      Assets/Scripts/Tests/PlayMode/LobbyRoundtripTests.cs
  59. 33
      Assets/Scripts/UI/DisplayCodeUI.cs
  60. 60
      Assets/Scripts/UI/InLobbyUserList.cs
  61. 19
      Assets/Scripts/UI/LobbyNameUI.cs
  62. 19
      Assets/Scripts/UI/RelayAddressUI.cs
  63. 22
      Assets/Scripts/UI/ShowWhenLobbyStateUI.cs
  64. 15
      Assets/Scripts/UI/StartLobbyButtonUI.cs
  65. 108
      Assets/Scripts/Lobby/LobbyAPIInterface.cs
  66. 218
      Assets/Scripts/Lobby/LobbyAsyncRequests.cs
  67. 109
      Assets/Scripts/Lobby/LobbyContentHeartbeat.cs
  68. 23
      Assets/Scripts/Lobby/LobbyListHeartbeat.cs
  69. 63
      Assets/Scripts/Lobby/ReadyCheck.cs
  70. 89
      Assets/Scripts/Lobby/ToLocalLobby.cs
  71. 4
      Assets/Scripts/Entities/LobbyDataObserver.cs
  72. 67
      Assets/Scripts/Entities/LobbyReadyCheck.cs
  73. 131
      Assets/Scripts/Tests/PlayMode/ReadyCheckTests.cs
  74. 163
      Assets/Scripts/Tests/PlayMode/RoomsRoundtripTests.cs
  75. 11
      Assets/Scripts/UI/RelayCodeUI.cs.meta
  76. 5
      Assets/Scripts/UI/SerializedValueEvents.cs
  77. 11
      Assets/Scripts/UI/SerializedValueEvents.cs.meta
  78. 19
      Assets/Scripts/UI/LobbyStateVisibilityUI.cs
  79. 60
      Assets/Scripts/UI/LobbyUsersUI.cs
  80. 27
      Assets/Scripts/UI/RelayCodeUI.cs
  81. 26
      Assets/Scripts/UI/RoomCodeUI.cs
  82. 16
      Assets/Scripts/UI/ServerAddressUI.cs
  83. 16
      Assets/Scripts/UI/ServerNameUI.cs
  84. 12
      Assets/Scripts/UI/StartLobbyButton.cs
  85. 8
      Assets/Scripts/Utilities.meta
  86. 11
      Assets/TempDeleteAllRooms.cs.meta
  87. 33
      Assets/TempDeleteAllRooms.cs
  88. 167
      ProjectSettings/SceneTemplateSettings.json
  89. 16
      ProjectSettings/BurstAotSettings_StandaloneWindows.json
  90. 6
      ProjectSettings/CommonBurstAotSettings.json
  91. 0
      /Assets/Scripts/Entities/LocalLobbyObserver.cs.meta
  92. 0
      /Assets/Scripts/Entities/LocalLobby.cs.meta
  93. 0
      /Assets/Scripts/Entities/LocalLobby.cs
  94. 0
      /Assets/Scripts/Tests/PlayMode/LobbyRoundtripTests.cs.meta
  95. 0
      /Assets/Scripts/Tests/PlayMode/LobbyReadyCheckTests.cs.meta
  96. 0
      /Assets/Scripts/UI/StartLobbyButtonUI.cs.meta
  97. 0
      /Assets/Scripts/UI/ShowWhenLobbyStateUI.cs.meta

3
.gitignore


.idea
.idea/
.UserSettings
.UserSettings/

4
Assets/Prefabs/UI/JoinContent.prefab


m_CallState: 2
showing: 1
m_LobbyButtonPrefab: {fileID: 7018369548608736188, guid: f6d35a456ba76a24587dce83bd088b7d, type: 3}
m_RoomCodeField: {fileID: 8659642538454988273}
m_RoomButtonParent: {fileID: 7824921818678239159}
m_LobbyCodeField: {fileID: 8659642538454988273}
m_LobbyButtonParent: {fileID: 7824921818678239159}
--- !u!114 &7550446569341709048
MonoBehaviour:
m_ObjectHideFlags: 0

7
Assets/Prefabs/UI/LobbyButtonUI.prefab


m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 7018369548608736188}
m_TargetAssemblyTypeName: LobbyRooms.UI.LobbyButtonUI, LobbyRooms
m_MethodName: OnRoomUpdated
m_Mode: 0
m_TargetAssemblyTypeName: LobbyRelaySample.UI.LobbyButtonUI, LobbyRooms
m_MethodName: OnLobbyClicked
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine

m_BoolArgument: 0
m_CallState: 2
observeOnStart: 1
--- !u!114 &1059336587790472163
MonoBehaviour:
m_ObjectHideFlags: 0

16
Assets/Prefabs/UI/LobbyCodeCanvas.prefab


m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 22
m_fontSizeBase: 22
m_fontSize: 18
m_fontSizeBase: 18
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18

m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_SizeDelta: {x: 200, y: 25}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &1118541987231860831
CanvasRenderer:

m_Script: {fileID: 11500000, guid: a6e005db2e7b3d94d9409975660cf97c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_onVisibilityChange:
m_PersistentCalls:
m_Calls: []
showing: 0
roomCodeText: {fileID: 5578852939709204548}
--- !u!114 &699060394989383769

m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
observeOnStart: 1
--- !u!1 &2798863108443093305
GameObject:
m_ObjectHideFlags: 0

m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 20.55
m_fontSize: 14
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontSizeMin: 14
m_fontSizeMax: 22
m_fontStyle: 2
m_HorizontalAlignment: 2
m_VerticalAlignment: 512

22
Assets/Prefabs/UI/LobbyGameCanvas.prefab


m_PersistentCalls:
m_Calls: []
showing: 0
m_ServerNameText: {fileID: 7322885418547999459}
m_lobbyNameText: {fileID: 7322885418547999459}
--- !u!225 &6749879306276389991
CanvasGroup:
m_ObjectHideFlags: 0

- component: {fileID: 2725000139462485941}
- component: {fileID: 7322885418547999459}
m_Layer: 5
m_Name: ServerText
m_Name: LobbyNameText
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

- component: {fileID: 279783410280127446}
- component: {fileID: 8630015524497407890}
m_Layer: 5
m_Name: ServerIPPanel
m_Name: RelayIPPanel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

propertyPath: m_fontSize
value: 26.15
objectReference: {fileID: 0}
- target: {fileID: 840905996306701940, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_fontSize
value: 26.15
objectReference: {fileID: 0}
- target: {fileID: 1079919869245620301, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_AnchorMax.y
value: 0

- target: {fileID: 2762366222576510419, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3246194187207366366, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_fontSize
value: 26.15
objectReference: {fileID: 0}
- target: {fileID: 3253464371495375142, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_AnchorMax.y

propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4917538085660885383, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_fontSize
value: 26.15
objectReference: {fileID: 0}
- target: {fileID: 5186258928042496532, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_fontSize
value: 26.15

- target: {fileID: 7620090743157897760, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7824963406237393945, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_fontSize
value: 26.15
objectReference: {fileID: 0}
- target: {fileID: 8020923114782963594, guid: e269788e17cbca145bf78e8971aeb223, type: 3}
propertyPath: m_fontSize

42
Assets/Prefabs/UI/LobbyUserList.prefab


m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 1
m_PresetInfoIsWorld: 0
--- !u!114 &4463750083940306577
MonoBehaviour:
m_ObjectHideFlags: 0

m_PersistentCalls:
m_Calls: []
showing: 0
m_PlayerCardSlots:
m_UserUIObjects:
- {fileID: 8208727230702623701}
- {fileID: 4503217775887893542}
- {fileID: 1646035575854440888}

m_Modifications:
- target: {fileID: 1767503274657767312, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_Name
value: UserCardPanel_4
value: UserUI_4
objectReference: {fileID: 0}
- target: {fileID: 2889154384621986752, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_AnchorMax.y

objectReference: {fileID: 0}
- target: {fileID: 3540056819003737500, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_fontSize
value: 26.15
value: 58
value: 26.15
value: 72
objectReference: {fileID: 0}
- target: {fileID: 5235189765028238254, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: showing

objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
--- !u!224 &3685075291402800769 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 3229036008637484624, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
m_PrefabInstance: {fileID: 2300164376451760337}
m_PrefabAsset: {fileID: 0}
--- !u!114 &6290668908104815487 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 5235189765028238254, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}

m_Script: {fileID: 11500000, guid: 9557a5d232068a149987bc0753800f26, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!224 &3685075291402800769 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 3229036008637484624, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
m_PrefabInstance: {fileID: 2300164376451760337}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &4128781293466929275
PrefabInstance:
m_ObjectHideFlags: 0

m_Modifications:
- target: {fileID: 1767503274657767312, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_Name
value: UserCardPanel_1
value: UserUI_1
objectReference: {fileID: 0}
- target: {fileID: 2889154384621986752, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_AnchorMax.y

propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3540056819003737500, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_fontSize
value: 58
objectReference: {fileID: 0}
- target: {fileID: 3667934756810823183, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_fontSize
value: 72
objectReference: {fileID: 0}
- target: {fileID: 5804120253616419419, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_AnchorMax.y
value: 0

m_Modifications:
- target: {fileID: 1767503274657767312, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_Name
value: UserCardPanel_3
value: UserUI_3
objectReference: {fileID: 0}
- target: {fileID: 2889154384621986752, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_AnchorMax.y

objectReference: {fileID: 0}
- target: {fileID: 3540056819003737500, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_fontSize
value: 26.15
value: 58
value: 26.15
value: 72
objectReference: {fileID: 0}
- target: {fileID: 5235189765028238254, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: showing

m_Modifications:
- target: {fileID: 1767503274657767312, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_Name
value: UserCardPanel_2
value: UserUI_2
objectReference: {fileID: 0}
- target: {fileID: 2889154384621986752, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_AnchorMax.y

objectReference: {fileID: 0}
- target: {fileID: 3540056819003737500, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: m_fontSize
value: 26.15
value: 58
value: 26.15
value: 72
objectReference: {fileID: 0}
- target: {fileID: 5235189765028238254, guid: 9c09208dc6d58f54aabb57c12071b660, type: 3}
propertyPath: showing

4
Assets/Prefabs/UI/PlayerInteractionPanel.prefab


m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 900710893788416922}
m_TargetAssemblyTypeName: LobbyRooms.UI.GameStateButtonUI, Assembly-CSharp
m_MethodName: EndServer
m_TargetAssemblyTypeName: LobbyRelaySample.UI.EndGameButtonUI, LobbyRelaySample
m_MethodName: EndGame
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}

17
Assets/Prefabs/UI/RelayCodeCanvas.prefab


m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 20.55
m_fontSize: 72
m_fontSizeBase: 45
m_fontWeight: 400
m_enableAutoSizing: 1

m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 18.2
m_fontSize: 68.3
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 1

- component: {fileID: 4102997489641105917}
- component: {fileID: 4102997489641105913}
- component: {fileID: 7676491730539518990}
- component: {fileID: 2381432589029884226}
- component: {fileID: 3340928240658051873}
- component: {fileID: 4523467532116611583}
m_Layer: 5
m_Name: RelayCodeCanvas

m_Interactable: 0
m_BlocksRaycasts: 0
m_IgnoreParentGroups: 0
--- !u!114 &2381432589029884226
--- !u!114 &3340928240658051873
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}

m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9a70bc1b6f999ee43974bbbf991a0b6a, type: 3}
m_Script: {fileID: 11500000, guid: a6e005db2e7b3d94d9409975660cf97c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_onVisibilityChange:

relayCodeText: {fileID: 8798075752901962210}
m_outputText: {fileID: 8798075752901962210}
m_codeType: 1
--- !u!114 &4523467532116611583
MonoBehaviour:
m_ObjectHideFlags: 0

OnObservedUpdated:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 2381432589029884226}
m_TargetAssemblyTypeName: LobbyRooms.UI.RelayCodeUI, LobbyRooms
- m_Target: {fileID: 3340928240658051873}
m_TargetAssemblyTypeName: LobbyRelaySample.UI.DisplayCodeUI, LobbyRelaySample
m_MethodName: ObservedUpdated
m_Mode: 0
m_Arguments:

283
Assets/Scenes/mainScene.unity


m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!224 &462074380 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 2637199315671523625, guid: f1d618bdc6f1813449d428126e640aa5, type: 3}
m_PrefabInstance: {fileID: 2637199315837045693}
m_PrefabAsset: {fileID: 0}
--- !u!114 &648562208 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 6939937855246394599, guid: f1d618bdc6f1813449d428126e640aa5, type: 3}

m_Script: {fileID: 11500000, guid: 70dfc2fde0a9ef04eaff29a138f0bf45, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &1790515943
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1790515944}
- component: {fileID: 1790515946}
- component: {fileID: 1790515945}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1790515944
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1790515943}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1839563668}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1790515945
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1790515943}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Delete all my rooms
--- !u!222 &1790515946
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1790515943}
m_CullTransparentMesh: 1
--- !u!1 &1839563667
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1839563668}
- component: {fileID: 1839563672}
- component: {fileID: 1839563671}
- component: {fileID: 1839563670}
- component: {fileID: 1839563669}
m_Layer: 5
m_Name: DeleteAllMine
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1839563668
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1839563667}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1790515944}
m_Father: {fileID: 462074380}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 0.5, y: 1}
--- !u!114 &1839563669
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1839563667}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0e7b1d59375bdf94795f339fd9395761, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1839563670
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1839563667}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 1839563671}
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 1839563669}
m_TargetAssemblyTypeName: TempDeleteAllRooms, Assembly-CSharp
m_MethodName: OnButton
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
--- !u!114 &1839563671
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1839563667}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1839563672
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1839563667}
m_CullTransparentMesh: 1
--- !u!114 &1886099429 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 3845984648666374778, guid: f1d618bdc6f1813449d428126e640aa5, type: 3}

m_Script: {fileID: 11500000, guid: 51373dc3c6ac79b4f8e36ac7c4419205, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &2637199315837045697 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 3903006825828350709, guid: f1d618bdc6f1813449d428126e640aa5, type: 3}
m_PrefabInstance: {fileID: 2637199315837045693}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 70dfc2fde0a9ef04eaff29a138f0bf45, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &2637199315837045698 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 618971913928185130, guid: f1d618bdc6f1813449d428126e640aa5, type: 3}

- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalUserObservers.Array.size
value: 3
objectReference: {fileID: 0}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.size
value: 9
objectReference: {fileID: 0}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_GameStateObservers.Array.data[0]

propertyPath: m_LocalUserObservers.Array.data[3]
value:
objectReference: {fileID: 0}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[0]
value:
objectReference: {fileID: 1886099429}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[1]
value:
objectReference: {fileID: 648562208}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[2]
value:
objectReference: {fileID: 1412109061}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[3]
value:
objectReference: {fileID: 297599733}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[4]
value:
objectReference: {fileID: 2637199315837045697}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[5]
value:
objectReference: {fileID: 2130620598}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[6]
value:
objectReference: {fileID: 2074106027}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[7]
value:
objectReference: {fileID: 309485569}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LocalLobbyObservers.Array.data[8]
value:
objectReference: {fileID: 2126854580}
- target: {fileID: 7716713811812636910, guid: f80fc24bab3dcda459a2669321e2e5a4, type: 3}
propertyPath: m_LobbyServerObservers.Array.data[0]
value:

2
Assets/Scripts/Auth/Identity.cs


/// <summary>
/// Our internal representation of a player, wrapping the data required for interfacing with the identities of that player in the services.
/// One will be created for the local player, as well as for each other member of the room.
/// One will be created for the local player, as well as for each other member of the lobby.
/// </summary>
public class Identity : IIdentity, IDisposable
{

2
Assets/Scripts/Auth/SubIdentity_Authentication.cs


AuthenticationService.Instance.SignedOut += OnSignInChange;
if (!AuthenticationService.Instance.IsSignedIn)
await AuthenticationService.Instance.SignInAnonymouslyAsync(); // Note: We don't want to sign out later, since that changes the UAS anonymous token, which would prevent the player from exiting rooms they're already in.
await AuthenticationService.Instance.SignInAnonymouslyAsync(); // Note: We don't want to sign out later, since that changes the UAS anonymous token, which would prevent the player from exiting lobbies they're already in.
onSigninComplete?.Invoke();
}

159
Assets/Scripts/Entities/GameStateManager.cs


[SerializeField]
List<LocalGameStateObserver> m_GameStateObservers = new List<LocalGameStateObserver>();
[SerializeField]
List<LobbyDataObserver> m_LobbyDataObservers = new List<LobbyDataObserver>();
List<LocalLobbyObserver> m_LocalLobbyObservers = new List<LocalLobbyObserver>();
private RoomsContentHeartbeat m_roomsContentHeartbeat = new RoomsContentHeartbeat();
private LobbyContentHeartbeat m_lobbyContentHeartbeat = new LobbyContentHeartbeat();
LobbyData m_lobbyData;
LocalLobby m_localLobby;
LobbyReadyCheck m_LobbyReadyCheck;
ReadyCheck m_ReadyCheck;
public void Awake()
{

var unused = Locator.Get;
#pragma warning restore IDE0059 // Unnecessary assignment of a value
Locator.Get.Provide(new Auth.Identity(OnAuthSignIn));
m_LobbyReadyCheck = new LobbyReadyCheck(null, 7);
m_ReadyCheck = new ReadyCheck(7);
Application.wantsToQuit += OnWantToQuit;
}

{
m_localUser.DisplayName = (string)msg;
}
else if (type == MessageType.CreateRoomRequest)
else if (type == MessageType.CreateLobbyRequest)
var createRoomData = (LobbyData)msg;
RoomsQuery.Instance.CreateRoomAsync(createRoomData.LobbyName, createRoomData.MaxPlayerCount, createRoomData.Private, (r) =>
var createLobbyData = (LocalLobby)msg;
LobbyAsyncRequests.Instance.CreateLobbyAsync(createLobbyData.LobbyName, createLobbyData.MaxPlayerCount, createLobbyData.Private, (r) =>
Lobby.ToLobbyData.Convert(r, m_lobbyData, m_localUser);
OnCreatedRoom();
Lobby.ToLocalLobby.Convert(r, m_localLobby, m_localUser);
OnCreatedLobby();
else if (type == MessageType.JoinRoomRequest)
else if (type == MessageType.JoinLobbyRequest)
LobbyInfo roomData = (LobbyInfo)msg;
RoomsQuery.Instance.JoinRoomAsync(roomData.RoomID, roomData.RoomCode, (r) =>
LobbyInfo lobbyInfo = (LobbyInfo)msg;
LobbyAsyncRequests.Instance.JoinLobbyAsync(lobbyInfo.LobbyID, lobbyInfo.LobbyCode, (r) =>
Lobby.ToLobbyData.Convert(r, m_lobbyData, m_localUser);
OnJoinedRoom();
Lobby.ToLocalLobby.Convert(r, m_localLobby, m_localUser);
OnJoinedLobby();
else if (type == MessageType.QueryRooms)
else if (type == MessageType.QueryLobbies)
RoomsQuery.Instance.RetrieveRoomListAsync(
LobbyAsyncRequests.Instance.RetrieveLobbyListAsync(
OnRefreshed(Lobby.ToLobbyData.Convert(qr));
OnRefreshed(Lobby.ToLocalLobby.Convert(qr));
}, er =>
{
long errorLong = 0;

}
else if (type == MessageType.Client_EndReadyCountdownAt)
{
m_lobbyData.TargetEndTime = (DateTime)msg;
m_localLobby.TargetEndTime = (DateTime)msg;
BeginCountDown();
}
else if (type == MessageType.ToLobby)

void Start()
{
m_lobbyData = new LobbyData
m_localLobby = new LocalLobby
};
m_localUser = new LobbyUser();
m_localUser.DisplayName = "New Player";

m_GameStateObservers.Add(gameStateObs);
}
foreach (var lobbyData in FindObjectsOfType<LobbyDataObserver>())
foreach (var localLobby in FindObjectsOfType<LocalLobbyObserver>())
if (!lobbyData.observeOnStart)
if (!localLobby.observeOnStart)
if (!m_LobbyDataObservers.Contains(lobbyData))
m_LobbyDataObservers.Add(lobbyData);
if (!m_LocalLobbyObservers.Contains(localLobby))
m_LocalLobbyObservers.Add(localLobby);
}
foreach (var lobbyUserObs in FindObjectsOfType<LobbyUserObserver>())

if (m_GameStateObservers.Count < 4)
Debug.LogWarning($"Scene has less than the default expected Game State Observers, ensure all the observers in the scene that need to watch the gameState are registered in the LocalGameStateObservers List.");
if (m_LobbyDataObservers.Count < 8)
Debug.LogWarning($"Scene has less than the default expected Lobby Data Observers, ensure all the observers in the scene that need to watch the Local Lobby Data are registered in the LobbyDataObservers List.");
if (m_LocalLobbyObservers.Count < 8)
Debug.LogWarning($"Scene has less than the default expected Local Lobby Observers, ensure all the observers in the scene that need to watch the Local Lobby are registered in the LocalLobbyObservers List.");
if (m_LocalUserObservers.Count < 3)
Debug.LogWarning($"Scene has less than the default expected Local User Observers, ensure all the observers in the scene that need to watch the gameState are registered in the LocalUserObservers List.");

gameStateObs.BeginObserving(m_localGameState);
}
foreach (var lobbyObs in m_LobbyDataObservers)
foreach (var lobbyObs in m_LocalLobbyObservers)
{
if (lobbyObs == null)
{

lobbyObs.BeginObserving(m_lobbyData);
lobbyObs.BeginObserving(m_localLobby);
}
foreach (var userObs in m_LocalUserObservers)

void SetGameState(GameState state)
{
bool isLeavingRoom = (state == GameState.Menu || state == GameState.JoinMenu) && m_localGameState.State == GameState.Lobby;
bool isLeavingLobby = (state == GameState.Menu || state == GameState.JoinMenu) && m_localGameState.State == GameState.Lobby;
if (isLeavingRoom)
OnLeftRoom();
if (isLeavingLobby)
OnLeftLobby();
void OnRefreshed(IEnumerable<LobbyData> lobbies)
void OnRefreshed(IEnumerable<LocalLobby> lobbies)
var newLobbyDict = new Dictionary<string, LobbyData>();
var newLobbyDict = new Dictionary<string, LocalLobby>();
newLobbyDict.Add(lobby.RoomID, lobby);
newLobbyDict.Add(lobby.LobbyID, lobby);
}
m_lobbyServiceData.State = LobbyServiceState.Fetched;

m_lobbyServiceData.State = LobbyServiceState.Error;
}
void OnCreatedRoom()
void OnCreatedLobby()
OnJoinedRoom();
RelayInterface.AllocateAsync(m_lobbyData.MaxPlayerCount, OnGotRelayAllocation);
OnJoinedLobby();
}
void OnGotRelayAllocation(Allocation allocationID)

void OnGotRelayCode(string relayCode)
{
m_lobbyData.RelayCode = relayCode;
m_localLobby.RelayCode = relayCode;
void OnJoinedRoom()
void OnJoinedLobby()
RoomsQuery.Instance.BeginTracking(m_lobbyData.RoomID);
m_roomsContentHeartbeat.BeginTracking(m_lobbyData, m_localUser);
LobbyAsyncRequests.Instance.BeginTracking(m_localLobby.LobbyID);
m_lobbyContentHeartbeat.BeginTracking(m_localLobby, m_localUser);
RoomsQuery.Instance.UpdatePlayerDataAsync(displayNameData, null);
LobbyAsyncRequests.Instance.UpdatePlayerDataAsync(displayNameData, null);
void OnLeftRoom()
void OnLeftLobby()
RoomsQuery.Instance.LeaveRoomAsync(m_lobbyData.RoomID, ResetLobbyData);
m_roomsContentHeartbeat.EndTracking();
RoomsQuery.Instance.EndTracking();
LobbyAsyncRequests.Instance.LeaveLobbyAsync(m_localLobby.LobbyID, ResetLocalLobby);
m_lobbyContentHeartbeat.EndTracking();
LobbyAsyncRequests.Instance.EndTracking();
}
/// <summary>

void BeginCountDown()
{
// Only start the countdown once.
if (m_lobbyData.State == LobbyState.CountDown)
if (m_localLobby.State == LobbyState.CountDown)
m_lobbyData.CountDownTime = m_lobbyData.TargetEndTime.Subtract(DateTime.Now).Seconds;
m_lobbyData.State = LobbyState.CountDown;
// We want to do all the Relay Allocation calls in quick succession, as waiting too long
// (10s) will cause the Relay server to get cleaned up by the service
RelayInterface.AllocateAsync(m_localLobby.MaxPlayerCount, OnGotRelayAllocation);
m_localLobby.CountDownTime = m_localLobby.TargetEndTime.Subtract(DateTime.Now).Seconds;
m_localLobby.State = LobbyState.CountDown;
/// <summary>
/// This is currently a countdown to Connection, once we have our transport integrated, this will be a countdown to Game Start
/// </summary>
m_LobbyReadyCheck.EndCheckingForReady();
while (m_lobbyData.CountDownTime > 0)
m_ReadyCheck.EndCheckingForReady();
while (m_localLobby.CountDownTime > 0)
if (m_lobbyData.State != LobbyState.CountDown)
if (m_localLobby.State != LobbyState.CountDown)
m_lobbyData.CountDownTime = m_lobbyData.TargetEndTime.Subtract(DateTime.Now).Seconds;
m_localLobby.CountDownTime = m_localLobby.TargetEndTime.Subtract(DateTime.Now).Seconds;
m_lobbyData.State = LobbyState.InGame;
m_localLobby.State = LobbyState.InGame;
RelayInterface.JoinAsync(m_lobbyData.RelayCode, OnJoinedGame);
// TODO TRANSPORT: Move Relay Join to Pre-Countdown, and do connection and health checks before counting down for the game start.
RelayInterface.JoinAsync(m_localLobby.RelayCode, OnJoinedRelay);
void OnJoinedGame(JoinAllocation joinData)
/// <summary>
/// Non Hosts Connect to server Here
/// </summary>
void OnJoinedRelay(JoinAllocation joinData)
m_lobbyData.RelayServer = new ServerAddress(ip, port);
m_localLobby.RelayServer = new ServerAddress(ip, port);
m_lobbyData.State = LobbyState.Lobby;
m_lobbyData.CountDownTime = 0;
m_lobbyData.RelayServer = null;
m_localLobby.State = LobbyState.Lobby;
m_localLobby.CountDownTime = 0;
m_localLobby.RelayServer = null;
m_localLobby.RelayCode = null;
SetUserLobbyState();
}

m_localUser.UserStatus = UserStatus.Lobby;
if (m_localUser.IsHost)
m_LobbyReadyCheck.BeginCheckingForReady();
m_ReadyCheck.BeginCheckingForReady();
void ResetLobbyData()
void ResetLocalLobby()
m_lobbyData.CopyObserved(new LobbyInfo(), new Dictionary<string, LobbyUser>());
m_lobbyData.CountDownTime = 0;
m_lobbyData.RelayServer = null;
m_LobbyReadyCheck.EndCheckingForReady();
m_localLobby.CopyObserved(new LobbyInfo(), new Dictionary<string, LobbyUser>());
m_localLobby.CountDownTime = 0;
m_localLobby.RelayServer = null;
m_ReadyCheck.EndCheckingForReady();
}
void OnDestroy()

bool OnWantToQuit()
{
bool canQuit = string.IsNullOrEmpty(m_lobbyData?.RoomID);
bool canQuit = string.IsNullOrEmpty(m_localLobby?.LobbyID);
StartCoroutine(LeaveBeforeQuit());
return canQuit;
}

Locator.Get.Messenger.Unsubscribe(this);
if (!string.IsNullOrEmpty(m_lobbyData?.RoomID))
if (!string.IsNullOrEmpty(m_localLobby?.LobbyID))
RoomsQuery.Instance.LeaveRoomAsync(m_lobbyData?.RoomID, null);
m_lobbyData = null;
LobbyAsyncRequests.Instance.LeaveLobbyAsync(m_localLobby?.LobbyID, null);
m_localLobby = null;
/// In builds, if we are in a room and try to send a Leave request on application quit, it won't go through if we're quitting on the same frame.
/// In builds, if we are in a lobby and try to send a Leave request on application quit, it won't go through if we're quitting on the same frame.
// TEMP: Since we're temporarily (as of 6/31/21) deleting empty rooms when we leave them manually, we'll delay a bit to ensure that happens.
// TEMP: Since we're temporarily (as of 6/31/21) deleting empty lobbies when we leave them manually, we'll delay longer to ensure that happens.
//yield return null;
yield return new WaitForSeconds(0.5f);
Application.Quit();

6
Assets/Scripts/Entities/LobbyServiceData.cs


}
/// <summary>
/// Holds the latest service data, such as the list of rooms
/// Holds data related to the Lobby service itself - The latest retrieved lobby list, the state of retrieval.
/// </summary>
[System.Serializable]
public class LobbyServiceData : Observed<LobbyServiceData>

}
}
Dictionary<string, LobbyData> m_currentLobbies = new Dictionary<string, LobbyData>();
Dictionary<string, LocalLobby> m_currentLobbies = new Dictionary<string, LocalLobby>();
public Dictionary<string, LobbyData> CurrentLobbies
public Dictionary<string, LocalLobby> CurrentLobbies
{
get { return m_currentLobbies; }
set

14
Assets/Scripts/Entities/LobbyUser.cs


{
/// <summary>
/// Current state of the user in the lobby.
/// Set as a flag to allow for the unity inspector to select multiples for various UI features.
/// This is a Flags enum to allow for the Inspector to select multiples for various UI features.
Lobby = 1, // Connected to lobby, not ready yet
Ready = 4, // User clicked ready
Connecting = 8, // User sent join request through relay
Connected = 16, // User connected through relay
Menu = 32, // User is in a menu, external to the lobby
Lobby = 1, // Connected to lobby, not ready yet
Ready = 4, // User clicked ready (Note that 2 is missing; some flags have been removed over time, but we want any serialized values to be unaffected.)
Connecting = 8, // User sent join request through Relay
Connected = 16, // User connected through Relay
Menu = 32, // User is in a menu, external to the lobby
/// Lobby Room Data for a player
/// Data for a local player instance. This will update data and is observed to know when to push local player changes to the entire lobby.
/// </summary>
[Serializable]
public class LobbyUser : Observed<LobbyUser>

542
Assets/Scripts/Entities/LocalLobby.cs

<

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace LobbyRelaySample
{
[Flags]
public enum LobbyState
{
Lobby = 1,
CountDown = 2,
InGame = 4
}
public struct LobbyInfo
{
public string RoomID { get; set; }
public string RoomCode { get; set; }
public string RelayCode { get; set; }
public string LobbyName { get; set; }
public bool Private { get; set; }
public int MaxPlayerCount { get; set; }
public LobbyState State { get; set; }
public long? AllPlayersReadyTime { get; set; }
public LobbyInfo(LobbyInfo existing)
{
RoomID = existing.RoomID;
RoomCode = existing.RoomCode;
RelayCode = existing.RelayCode;
LobbyName = existing.LobbyName;
Private = existing.Private;
MaxPlayerCount = existing.MaxPlayerCount;
State = existing.State;
AllPlayersReadyTime = existing.AllPlayersReadyTime;
}
public LobbyInfo(string roomCode)
{
RoomID = null;
RoomCode = roomCode;
RelayCode = null;
LobbyName = null;
Private = false;
MaxPlayerCount = -1;
State = LobbyState.Lobby;
AllPlayersReadyTime = null;
}
}
/// <summary>
/// The local lobby data that the game can observe
/// </summary>
[System.Serializable]
public class LobbyData : Observed<LobbyData>
{
Dictionary<string, LobbyUser> m_LobbyUsers = new Dictionary<string, LobbyUser>();
public Dictionary<string, LobbyUser> LobbyUsers => m_LobbyUsers;
#region LocalLobbyData
private LobbyInfo m_data;
public LobbyInfo Data
{
get { return new LobbyInfo(m_data); }
}
float m_CountDownTime;
public float CountDownTime
{
get { return m_CountDownTime; }
set
{
m_CountDownTime = value;
OnChanged(this);
}
}
DateTime m_TargetEndTime;
public DateTime TargetEndTime
{
get => m_TargetEndTime;
set
{
m_TargetEndTime = value;
OnChanged(this);
}
}
ServerAddress m_relayServer;
public ServerAddress RelayServer
{
get => m_relayServer;
set
{
m_relayServer = value;
OnChanged(this);
}
}
#endregion
public void AddPlayer(LobbyUser user)
{
if (m_LobbyUsers.ContainsKey(user.ID))
{
Debug.LogError($"Cant add player {user.DisplayName}({user.ID}) to room: {RoomID} twice");
return;
}
DoAddPlayer(user);
OnChanged(this);
}
private void DoAddPlayer(LobbyUser user)
{
m_LobbyUsers.Add(user.ID, user);
user.onChanged += OnChangedUser;
}
public void RemovePlayer(LobbyUser user)
{
DoRemoveUser(user);
OnChanged(this);
}
private void DoRemoveUser(LobbyUser user)
{
if (!m_LobbyUsers.ContainsKey(user.ID))
{
Debug.LogWarning($"Player {user.DisplayName}({user.ID}) does not exist in room: {RoomID}");
return;
}
m_LobbyUsers.Remove(user.ID);
user.onChanged -= OnChangedUser;
}
private void OnChangedUser(LobbyUser user)
{
OnChanged(this);
}
public string RoomID
{
get => m_data.RoomID;
set
{
m_data.RoomID = value;
OnChanged(this);
}
}
public string RoomCode
{
get => m_data.RoomCode;
set
{
m_data.RoomCode = value;
OnChanged(this);
}
}
public string RelayCode
{
get => m_data.RelayCode;
set
{
m_data.RelayCode = value;
OnChanged(this);
}
}
public string LobbyName
{
get => m_data.LobbyName;
set
{
m_data.LobbyName = value;
OnChanged(this);
}
}
public LobbyState State
{
get => m_data.State;
set
{
m_data.State = value;
OnChanged(this);
}
}
public bool Private
{
get => m_data.Private;
set
{
m_data.Private = value;
OnChanged(this);
}
}
public int PlayerCount => m_LobbyUsers.Count;
public int MaxPlayerCount
{
get => m_data.MaxPlayerCount;
set
{
m_data.MaxPlayerCount = value;
OnChanged(this);
}
}
public long? AllPlayersReadyTime => m_data.AllPlayersReadyTime;
/// <summary>
/// Checks if we have n players that have the Status.
/// -1 Count means you need all Lobbyusers
/// </summary>
/// <returns>True if enough players are of the input status.</returns>
public bool PlayersOfState(UserStatus status, int playersCount = -1)
{
var statePlayers = m_LobbyUsers.Values.Count(user => user.UserStatus == status);
if (playersCount < 0)
return statePlayers == m_LobbyUsers.Count;
return statePlayers == playersCount;
}
public void CopyObserved(LobbyInfo info, Dictionary<string, LobbyUser> oldUsers)
{
m_data = info;
if (oldUsers == null)
m_LobbyUsers = new Dictionary<string, LobbyUser>();
else
{
List<LobbyUser> toRemove = new List<LobbyUser>();
foreach (var user in m_LobbyUsers)
{
if (oldUsers.ContainsKey(user.Key))
user.Value.CopyObserved(oldUsers[user.Key]);
else
toRemove.Add(user.Value);
}
foreach (var remove in toRemove)
{
DoRemoveUser(remove);
}
foreach (var oldUser in oldUsers)
{
if (!m_LobbyUsers.ContainsKey(oldUser.Key))
DoAddPlayer(oldUser.Value);
}
}
OnChanged(this);
}
public override void CopyObserved(LobbyData oldObserved)
{
CopyObserved(oldObserved.Data, oldObserved.m_LobbyUsers);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace LobbyRelaySample
{
[Flags]
public enum LobbyState
{
Lobby = 1,
CountDown = 2,
InGame = 4
}
public struct LobbyInfo
{
public string LobbyID { get; set; }
public string LobbyCode { get; set; }
public string RelayCode { get; set; }
public string LobbyName { get; set; }
public bool Private { get; set; }
public int MaxPlayerCount { get; set; }
public LobbyState State { get; set; }
public long? AllPlayersReadyTime { get; set; }
public LobbyInfo(LobbyInfo existing)
{
LobbyID = existing.LobbyID;
LobbyCode = existing.LobbyCode;
RelayCode = existing.RelayCode;
LobbyName = existing.LobbyName;
Private = existing.Private;
MaxPlayerCount = existing.MaxPlayerCount;
State = existing.State;
AllPlayersReadyTime = existing.AllPlayersReadyTime;
}
public LobbyInfo(string lobbyCode)
{
LobbyID = null;
LobbyCode = lobbyCode;
RelayCode = null;
LobbyName = null;
Private = false;
MaxPlayerCount = -1;
State = LobbyState.Lobby;
AllPlayersReadyTime = null;
}
}
/// <summary>
/// A local wrapper around a lobby's remote data, with additional functionality for providing that data to UI elements and tracking local player objects.
/// </summary>
[System.Serializable]
public class LocalLobby : Observed<LocalLobby>
{
Dictionary<string, LobbyUser> m_LobbyUsers = new Dictionary<string, LobbyUser>();
public Dictionary<string, LobbyUser> LobbyUsers => m_LobbyUsers;
#region LocalLobbyData
private LobbyInfo m_data;
public LobbyInfo Data
{
get { return new LobbyInfo(m_data); }
}
float m_CountDownTime;
public float CountDownTime
{
get { return m_CountDownTime; }
set
{
m_CountDownTime = value;
OnChanged(this);
}
}
DateTime m_TargetEndTime;
public DateTime TargetEndTime
{
get => m_TargetEndTime;
set
{
m_TargetEndTime = value;
OnChanged(this);
}
}
ServerAddress m_relayServer;
public ServerAddress RelayServer
{
get => m_relayServer;
set
{
m_relayServer = value;
OnChanged(this);
}
}
#endregion
public void AddPlayer(LobbyUser user)
{
if (m_LobbyUsers.ContainsKey(user.ID))
{
Debug.LogError($"Cant add player {user.DisplayName}({user.ID}) to lobby: {LobbyID} twice");
return;
}
DoAddPlayer(user);
OnChanged(this);
}
private void DoAddPlayer(LobbyUser user)
{
m_LobbyUsers.Add(user.ID, user);
user.onChanged += OnChangedUser;
}
public void RemovePlayer(LobbyUser user)
{
DoRemoveUser(user);
OnChanged(this);
}
private void DoRemoveUser(LobbyUser user)
{
if (!m_LobbyUsers.ContainsKey(user.ID))
{
Debug.LogWarning($"Player {user.DisplayName}({user.ID}) does not exist in lobby: {LobbyID}");
return;
}
m_LobbyUsers.Remove(user.ID);
user.onChanged -= OnChangedUser;
}
private void OnChangedUser(LobbyUser user)
{
OnChanged(this);
}
public string LobbyID
{
get => m_data.LobbyID;
set
{
m_data.LobbyID = value;
OnChanged(this);
}
}
public string LobbyCode
{
get => m_data.LobbyCode;
set
{
m_data.LobbyCode = value;
OnChanged(this);
}
}
public string RelayCode
{
get => m_data.RelayCode;
set
{
m_data.RelayCode = value;
OnChanged(this);
}
}