From c1be3b6936fd03e765afd94babfd46e044ca96e0 Mon Sep 17 00:00:00 2001 From: Ali Sharoz Date: Wed, 8 Jan 2025 14:15:05 +0500 Subject: [PATCH] Point 3 --- Assets/Prefabs/PlayerName (TMP).prefab | 136 +++++++ Assets/Prefabs/PlayerName (TMP).prefab.meta | 7 + Assets/Prefabs/PlayerNumber.prefab | 77 ++++ Assets/Prefabs/PlayerNumber.prefab.meta | 7 + Assets/Prefabs/UI/PlayerSeatTemplate.prefab | 31 +- Assets/Scenes/CharSelect.unity | 128 +++++- .../GameState/ClientCharSelectState.cs | 91 +++-- .../GameState/ServerCharSelectState.cs | 383 ++++++++++++++---- .../Gameplay/UI/UICharSelectPlayerSeat.cs | 365 ++++++++++++++--- 9 files changed, 1023 insertions(+), 202 deletions(-) create mode 100644 Assets/Prefabs/PlayerName (TMP).prefab create mode 100644 Assets/Prefabs/PlayerName (TMP).prefab.meta create mode 100644 Assets/Prefabs/PlayerNumber.prefab create mode 100644 Assets/Prefabs/PlayerNumber.prefab.meta diff --git a/Assets/Prefabs/PlayerName (TMP).prefab b/Assets/Prefabs/PlayerName (TMP).prefab new file mode 100644 index 0000000..fe49f2b --- /dev/null +++ b/Assets/Prefabs/PlayerName (TMP).prefab @@ -0,0 +1,136 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &2512335036501734854 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6791306556250902720} + - component: {fileID: 8094484515574096654} + - component: {fileID: 7829013984713734201} + m_Layer: 0 + m_Name: PlayerName (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6791306556250902720 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2512335036501734854} + 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: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: -100} + m_SizeDelta: {x: 130, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8094484515574096654 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2512335036501734854} + m_CullTransparentMesh: 1 +--- !u!114 &7829013984713734201 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2512335036501734854} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, 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_text: Player name + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 1a8c97d4cbe5134499b26527f8609c7e, type: 2} + m_sharedMaterial: {fileID: -466885322316925189, guid: 1a8c97d4cbe5134499b26527f8609c7e, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 12 + m_fontSizeBase: 12 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 10 + m_fontSizeMax: 12 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 1 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} diff --git a/Assets/Prefabs/PlayerName (TMP).prefab.meta b/Assets/Prefabs/PlayerName (TMP).prefab.meta new file mode 100644 index 0000000..bb0000d --- /dev/null +++ b/Assets/Prefabs/PlayerName (TMP).prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c9c256cefc93f3647880ff0178ca92a7 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/PlayerNumber.prefab b/Assets/Prefabs/PlayerNumber.prefab new file mode 100644 index 0000000..06c6f63 --- /dev/null +++ b/Assets/Prefabs/PlayerNumber.prefab @@ -0,0 +1,77 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &6679836675240493281 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8756849045857746274} + - component: {fileID: 8827747123714470789} + - component: {fileID: 2175197792763547348} + m_Layer: 5 + m_Name: PlayerNumber + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8756849045857746274 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6679836675240493281} + 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: 0} + 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: 35} + m_SizeDelta: {x: 70, y: 70} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &8827747123714470789 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6679836675240493281} + m_CullTransparentMesh: 1 +--- !u!114 &2175197792763547348 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6679836675240493281} + 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: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 9e74ea5f2c75a624e9d29ced68c1faa6, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 diff --git a/Assets/Prefabs/PlayerNumber.prefab.meta b/Assets/Prefabs/PlayerNumber.prefab.meta new file mode 100644 index 0000000..7157c9c --- /dev/null +++ b/Assets/Prefabs/PlayerNumber.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7dd427a6eee98c04181e215582137e9c +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/UI/PlayerSeatTemplate.prefab b/Assets/Prefabs/UI/PlayerSeatTemplate.prefab index 6b813e7..9f90c59 100644 --- a/Assets/Prefabs/UI/PlayerSeatTemplate.prefab +++ b/Assets/Prefabs/UI/PlayerSeatTemplate.prefab @@ -31,7 +31,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 628160980191873562} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -107,7 +106,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 628160980191873562} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -185,7 +183,6 @@ RectTransform: - {fileID: 7227755882419628908} - {fileID: 2849120150865561455} m_Father: {fileID: 628160980191873562} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -261,7 +258,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2768642224677944325} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -343,7 +339,6 @@ RectTransform: - {fileID: 6895277928560741035} - {fileID: 31381581329544165} m_Father: {fileID: 7773346133266671123} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -352,7 +347,7 @@ RectTransform: m_Pivot: {x: 0.5, y: 0.5} --- !u!95 &6724969306933167588 Animator: - serializedVersion: 4 + serializedVersion: 5 m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -369,7 +364,8 @@ Animator: m_WarningMessage: m_HasTransformHierarchy: 1 m_AllowConstantClipSamplingOptimization: 1 - m_KeepAnimatorControllerStateOnDisable: 0 + m_KeepAnimatorStateOnDisable: 0 + m_WriteDefaultValuesOnDisable: 0 --- !u!1 &239969297857855374 GameObject: m_ObjectHideFlags: 0 @@ -401,7 +397,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1447857258} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0} @@ -477,7 +472,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2768642224677944325} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1} @@ -499,7 +493,7 @@ MonoBehaviour: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 979343943039640553} - m_Enabled: 1 + m_Enabled: 0 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: @@ -553,7 +547,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1447857258} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0} @@ -630,7 +623,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 628160980191873562} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -762,7 +754,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2768642224677944325} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0} @@ -843,7 +834,6 @@ RectTransform: - {fileID: 8171136458736705924} - {fileID: 3079994904646502685} m_Father: {fileID: 628160980191873562} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -919,7 +909,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 628160980191873562} - m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -941,7 +930,7 @@ MonoBehaviour: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6887953740487273603} - m_Enabled: 1 + m_Enabled: 0 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} m_Name: @@ -1054,7 +1043,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2768642224677944325} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0} @@ -1131,7 +1119,6 @@ RectTransform: m_Children: - {fileID: 628160980191873562} m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1160,8 +1147,10 @@ MonoBehaviour: m_EditorClassIdentifier: m_InactiveStateVisuals: {fileID: 1447857257} m_ActiveStateVisuals: {fileID: 5797092946621803531} - m_PlayerNumberHolder: {fileID: 4222928942078796956} - m_PlayerNameHolder: {fileID: 463572819075978806} + m_PlayerNumberHolderParent: {fileID: 7697377224375302682} + m_PlayerNameHolderParent: {fileID: 31381581329544165} + m_PlayerNumberTemplate: {fileID: 6679836675240493281, guid: 7dd427a6eee98c04181e215582137e9c, type: 3} + m_PlayerNameTemplate: {fileID: 2512335036501734854, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} m_Glow: {fileID: 763871756} m_Checkbox: {fileID: 548950178457608205} m_Button: {fileID: 7451589453558463903} @@ -1200,7 +1189,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 628160980191873562} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -1276,7 +1264,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2768642224677944325} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0} diff --git a/Assets/Scenes/CharSelect.unity b/Assets/Scenes/CharSelect.unity index a65734c..0fb00d9 100644 --- a/Assets/Scenes/CharSelect.unity +++ b/Assets/Scenes/CharSelect.unity @@ -1192,6 +1192,108 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: e72290981fe0b14469584445274082b6, type: 3} +--- !u!1001 &4620751774230532315 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 5940892340892531732} + m_Modifications: + - target: {fileID: 2512335036501734854, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_Name + value: PlayerName (TMP) (1) + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_Pivot.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_Pivot.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_AnchorMax.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_AnchorMax.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_AnchorMin.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_AnchorMin.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_SizeDelta.x + value: 130 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_SizeDelta.y + value: 20 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalRotation.x + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalRotation.y + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalRotation.z + value: -0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_AnchoredPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_AnchoredPosition.y + value: -100 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} +--- !u!224 &4620751774230532316 stripped +RectTransform: + m_CorrespondingSourceObject: {fileID: 6791306556250902720, guid: c9c256cefc93f3647880ff0178ca92a7, type: 3} + m_PrefabInstance: {fileID: 4620751774230532315} + m_PrefabAsset: {fileID: 0} --- !u!1001 &5940892340892531729 PrefabInstance: m_ObjectHideFlags: 0 @@ -1200,6 +1302,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: + - target: {fileID: 144435462024127419, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} - target: {fileID: 4921811456745109879, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} propertyPath: m_SizeDelta.x value: 0 @@ -1308,9 +1414,24 @@ PrefabInstance: propertyPath: m_Camera value: objectReference: {fileID: 1231490493} + - target: {fileID: 6909962442532760665, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6909962442666860111, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6909962443233750038, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] - m_AddedGameObjects: [] + m_AddedGameObjects: + - targetCorrespondingSourceObject: {fileID: 6540888083354289637, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} + insertIndex: -1 + addedObject: {fileID: 4620751774230532316} m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} --- !u!114 &5940892340892531730 stripped @@ -1329,6 +1450,11 @@ GameObject: m_CorrespondingSourceObject: {fileID: 5940892341882885327, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} m_PrefabInstance: {fileID: 5940892340892531729} m_PrefabAsset: {fileID: 0} +--- !u!224 &5940892340892531732 stripped +RectTransform: + m_CorrespondingSourceObject: {fileID: 6540888083354289637, guid: 463d19e34c787654c8cb7332fc58149b, type: 3} + m_PrefabInstance: {fileID: 5940892340892531729} + m_PrefabAsset: {fileID: 0} --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Gameplay/GameState/ClientCharSelectState.cs b/Assets/Scripts/Gameplay/GameState/ClientCharSelectState.cs index 79c7d23..fa8d2d5 100644 --- a/Assets/Scripts/Gameplay/GameState/ClientCharSelectState.cs +++ b/Assets/Scripts/Gameplay/GameState/ClientCharSelectState.cs @@ -8,6 +8,7 @@ using Unity.Netcode; using UnityEngine; using VContainer; using Avatar = Unity.BossRoom.Gameplay.Configuration.Avatar; +using System.Linq; namespace Unity.BossRoom.Gameplay.GameState { @@ -238,64 +239,74 @@ namespace Unity.BossRoom.Gameplay.GameState /// Which seat we're sitting in, or -1 if SeatState is Inactive void UpdateCharacterSelection(NetworkCharSelection.SeatState state, int seatIdx = -1) { - bool isNewSeat = m_LastSeatSelected != seatIdx; + if (seatIdx < -1 || seatIdx >= m_NetworkCharSelection.AvatarConfiguration.Length) + { + Debug.LogError($"Invalid seat index: {seatIdx}. Must be between 0 and {m_NetworkCharSelection.AvatarConfiguration.Length - 1}."); + return; // Prevent out-of-bounds access. + } + bool isNewSeat = m_LastSeatSelected != seatIdx; m_LastSeatSelected = seatIdx; + if (state == NetworkCharSelection.SeatState.Inactive) { + // Deactivate current character graphics when unselecting a seat if (m_CurrentCharacterGraphics) { m_CurrentCharacterGraphics.SetActive(false); } - m_ClassInfoBox.ConfigureForNoSelection(); + m_HasLocalPlayerLockedIn = false; // Reset lock-in status + ConfigureUIForLobbyMode(LobbyMode.ChooseSeat); + return; } - else - { - if (seatIdx != -1) - { - // change character preview when selecting a new seat - if (isNewSeat) - { - var selectedCharacterGraphics = GetCharacterGraphics(m_NetworkCharSelection.AvatarConfiguration[seatIdx]); - if (m_CurrentCharacterGraphics) - { - m_CurrentCharacterGraphics.SetActive(false); - } + if (seatIdx == -1) + { + Debug.LogWarning("Seat index is -1 for an active state. This should not happen."); + return; + } - selectedCharacterGraphics.SetActive(true); - m_CurrentCharacterGraphics = selectedCharacterGraphics; - m_CurrentCharacterGraphicsAnimator = m_CurrentCharacterGraphics.GetComponent(); + // Change character preview when selecting a new seat + if (isNewSeat) + { + var selectedCharacterGraphics = GetCharacterGraphics(m_NetworkCharSelection.AvatarConfiguration[seatIdx]); - m_ClassInfoBox.ConfigureForClass(m_NetworkCharSelection.AvatarConfiguration[seatIdx].CharacterClass); - } - } - if (state == NetworkCharSelection.SeatState.LockedIn && !m_HasLocalPlayerLockedIn) - { - // the local player has locked in their seat choice! Rearrange the UI appropriately - // the character should act excited - // m_CurrentCharacterGraphicsAnimator.SetTrigger(m_AnimationTriggerOnCharChosen); - ConfigureUIForLobbyMode(m_NetworkCharSelection.IsLobbyClosed.Value ? LobbyMode.LobbyEnding : LobbyMode.SeatChosen); - m_HasLocalPlayerLockedIn = true; - } - else if (m_HasLocalPlayerLockedIn && state == NetworkCharSelection.SeatState.Active) - { - // reset character seats if locked in choice was unselected - if (m_HasLocalPlayerLockedIn) - { - ConfigureUIForLobbyMode(LobbyMode.ChooseSeat); - m_ClassInfoBox.SetLockedIn(false); - m_HasLocalPlayerLockedIn = false; - } - } - else if (state == NetworkCharSelection.SeatState.Active && isNewSeat) + if (m_CurrentCharacterGraphics) { - // m_CurrentCharacterGraphicsAnimator.SetTrigger(m_AnimationTriggerOnCharSelect); + m_CurrentCharacterGraphics.SetActive(false); // Deactivate previous graphics } + + selectedCharacterGraphics.SetActive(true); // Activate new character graphics + m_CurrentCharacterGraphics = selectedCharacterGraphics; + m_CurrentCharacterGraphicsAnimator = m_CurrentCharacterGraphics.GetComponent(); + + m_ClassInfoBox.ConfigureForClass(m_NetworkCharSelection.AvatarConfiguration[seatIdx].CharacterClass); + } + + // Handle lock-in and active state changes + if (state == NetworkCharSelection.SeatState.LockedIn && !m_HasLocalPlayerLockedIn) + { + // Local player locks in their choice + ConfigureUIForLobbyMode(m_NetworkCharSelection.IsLobbyClosed.Value ? LobbyMode.LobbyEnding : LobbyMode.SeatChosen); + m_HasLocalPlayerLockedIn = true; + // m_CurrentCharacterGraphicsAnimator.SetTrigger(m_AnimationTriggerOnCharChosen); // Optional animation trigger + } + else if (state == NetworkCharSelection.SeatState.Active && m_HasLocalPlayerLockedIn) + { + // Reset if locked-in choice was unselected + ConfigureUIForLobbyMode(LobbyMode.ChooseSeat); + m_ClassInfoBox.SetLockedIn(false); + m_HasLocalPlayerLockedIn = false; + } + else if (state == NetworkCharSelection.SeatState.Active && isNewSeat) + { + // Handle animation trigger when actively selecting a new seat + // m_CurrentCharacterGraphicsAnimator.SetTrigger(m_AnimationTriggerOnCharSelect); // Optional animation trigger } } + /// /// Internal utility that sets the graphics for the eight lobby-seats (based on their current networked state) /// diff --git a/Assets/Scripts/Gameplay/GameState/ServerCharSelectState.cs b/Assets/Scripts/Gameplay/GameState/ServerCharSelectState.cs index 9c4b01e..adfe6a0 100644 --- a/Assets/Scripts/Gameplay/GameState/ServerCharSelectState.cs +++ b/Assets/Scripts/Gameplay/GameState/ServerCharSelectState.cs @@ -22,7 +22,7 @@ namespace Unity.BossRoom.Gameplay.GameState public override GameState ActiveState => GameState.CharSelect; public NetworkCharSelection networkCharSelection { get; private set; } - //public static int numOfPlayers; + Coroutine m_WaitToEndLobbyCoroutine; [Inject] @@ -62,31 +62,7 @@ namespace Unity.BossRoom.Gameplay.GameState return; } - if (newSeatIdx == -1) - { - // we can't lock in with no seat - lockedIn = false; - } - else - { - // see if someone has already locked-in that seat! If so, too late... discard this choice - foreach (NetworkCharSelection.LobbyPlayerState playerInfo in networkCharSelection.LobbyPlayers) - { - if (playerInfo.ClientId != clientId && playerInfo.SeatIdx == newSeatIdx && playerInfo.SeatState == NetworkCharSelection.SeatState.LockedIn) - { - // somebody already locked this choice in. Stop! - // Instead of granting lock request, change this player to Inactive state. - networkCharSelection.LobbyPlayers[idx] = new NetworkCharSelection.LobbyPlayerState(clientId, - networkCharSelection.LobbyPlayers[idx].PlayerName, - networkCharSelection.LobbyPlayers[idx].PlayerNumber, - NetworkCharSelection.SeatState.Inactive); - - // then early out - return; - } - } - } - + // Allow multiple players to select the same character without restrictions networkCharSelection.LobbyPlayers[idx] = new NetworkCharSelection.LobbyPlayerState(clientId, networkCharSelection.LobbyPlayers[idx].PlayerName, networkCharSelection.LobbyPlayers[idx].PlayerNumber, @@ -94,24 +70,6 @@ namespace Unity.BossRoom.Gameplay.GameState newSeatIdx, Time.time); - if (lockedIn) - { - // to help the clients visually keep track of who's in what seat, we'll "kick out" any other players - // who were also in that seat. (Those players didn't click "Ready!" fast enough, somebody else took their seat!) - for (int i = 0; i < networkCharSelection.LobbyPlayers.Count; ++i) - { - if (networkCharSelection.LobbyPlayers[i].SeatIdx == newSeatIdx && i != idx) - { - // change this player to Inactive state. - networkCharSelection.LobbyPlayers[i] = new NetworkCharSelection.LobbyPlayerState( - networkCharSelection.LobbyPlayers[i].ClientId, - networkCharSelection.LobbyPlayers[i].PlayerName, - networkCharSelection.LobbyPlayers[i].PlayerNumber, - NetworkCharSelection.SeatState.Inactive); - } - } - } - CloseLobbyIfReady(); } @@ -128,31 +86,20 @@ namespace Unity.BossRoom.Gameplay.GameState return -1; } - /// - /// Looks through all our connections and sees if everyone has locked in their choice; - /// if so, we lock in the whole lobby, save state, and begin the transition to gameplay - /// void CloseLobbyIfReady() { foreach (NetworkCharSelection.LobbyPlayerState playerInfo in networkCharSelection.LobbyPlayers) { if (playerInfo.SeatState != NetworkCharSelection.SeatState.LockedIn) - return; // nope, at least one player isn't locked in yet! + return; // at least one player isn't locked in yet! } - // everybody's ready at the same time! Lock it down! networkCharSelection.IsLobbyClosed.Value = true; - // remember our choices so the next scene can use the info SaveLobbyResults(); - - // Delay a few seconds to give the UI time to react, then switch scenes m_WaitToEndLobbyCoroutine = StartCoroutine(WaitToEndLobby()); } - /// - /// Cancels the process of closing the lobby, so that if a new player joins, they are able to chose a character. - /// void CancelCloseLobby() { if (m_WaitToEndLobbyCoroutine != null) @@ -165,7 +112,6 @@ namespace Unity.BossRoom.Gameplay.GameState void SaveLobbyResults() { int numofPlayersInLobby = networkCharSelection.LobbyPlayers.Count; - //numOfPlayers = numofPlayersInLobby; PlayerPrefs.SetInt("NumberOfLobbyPlayers", numofPlayersInLobby); Debug.Log("Number of Players in lobby are: " + numofPlayersInLobby); foreach (NetworkCharSelection.LobbyPlayerState playerInfo in networkCharSelection.LobbyPlayers) @@ -174,8 +120,6 @@ namespace Unity.BossRoom.Gameplay.GameState if (playerNetworkObject && playerNetworkObject.TryGetComponent(out PersistentPlayer persistentPlayer)) { - // pass avatar GUID to PersistentPlayer - // it'd be great to simplify this with something like a NetworkScriptableObjects :( persistentPlayer.NetworkAvatarGuidState.AvatarGuid.Value = networkCharSelection.AvatarConfiguration[playerInfo.SeatIdx].Guid.ToNetworkGuid(); } @@ -218,9 +162,7 @@ namespace Unity.BossRoom.Gameplay.GameState void OnSceneEvent(SceneEvent sceneEvent) { - // We need to filter out the event that are not a client has finished loading the scene if (sceneEvent.SceneEventType != SceneEventType.LoadComplete) return; - // When the client finishes loading the Lobby Map, we will need to Seat it SeatNewPlayer(sceneEvent.ClientId); } @@ -233,28 +175,23 @@ namespace Unity.BossRoom.Gameplay.GameState return possiblePlayerNumber; } } - // we couldn't get a Player# for this person... which means the lobby is full! return -1; } bool IsPlayerNumberAvailable(int playerNumber) { - bool found = false; foreach (NetworkCharSelection.LobbyPlayerState playerState in networkCharSelection.LobbyPlayers) { if (playerState.PlayerNumber == playerNumber) { - found = true; - break; + return false; } } - - return !found; + return true; } void SeatNewPlayer(ulong clientId) { - // If lobby is closing and waiting to start the game, cancel to allow that new player to select a character if (networkCharSelection.IsLobbyClosed.Value) { CancelCloseLobby(); @@ -266,13 +203,11 @@ namespace Unity.BossRoom.Gameplay.GameState var playerData = sessionPlayerData.Value; if (playerData.PlayerNumber == -1 || !IsPlayerNumberAvailable(playerData.PlayerNumber)) { - // If no player num already assigned or if player num is no longer available, get an available one. playerData.PlayerNumber = GetAvailablePlayerNumber(); } if (playerData.PlayerNumber == -1) { - // Sanity check. We ran out of seats... there was no room! - throw new Exception($"we shouldn't be here, connection approval should have refused this connection already for client ID {clientId} and player num {playerData.PlayerNumber}"); + throw new Exception($"No available player number for client ID {clientId}"); } networkCharSelection.LobbyPlayers.Add(new NetworkCharSelection.LobbyPlayerState(clientId, playerData.PlayerName, playerData.PlayerNumber, NetworkCharSelection.SeatState.Inactive)); @@ -282,7 +217,6 @@ namespace Unity.BossRoom.Gameplay.GameState void OnClientDisconnectCallback(ulong clientId) { - // clear this client's PlayerNumber and any associated visuals (so other players know they're gone). for (int i = 0; i < networkCharSelection.LobbyPlayers.Count; ++i) { if (networkCharSelection.LobbyPlayers[i].ClientId == clientId) @@ -294,9 +228,312 @@ namespace Unity.BossRoom.Gameplay.GameState if (!networkCharSelection.IsLobbyClosed.Value) { - // If the lobby is not already closing, close if the remaining players are all ready CloseLobbyIfReady(); } } } } + + +//using System; +//using System.Collections; +//using Unity.BossRoom.ConnectionManagement; +//using Unity.BossRoom.Gameplay.GameplayObjects; +//using Unity.BossRoom.Infrastructure; +//using Unity.Multiplayer.Samples.BossRoom; +//using Unity.Multiplayer.Samples.Utilities; +//using Unity.Netcode; +//using UnityEngine; +//using VContainer; + +//namespace Unity.BossRoom.Gameplay.GameState +//{ +// /// +// /// Server specialization of Character Select game state. +// /// +// [RequireComponent(typeof(NetcodeHooks), typeof(NetworkCharSelection))] +// public class ServerCharSelectState : GameStateBehaviour +// { +// [SerializeField] +// NetcodeHooks m_NetcodeHooks; + +// public override GameState ActiveState => GameState.CharSelect; +// public NetworkCharSelection networkCharSelection { get; private set; } +// //public static int numOfPlayers; +// Coroutine m_WaitToEndLobbyCoroutine; + +// [Inject] +// ConnectionManager m_ConnectionManager; + +// protected override void Awake() +// { +// base.Awake(); +// networkCharSelection = GetComponent(); + +// m_NetcodeHooks.OnNetworkSpawnHook += OnNetworkSpawn; +// m_NetcodeHooks.OnNetworkDespawnHook += OnNetworkDespawn; +// } + +// protected override void OnDestroy() +// { +// base.OnDestroy(); + +// if (m_NetcodeHooks) +// { +// m_NetcodeHooks.OnNetworkSpawnHook -= OnNetworkSpawn; +// m_NetcodeHooks.OnNetworkDespawnHook -= OnNetworkDespawn; +// } +// } + +// void OnClientChangedSeat(ulong clientId, int newSeatIdx, bool lockedIn) +// { +// int idx = FindLobbyPlayerIdx(clientId); +// if (idx == -1) +// { +// throw new Exception($"OnClientChangedSeat: client ID {clientId} is not a lobby player and cannot change seats! Shouldn't be here!"); +// } + +// if (networkCharSelection.IsLobbyClosed.Value) +// { +// // The user tried to change their class after everything was locked in... too late! Discard this choice +// return; +// } + +// if (newSeatIdx == -1) +// { +// // we can't lock in with no seat +// lockedIn = false; +// } +// else +// { +// // see if someone has already locked-in that seat! If so, too late... discard this choice +// foreach (NetworkCharSelection.LobbyPlayerState playerInfo in networkCharSelection.LobbyPlayers) +// { +// if (playerInfo.ClientId != clientId && playerInfo.SeatIdx == newSeatIdx && playerInfo.SeatState == NetworkCharSelection.SeatState.LockedIn) +// { +// // somebody already locked this choice in. Stop! +// // Instead of granting lock request, change this player to Inactive state. +// networkCharSelection.LobbyPlayers[idx] = new NetworkCharSelection.LobbyPlayerState(clientId, +// networkCharSelection.LobbyPlayers[idx].PlayerName, +// networkCharSelection.LobbyPlayers[idx].PlayerNumber, +// NetworkCharSelection.SeatState.Inactive); + +// // then early out +// return; +// } +// } +// } + +// networkCharSelection.LobbyPlayers[idx] = new NetworkCharSelection.LobbyPlayerState(clientId, +// networkCharSelection.LobbyPlayers[idx].PlayerName, +// networkCharSelection.LobbyPlayers[idx].PlayerNumber, +// lockedIn ? NetworkCharSelection.SeatState.LockedIn : NetworkCharSelection.SeatState.Active, +// newSeatIdx, +// Time.time); + +// if (lockedIn) +// { +// // to help the clients visually keep track of who's in what seat, we'll "kick out" any other players +// // who were also in that seat. (Those players didn't click "Ready!" fast enough, somebody else took their seat!) +// for (int i = 0; i < networkCharSelection.LobbyPlayers.Count; ++i) +// { +// if (networkCharSelection.LobbyPlayers[i].SeatIdx == newSeatIdx && i != idx) +// { +// // change this player to Inactive state. +// networkCharSelection.LobbyPlayers[i] = new NetworkCharSelection.LobbyPlayerState( +// networkCharSelection.LobbyPlayers[i].ClientId, +// networkCharSelection.LobbyPlayers[i].PlayerName, +// networkCharSelection.LobbyPlayers[i].PlayerNumber, +// NetworkCharSelection.SeatState.Inactive); +// } +// } +// } + +// CloseLobbyIfReady(); +// } + +// /// +// /// Returns the index of a client in the master LobbyPlayer list, or -1 if not found +// /// +// int FindLobbyPlayerIdx(ulong clientId) +// { +// for (int i = 0; i < networkCharSelection.LobbyPlayers.Count; ++i) +// { +// if (networkCharSelection.LobbyPlayers[i].ClientId == clientId) +// return i; +// } +// return -1; +// } + +// /// +// /// Looks through all our connections and sees if everyone has locked in their choice; +// /// if so, we lock in the whole lobby, save state, and begin the transition to gameplay +// /// +// void CloseLobbyIfReady() +// { +// foreach (NetworkCharSelection.LobbyPlayerState playerInfo in networkCharSelection.LobbyPlayers) +// { +// if (playerInfo.SeatState != NetworkCharSelection.SeatState.LockedIn) +// return; // nope, at least one player isn't locked in yet! +// } + +// // everybody's ready at the same time! Lock it down! +// networkCharSelection.IsLobbyClosed.Value = true; + +// // remember our choices so the next scene can use the info +// SaveLobbyResults(); + +// // Delay a few seconds to give the UI time to react, then switch scenes +// m_WaitToEndLobbyCoroutine = StartCoroutine(WaitToEndLobby()); +// } + +// /// +// /// Cancels the process of closing the lobby, so that if a new player joins, they are able to chose a character. +// /// +// void CancelCloseLobby() +// { +// if (m_WaitToEndLobbyCoroutine != null) +// { +// StopCoroutine(m_WaitToEndLobbyCoroutine); +// } +// networkCharSelection.IsLobbyClosed.Value = false; +// } + +// void SaveLobbyResults() +// { +// int numofPlayersInLobby = networkCharSelection.LobbyPlayers.Count; +// //numOfPlayers = numofPlayersInLobby; +// PlayerPrefs.SetInt("NumberOfLobbyPlayers", numofPlayersInLobby); +// Debug.Log("Number of Players in lobby are: " + numofPlayersInLobby); +// foreach (NetworkCharSelection.LobbyPlayerState playerInfo in networkCharSelection.LobbyPlayers) +// { +// var playerNetworkObject = NetworkManager.Singleton.SpawnManager.GetPlayerNetworkObject(playerInfo.ClientId); + +// if (playerNetworkObject && playerNetworkObject.TryGetComponent(out PersistentPlayer persistentPlayer)) +// { +// // pass avatar GUID to PersistentPlayer +// // it'd be great to simplify this with something like a NetworkScriptableObjects :( +// persistentPlayer.NetworkAvatarGuidState.AvatarGuid.Value = +// networkCharSelection.AvatarConfiguration[playerInfo.SeatIdx].Guid.ToNetworkGuid(); +// } +// } +// } + +// IEnumerator WaitToEndLobby() +// { +// yield return new WaitForSeconds(3); +// SceneLoaderWrapper.Instance.LoadScene("BossRoom", useNetworkSceneManager: true); +// } + +// public void OnNetworkDespawn() +// { +// if (NetworkManager.Singleton) +// { +// NetworkManager.Singleton.OnClientDisconnectCallback -= OnClientDisconnectCallback; +// NetworkManager.Singleton.SceneManager.OnSceneEvent -= OnSceneEvent; +// } +// if (networkCharSelection) +// { +// networkCharSelection.OnClientChangedSeat -= OnClientChangedSeat; +// } +// } + +// public void OnNetworkSpawn() +// { +// if (!NetworkManager.Singleton.IsServer) +// { +// enabled = false; +// } +// else +// { +// NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnectCallback; +// networkCharSelection.OnClientChangedSeat += OnClientChangedSeat; + +// NetworkManager.Singleton.SceneManager.OnSceneEvent += OnSceneEvent; +// } +// } + +// void OnSceneEvent(SceneEvent sceneEvent) +// { +// // We need to filter out the event that are not a client has finished loading the scene +// if (sceneEvent.SceneEventType != SceneEventType.LoadComplete) return; +// // When the client finishes loading the Lobby Map, we will need to Seat it +// SeatNewPlayer(sceneEvent.ClientId); +// } + +// int GetAvailablePlayerNumber() +// { +// for (int possiblePlayerNumber = 0; possiblePlayerNumber < m_ConnectionManager.MaxConnectedPlayers; ++possiblePlayerNumber) +// { +// if (IsPlayerNumberAvailable(possiblePlayerNumber)) +// { +// return possiblePlayerNumber; +// } +// } +// // we couldn't get a Player# for this person... which means the lobby is full! +// return -1; +// } + +// bool IsPlayerNumberAvailable(int playerNumber) +// { +// bool found = false; +// foreach (NetworkCharSelection.LobbyPlayerState playerState in networkCharSelection.LobbyPlayers) +// { +// if (playerState.PlayerNumber == playerNumber) +// { +// found = true; +// break; +// } +// } + +// return !found; +// } + +// void SeatNewPlayer(ulong clientId) +// { +// // If lobby is closing and waiting to start the game, cancel to allow that new player to select a character +// if (networkCharSelection.IsLobbyClosed.Value) +// { +// CancelCloseLobby(); +// } + +// SessionPlayerData? sessionPlayerData = SessionManager.Instance.GetPlayerData(clientId); +// if (sessionPlayerData.HasValue) +// { +// var playerData = sessionPlayerData.Value; +// if (playerData.PlayerNumber == -1 || !IsPlayerNumberAvailable(playerData.PlayerNumber)) +// { +// // If no player num already assigned or if player num is no longer available, get an available one. +// playerData.PlayerNumber = GetAvailablePlayerNumber(); +// } +// if (playerData.PlayerNumber == -1) +// { +// // Sanity check. We ran out of seats... there was no room! +// throw new Exception($"we shouldn't be here, connection approval should have refused this connection already for client ID {clientId} and player num {playerData.PlayerNumber}"); +// } + +// networkCharSelection.LobbyPlayers.Add(new NetworkCharSelection.LobbyPlayerState(clientId, playerData.PlayerName, playerData.PlayerNumber, NetworkCharSelection.SeatState.Inactive)); +// SessionManager.Instance.SetPlayerData(clientId, playerData); +// } +// } + +// void OnClientDisconnectCallback(ulong clientId) +// { +// // clear this client's PlayerNumber and any associated visuals (so other players know they're gone). +// for (int i = 0; i < networkCharSelection.LobbyPlayers.Count; ++i) +// { +// if (networkCharSelection.LobbyPlayers[i].ClientId == clientId) +// { +// networkCharSelection.LobbyPlayers.RemoveAt(i); +// break; +// } +// } + +// if (!networkCharSelection.IsLobbyClosed.Value) +// { +// // If the lobby is not already closing, close if the remaining players are all ready +// CloseLobbyIfReady(); +// } +// } +// } +//} diff --git a/Assets/Scripts/Gameplay/UI/UICharSelectPlayerSeat.cs b/Assets/Scripts/Gameplay/UI/UICharSelectPlayerSeat.cs index d79146a..59ca68b 100644 --- a/Assets/Scripts/Gameplay/UI/UICharSelectPlayerSeat.cs +++ b/Assets/Scripts/Gameplay/UI/UICharSelectPlayerSeat.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Unity.BossRoom.Gameplay.GameplayObjects.Character; using Unity.BossRoom.Gameplay.GameState; using TMPro; @@ -7,9 +8,6 @@ using UnityEngine.UI; namespace Unity.BossRoom.Gameplay.UI { - /// - /// Controls one of the eight "seats" on the character-select screen (the boxes along the bottom). - /// public class UICharSelectPlayerSeat : MonoBehaviour { [SerializeField] @@ -17,9 +15,13 @@ namespace Unity.BossRoom.Gameplay.UI [SerializeField] private GameObject m_ActiveStateVisuals; [SerializeField] - private Image m_PlayerNumberHolder; + private Transform m_PlayerNumberHolderParent; // Parent for player images [SerializeField] - private TextMeshProUGUI m_PlayerNameHolder; + private Transform m_PlayerNameHolderParent; // Parent for player names + [SerializeField] + private GameObject m_PlayerNumberTemplate; // Prefab template for player images + [SerializeField] + private GameObject m_PlayerNameTemplate; // Prefab template for player names [SerializeField] private Image m_Glow; [SerializeField] @@ -36,52 +38,135 @@ namespace Unity.BossRoom.Gameplay.UI [SerializeField] private CharacterTypeEnum m_CharacterClass; - // just a way to designate which seat we are -- the leftmost seat on the lobby UI is index 0, the next one is index 1, etc. private int m_SeatIndex; - - // playerNumber of who is sitting in this seat right now. 0-based; e.g. this is 0 for Player 1, 1 for Player 2, etc. Meaningless when m_State is Inactive (and in that case it is set to -1 for clarity) - private int m_PlayerNumber; - - // the last SeatState we were assigned + private List m_PlayerNumbers = new List(); + private List m_PlayerNames = new List(); private NetworkCharSelection.SeatState m_State; - - // once this is true, we're never clickable again! private bool m_IsDisabled; + public static event Action OnPlayerSwitchedProfile; // Event for player switching + public void Initialize(int seatIndex) { m_SeatIndex = seatIndex; m_State = NetworkCharSelection.SeatState.Inactive; - m_PlayerNumber = -1; + m_PlayerNumbers.Clear(); + m_PlayerNames.Clear(); ConfigureStateGraphics(); } - - public void SetState(NetworkCharSelection.SeatState state, int playerIndex, string playerName) + public bool IsLocked() + { + return m_State == NetworkCharSelection.SeatState.LockedIn && m_PlayerNumbers.Count > 0; + } + /// + /// Sets the state of the seat and updates the UI for the selected players. + /// + public void SetState(NetworkCharSelection.SeatState state, int playerNumber, string playerName) { - if (state == m_State && playerIndex == m_PlayerNumber) - return; // no actual changes + if (state == NetworkCharSelection.SeatState.Inactive) + { + RemovePlayer(playerNumber); + } + else + { + OnPlayerSwitchedProfile?.Invoke(playerNumber, m_SeatIndex); // Notify other seats + AddPlayer(playerNumber, playerName); + } m_State = state; - m_PlayerNumber = playerIndex; - m_PlayerNameHolder.text = playerName; - if (m_State == NetworkCharSelection.SeatState.Inactive) - m_PlayerNumber = -1; ConfigureStateGraphics(); } - public bool IsLocked() + /// + /// Adds a player's number and name to the seat. + /// + public void AddPlayer(int playerNumber, string playerName) { - return m_State == NetworkCharSelection.SeatState.LockedIn; + if (!m_PlayerNumbers.Contains(playerNumber)) + { + m_PlayerNumbers.Add(playerNumber); + m_PlayerNames.Add(playerName); + } + ConfigureStateGraphics(); } - public void SetDisableInteraction(bool disable) + /// + /// Removes a player's number and name from the seat. + /// + public void RemovePlayer(int playerNumber) { - m_Button.interactable = !disable; - m_IsDisabled = disable; + int index = m_PlayerNumbers.IndexOf(playerNumber); + if (index >= 0) + { + m_PlayerNumbers.RemoveAt(index); + m_PlayerNames.RemoveAt(index); + } + ConfigureStateGraphics(); + } - if (!disable) + private void ConfigureStateGraphics() + { + // Clear existing player images and names. + foreach (Transform child in m_PlayerNumberHolderParent) + { + Destroy(child.gameObject); + } + + foreach (Transform child in m_PlayerNameHolderParent) + { + Destroy(child.gameObject); + } + + if (m_State == NetworkCharSelection.SeatState.Inactive || m_PlayerNumbers.Count == 0) + { + m_InactiveStateVisuals.SetActive(true); + m_ActiveStateVisuals.SetActive(false); + m_Glow.gameObject.SetActive(false); + m_Checkbox.gameObject.SetActive(false); + return; + } + + m_InactiveStateVisuals.SetActive(false); + m_ActiveStateVisuals.SetActive(true); + + float playerNumberYPosition = 0f; // Starting Y-position for player images. + float playerNameYPosition = 0f; // Starting Y-position for player names. + + for (int i = 0; i < m_PlayerNumbers.Count; i++) + { + // Instantiate and position player number (image). + var playerImageObj = Instantiate(m_PlayerNumberTemplate, m_PlayerNumberHolderParent); + var playerImage = playerImageObj.GetComponent(); + playerImage.sprite = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumbers[i]].Indicator; + + // Set position of player image with Y-offset of +60 units. + RectTransform imageRect = playerImageObj.GetComponent(); + imageRect.anchoredPosition = new Vector2(imageRect.anchoredPosition.x, playerNumberYPosition); + playerNumberYPosition += 60f; // Move upward by 60 units for the next image. + + // Instantiate and position player name (text). + var playerNameObj = Instantiate(m_PlayerNameTemplate, m_PlayerNameHolderParent); + var playerNameText = playerNameObj.GetComponent(); + playerNameText.text = m_PlayerNames[i]; + playerNameText.color = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumbers[i]].Color; + + // Set position of player name with Y-offset of -20 units. + RectTransform nameRect = playerNameObj.GetComponent(); + nameRect.anchoredPosition = new Vector2(nameRect.anchoredPosition.x, playerNameYPosition); + playerNameYPosition -= 20f; // Move downward by 20 units for the next name. + } + + if (m_State == NetworkCharSelection.SeatState.LockedIn) + { + m_Glow.color = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumbers[0]].Color; + m_Glow.gameObject.SetActive(true); + m_Checkbox.gameObject.SetActive(true); + PlayLockAnim(); + } + else { - // if we were locked move to unlocked state + m_Glow.gameObject.SetActive(false); + m_Checkbox.gameObject.SetActive(false); PlayUnlockAnim(); } } @@ -104,50 +189,198 @@ namespace Unity.BossRoom.Gameplay.UI } } - private void ConfigureStateGraphics() + public void SetDisableInteraction(bool disable) { - if (m_State == NetworkCharSelection.SeatState.Inactive) - { - m_InactiveStateVisuals.SetActive(true); - m_ActiveStateVisuals.SetActive(false); - m_Glow.gameObject.SetActive(false); - m_Checkbox.gameObject.SetActive(false); - m_PlayerNameHolder.gameObject.SetActive(false); - m_Button.interactable = m_IsDisabled ? false : true; - PlayUnlockAnim(); - } - else // either active or locked-in... these states are visually very similar - { - m_InactiveStateVisuals.SetActive(false); - m_PlayerNumberHolder.sprite = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumber].Indicator; - m_ActiveStateVisuals.SetActive(true); - - m_PlayerNameHolder.gameObject.SetActive(true); - m_PlayerNameHolder.color = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumber].Color; - m_Button.interactable = m_IsDisabled ? false : true; - - if (m_State == NetworkCharSelection.SeatState.LockedIn) - { - m_Glow.color = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumber].Color; - m_Glow.gameObject.SetActive(true); - m_Checkbox.gameObject.SetActive(true); - m_Button.interactable = false; - PlayLockAnim(); - } - else - { - m_Glow.gameObject.SetActive(false); - m_Checkbox.gameObject.SetActive(false); - PlayUnlockAnim(); - } - } + m_IsDisabled = disable; } - // Called directly by Button in UI public void OnClicked() { ClientCharSelectState.Instance.OnPlayerClickedSeat(m_SeatIndex); } + private void OnEnable() + { + OnPlayerSwitchedProfile += HandlePlayerSwitched; + } + + private void OnDisable() + { + OnPlayerSwitchedProfile -= HandlePlayerSwitched; + } + + /// + /// Removes the player from this seat if they select another. + /// + private void HandlePlayerSwitched(int playerNumber, int newSeatIndex) + { + if (newSeatIndex != m_SeatIndex) + { + RemovePlayer(playerNumber); + } + } } } + + + +//using System; +//using Unity.BossRoom.Gameplay.GameplayObjects.Character; +//using Unity.BossRoom.Gameplay.GameState; +//using TMPro; +//using UnityEngine; +//using UnityEngine.UI; + +//namespace Unity.BossRoom.Gameplay.UI +//{ +// /// +// /// Controls one of the eight "seats" on the character-select screen (the boxes along the bottom). +// /// +// public class UICharSelectPlayerSeat : MonoBehaviour +// { +// [SerializeField] +// private GameObject m_InactiveStateVisuals; +// [SerializeField] +// private GameObject m_ActiveStateVisuals; +// [SerializeField] +// private Image m_PlayerNumberHolder; +// [SerializeField] +// private TextMeshProUGUI m_PlayerNameHolder; +// [SerializeField] +// private Image m_Glow; +// [SerializeField] +// private Image m_Checkbox; +// [SerializeField] +// private Button m_Button; +// [SerializeField] +// private Animator m_Animator; +// [SerializeField] +// private string m_AnimatorTriggerWhenLockedIn = "LockedIn"; +// [SerializeField] +// private string m_AnimatorTriggerWhenUnlocked = "Unlocked"; + +// [SerializeField] +// private CharacterTypeEnum m_CharacterClass; + +// // just a way to designate which seat we are -- the leftmost seat on the lobby UI is index 0, the next one is index 1, etc. +// private int m_SeatIndex; + +// // playerNumber of who is sitting in this seat right now. 0-based; e.g. this is 0 for Player 1, 1 for Player 2, etc. Meaningless when m_State is Inactive (and in that case it is set to -1 for clarity) +// private int m_PlayerNumber; + +// // the last SeatState we were assigned +// private NetworkCharSelection.SeatState m_State; + +// // once this is true, we're never clickable again! +// private bool m_IsDisabled; + +// public void Initialize(int seatIndex) +// { +// m_SeatIndex = seatIndex; +// m_State = NetworkCharSelection.SeatState.Inactive; +// m_PlayerNumber = -1; +// ConfigureStateGraphics(); +// } + +// public void SetState(NetworkCharSelection.SeatState state, int playerIndex, string playerName) +// { +// if (state == m_State && playerIndex == m_PlayerNumber) +// return; // no actual changes + +// m_State = state; +// m_PlayerNumber = playerIndex; +// m_PlayerNameHolder.text = playerName; +// if (m_State == NetworkCharSelection.SeatState.Inactive) +// m_PlayerNumber = -1; +// ConfigureStateGraphics(); +// } + +// public bool IsLocked() +// { +// return m_State == NetworkCharSelection.SeatState.LockedIn; +// } + +// public void SetDisableInteraction(bool disable) +// { +// Debug.Log("Ali Interactable False"); +// //m_Button.interactable = !disable; +// m_IsDisabled = disable; + +// if (!disable) +// { +// // if we were locked move to unlocked state +// PlayUnlockAnim(); +// } +// } + +// private void PlayLockAnim() +// { +// if (m_Animator) +// { +// m_Animator.ResetTrigger(m_AnimatorTriggerWhenUnlocked); +// m_Animator.SetTrigger(m_AnimatorTriggerWhenLockedIn); +// } +// } + +// private void PlayUnlockAnim() +// { +// if (m_Animator) +// { +// m_Animator.ResetTrigger(m_AnimatorTriggerWhenLockedIn); +// m_Animator.SetTrigger(m_AnimatorTriggerWhenUnlocked); +// } +// } + +// private void ConfigureStateGraphics() +// { +// if (m_State == NetworkCharSelection.SeatState.Inactive) +// { +// m_InactiveStateVisuals.SetActive(true); +// m_ActiveStateVisuals.SetActive(false); +// m_Glow.gameObject.SetActive(false); +// m_Checkbox.gameObject.SetActive(false); +// m_PlayerNameHolder.gameObject.SetActive(false); + +// Debug.Log("Ali Interactable False 2"); +// //m_Button.interactable = !m_IsDisabled; +// PlayUnlockAnim(); +// } +// else // either active or locked-in... these states are visually very similar +// { +// m_InactiveStateVisuals.SetActive(false); + +// m_PlayerNumberHolder.sprite = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumber].Indicator; +// m_ActiveStateVisuals.SetActive(true); + +// m_PlayerNameHolder.gameObject.SetActive(true); +// m_PlayerNameHolder.color = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumber].Color; +// //m_Button.interactable = !m_IsDisabled; +// Debug.Log("Ali Interactable False 3"); + +// if (m_State == NetworkCharSelection.SeatState.LockedIn) +// { +// m_Glow.color = ClientCharSelectState.Instance.m_IdentifiersForEachPlayerNumber[m_PlayerNumber].Color; +// m_Glow.gameObject.SetActive(true); +// m_Checkbox.gameObject.SetActive(true); +// Debug.Log("Ali Interactable False 4"); + +// //m_Button.interactable = false; +// PlayLockAnim(); +// } +// else +// { +// m_Glow.gameObject.SetActive(false); +// m_Checkbox.gameObject.SetActive(false); +// PlayUnlockAnim(); +// } +// } +// } + +// // Called directly by Button in UI +// public void OnClicked() +// { +// ClientCharSelectState.Instance.OnPlayerClickedSeat(m_SeatIndex); +// } + +// } +//}