From ff18dc8ce1b97890717c991de0f93b7dc97a7c38 Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Mon, 22 Jul 2024 21:37:47 +0100 Subject: [PATCH 1/8] Implemented a graphical player list Hotkey is configurable via the usual in-game settings screen --- NebulaModel/MultiplayerOptions.cs | 4 + NebulaNetwork/Messaging/WebSocketService.cs | 1 - NebulaWorld/MultiplayerSession.cs | 1 + NebulaWorld/NebulaWorld.csproj | 6 +- NebulaWorld/SimulatedWorld.cs | 3 + NebulaWorld/UIPlayerList/UIPlayerWindow.cs | 188 ++++++++++++++++++ .../UIPlayerList/UIStyles/BoxStyles.cs | 12 ++ .../UIPlayerList/UIStyles/DialogStyles.cs | 36 ++++ .../UIPlayerList/UIStyles/LabelStyles.cs | 34 ++++ 9 files changed, 281 insertions(+), 4 deletions(-) create mode 100644 NebulaWorld/UIPlayerList/UIPlayerWindow.cs create mode 100644 NebulaWorld/UIPlayerList/UIStyles/BoxStyles.cs create mode 100644 NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs create mode 100644 NebulaWorld/UIPlayerList/UIStyles/LabelStyles.cs diff --git a/NebulaModel/MultiplayerOptions.cs b/NebulaModel/MultiplayerOptions.cs index a9d4cf5fb..743e411d0 100644 --- a/NebulaModel/MultiplayerOptions.cs +++ b/NebulaModel/MultiplayerOptions.cs @@ -129,6 +129,10 @@ public bool StreamerMode [Description("Keyboard shortcut to toggle the chat window")] public KeyboardShortcut ChatHotkey { get; set; } = new(KeyCode.BackQuote, KeyCode.LeftAlt); + [DisplayName("Player List Hotkey")] + [Description("Keyboard shortcut to display the Connected Players Window")] + public KeyboardShortcut PlayerListHotkey { get; set; } = new(KeyCode.Tab); + [DisplayName("Auto Open Chat")] [Category("Chat")] [Description("Auto open chat window when receiving message from other players")] diff --git a/NebulaNetwork/Messaging/WebSocketService.cs b/NebulaNetwork/Messaging/WebSocketService.cs index 01521b63d..c96fb5af8 100644 --- a/NebulaNetwork/Messaging/WebSocketService.cs +++ b/NebulaNetwork/Messaging/WebSocketService.cs @@ -91,7 +91,6 @@ protected override void OnError(ErrorEventArgs e) } connections.Remove(Context.UserEndPoint.GetHashCode()); - Log.Info($"Client disconnected because of an error: {ID}, reason: {e.Exception}"); UnityDispatchQueue.RunOnMainThread(() => { diff --git a/NebulaWorld/MultiplayerSession.cs b/NebulaWorld/MultiplayerSession.cs index ad26bbcda..3b9696182 100644 --- a/NebulaWorld/MultiplayerSession.cs +++ b/NebulaWorld/MultiplayerSession.cs @@ -16,6 +16,7 @@ using NebulaWorld.Trash; using NebulaWorld.Universe; using NebulaWorld.Warning; +using UnityEngine; #endregion diff --git a/NebulaWorld/NebulaWorld.csproj b/NebulaWorld/NebulaWorld.csproj index d39b37d4d..ca630efc9 100644 --- a/NebulaWorld/NebulaWorld.csproj +++ b/NebulaWorld/NebulaWorld.csproj @@ -1,8 +1,8 @@  - - - + + + \ No newline at end of file diff --git a/NebulaWorld/SimulatedWorld.cs b/NebulaWorld/SimulatedWorld.cs index aa889feed..26b5b581a 100644 --- a/NebulaWorld/SimulatedWorld.cs +++ b/NebulaWorld/SimulatedWorld.cs @@ -20,6 +20,7 @@ using NebulaWorld.MonoBehaviours; using NebulaWorld.MonoBehaviours.Local; using NebulaWorld.MonoBehaviours.Local.Chat; +using NebulaWorld.UIPlayerList; using UnityEngine; using UnityEngine.UI; using Object = UnityEngine.Object; @@ -189,6 +190,8 @@ public void SetupInitialPlayerState() localPlayerMovement = GameMain.mainPlayer.gameObject.AddComponentIfMissing(); // ChatManager should exist continuously until the game is closed GameMain.mainPlayer.gameObject.AddComponentIfMissing(); + // Load the Player List Window + GameMain.mainPlayer.gameObject.AddComponentIfMissing(); } public static void FixPlayerAfterImport() diff --git a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs new file mode 100644 index 000000000..38bed442c --- /dev/null +++ b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs @@ -0,0 +1,188 @@ +using System; +using NebulaModel; +using NebulaModel.Logger; +using NebulaWorld.Combat; +using UnityEngine; +using Object = System.Object; + +namespace NebulaWorld.UIPlayerList +{ + public class UIPlayerWindow : MonoBehaviour + { + private const string WindowName = ""; + + private Rect windowSize = new Rect(10f, 10f, 1100f, 600f); + private Vector2 playerListScrollPosition = Vector2.zero; + + private readonly Object _lockable = new Object(); + + private bool _windowVisible; + + + public void OnGUI() + { + if (!Multiplayer.IsActive) return; + if (Multiplayer.Session.IsDedicated) return; + + try + { + if (Event.current.isKey && Event.current.keyCode == Config.Options.PlayerListHotkey.MainKey) + { + if (Event.current.type == EventType.KeyDown) + { + _windowVisible = true; + } + else + { + _windowVisible = false; + } + } + + if (!_windowVisible) + return; + + windowSize = GUI.Window(6245814, windowSize, WindowHandler, WindowName, UIStyles.DialogStyles.WindowBackgroundStyle()); + windowSize.x = (int)(Screen.width * 0.5f - windowSize.width * 0.5f); + windowSize.y = (int)(Screen.height * 0.5f - windowSize.height * 0.5f); + } + catch (Exception ex) + { + Log.Error("Error in UIPlayerWindow OnGUI"); + Log.Error(ex); + } + } + + public void WindowHandler(int id) + { + //used to track how many times a GUI element needs to be recycled in the event + // that an exception is caught + var areaBegins = 0; + var horizontalBegins = 0; + var verticalBegins = 0; + var scrollViewBegins = 0; + + var localPlayer = GameMain.mainPlayer; + + try + { + GUILayout.BeginArea(new Rect(5f, 20f, windowSize.width - 10f, windowSize.height - 55f)); areaBegins++; + GUILayout.BeginHorizontal(); horizontalBegins++; + GUILayout.Space(2); + GUILayout.Label("Online Players", UIStyles.LabelStyles.HeaderLabelStyle, new GUILayoutOption[] { GUILayout.ExpandHeight(false), GUILayout.ExpandWidth(true) }); + GUILayout.EndHorizontal(); horizontalBegins--; + + + // If the player is alone in their save, then do not draw the scoreboard proper + if (AmIAlone()) + { + GUILayout.Label("It's Just You", UIStyles.LabelStyles.CenterLabelLarge, new GUILayoutOption[] { GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true) }); + GUILayout.EndArea(); + return; + } + + GUILayout.Space(20f); + GUILayout.BeginVertical(); verticalBegins++; + + // Headers + GUILayout.BeginHorizontal(); horizontalBegins++; + GUILayout.Label("Name", UIStyles.LabelStyles.RowHeaderLabelsStyle, GUILayout.Width(300)); + GUILayout.Label("Location", UIStyles.LabelStyles.RowHeaderLabelsStyle, GUILayout.Width(600)); + GUILayout.Label("Distance", UIStyles.LabelStyles.RowHeaderLabelsStyle, GUILayout.Width(100)); + GUILayout.EndHorizontal(); horizontalBegins--; + + // Horizontal bar + GUILayout.BeginHorizontal(); horizontalBegins++; + GUILayout.Box("", GUI.skin.horizontalSlider, UIStyles.BoxStyles.HorizontalSliderStyle); + GUILayout.EndHorizontal(); horizontalBegins--; + + GUILayout.Space(10f); + + playerListScrollPosition = GUILayout.BeginScrollView(playerListScrollPosition, + GUILayout.Width(windowSize.width - 10), GUILayout.ExpandHeight(true)); scrollViewBegins++; + + lock (_lockable) + { + using (Multiplayer.Session.World.GetRemotePlayersModels(out var remotePlayersModels)) + { + foreach (var entry in remotePlayersModels) + { + var player = entry.Value; + var pName = player.Username; + var pDistanceFromLocalPlayer = ""; + var pLocation = ""; + + PlanetData pPlanet = null; + if (Multiplayer.Session.Combat.IndexByPlayerId.TryGetValue(player.PlayerId, out var index)) + { + pPlanet = GameMain.galaxy.PlanetById(Multiplayer.Session.Combat.Players[index].planetId); + } + + if (pPlanet != null) + pLocation = $"{pPlanet.displayName}"; + + if (pPlanet == null) + pLocation = "In Space"; + + var pPosition = player.PlayerTransform.position; + var distance = Vector3.Distance(localPlayer.position, pPosition); + + if (distance < 10000) + { + pDistanceFromLocalPlayer = $"{distance:0.00} m"; + } + else if (distance < 600000.0) + { + pDistanceFromLocalPlayer = $"{(distance / 40000):0.00} AU"; + } + else + { + pDistanceFromLocalPlayer = $"{(distance / 2400000.0):0.00} LY"; + } + + GUILayout.BeginHorizontal(); horizontalBegins++; + GUILayout.Label(pName, UIStyles.LabelStyles.RowLabelStyle, GUILayout.Width(300)); + GUILayout.Label(pLocation, UIStyles.LabelStyles.RowLabelStyle, GUILayout.Width(600)); + GUILayout.Label(pDistanceFromLocalPlayer, UIStyles.LabelStyles.RowLabelStyle, + GUILayout.Width(100)); + GUILayout.EndHorizontal(); horizontalBegins--; + GUILayout.Space(10f); + } + } + } + GUILayout.EndScrollView(); scrollViewBegins--; + GUILayout.EndVertical(); verticalBegins--; + GUILayout.EndArea(); areaBegins--; + } + catch (Exception e) + { + Log.Error("Error in UIPlayerWindow OnGUI while building the UI"); + Log.Error(e); + + for (var i = 1; i <= areaBegins; i++) + GUILayout.EndArea(); + + for (var i = 1; i <= horizontalBegins; i++) + GUILayout.EndHorizontal(); + + for (var i = 1; i <= verticalBegins; i++) + GUILayout.EndVertical(); + + for (var i = 1; i <= scrollViewBegins; i++) + GUILayout.EndScrollView(); + } + + } + + private bool AmIAlone() + { + var connectedPlayerCount = 0; + + using (Multiplayer.Session.World.GetRemotePlayersModels(out var remotePlayersModels)) + { + connectedPlayerCount = remotePlayersModels.Count; + } + + return connectedPlayerCount == 0; + } + } +} diff --git a/NebulaWorld/UIPlayerList/UIStyles/BoxStyles.cs b/NebulaWorld/UIPlayerList/UIStyles/BoxStyles.cs new file mode 100644 index 000000000..03d71dc7b --- /dev/null +++ b/NebulaWorld/UIPlayerList/UIStyles/BoxStyles.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +namespace NebulaWorld.UIPlayerList.UIStyles +{ + internal class BoxStyles + { + public static GUILayoutOption[] HorizontalSliderStyle => new GUILayoutOption[] + { + GUILayout.ExpandWidth(true), GUILayout.Height(1), GUILayout.MaxHeight(1) + }; + } +} diff --git a/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs b/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs new file mode 100644 index 000000000..c0677880f --- /dev/null +++ b/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs @@ -0,0 +1,36 @@ +using UnityEngine; + +namespace NebulaWorld.UIPlayerList.UIStyles +{ + internal class DialogStyles + { + public static GUIStyle WindowBackgroundStyle() + { + var width = 32; + var height = 32; + + var style = new GUIStyle(GUI.skin.box) + { + normal = new GUIStyleState() + { + background = MakeTex(width, height, new Color32(36,67,76,200)) + }, + }; + + return style; + } + + private static Texture2D MakeTex(int width, int height, Color col) + { + Color[] pixels = new Color[width * height]; + for (int i = 0; i < pixels.Length; ++i) + { + pixels[i] = col; + } + Texture2D result = new Texture2D(width, height); + result.SetPixels(pixels); + result.Apply(); + return result; + } + } +} diff --git a/NebulaWorld/UIPlayerList/UIStyles/LabelStyles.cs b/NebulaWorld/UIPlayerList/UIStyles/LabelStyles.cs new file mode 100644 index 000000000..1e4d2c3a1 --- /dev/null +++ b/NebulaWorld/UIPlayerList/UIStyles/LabelStyles.cs @@ -0,0 +1,34 @@ +using UnityEngine; + +namespace NebulaWorld.UIPlayerList.UIStyles +{ + internal class LabelStyles + { + public static GUIStyle HeaderLabelStyle = new GUIStyle(UnityEngine.GUI.skin.label) + { + alignment = TextAnchor.MiddleCenter, + fontSize = 24, + fontStyle = FontStyle.Bold + }; + + public static GUIStyle CenterLabelLarge = new GUIStyle(UnityEngine.GUI.skin.label) + { + alignment = TextAnchor.MiddleCenter, + fontSize = 42, + fontStyle = FontStyle.Bold + }; + + public static GUIStyle RowHeaderLabelsStyle = new GUIStyle(UnityEngine.GUI.skin.label) + { + alignment = TextAnchor.MiddleLeft, + fontSize = 18, + fontStyle = FontStyle.Bold + }; + + public static GUIStyle RowLabelStyle = new GUIStyle(UnityEngine.GUI.skin.label) + { + alignment = TextAnchor.MiddleLeft, + fontSize = 18 + }; + } +} From 7aa51d1b97f4c561e4feb049f5f3c4366f856ac8 Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Mon, 22 Jul 2024 21:42:01 +0100 Subject: [PATCH 2/8] Cleaned up a old Using that is no longer needed --- NebulaWorld/MultiplayerSession.cs | 1 - NebulaWorld/UIPlayerList/UIPlayerWindow.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/NebulaWorld/MultiplayerSession.cs b/NebulaWorld/MultiplayerSession.cs index 3b9696182..ad26bbcda 100644 --- a/NebulaWorld/MultiplayerSession.cs +++ b/NebulaWorld/MultiplayerSession.cs @@ -16,7 +16,6 @@ using NebulaWorld.Trash; using NebulaWorld.Universe; using NebulaWorld.Warning; -using UnityEngine; #endregion diff --git a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs index 38bed442c..045ee1cf2 100644 --- a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs +++ b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs @@ -110,7 +110,7 @@ public void WindowHandler(int id) var pName = player.Username; var pDistanceFromLocalPlayer = ""; var pLocation = ""; - + PlanetData pPlanet = null; if (Multiplayer.Session.Combat.IndexByPlayerId.TryGetValue(player.PlayerId, out var index)) { From d72baa0f5ed0b206ceab40dd20650e435748fded Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Mon, 22 Jul 2024 22:15:53 +0100 Subject: [PATCH 3/8] MakeTex texture saved to memory now --- NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs b/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs index c0677880f..1860ec7cc 100644 --- a/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs +++ b/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs @@ -4,16 +4,22 @@ namespace NebulaWorld.UIPlayerList.UIStyles { internal class DialogStyles { + // ReSharper disable once InconsistentNaming + private static Texture2D _textureMemory = null; + public static GUIStyle WindowBackgroundStyle() { var width = 32; var height = 32; + if (_textureMemory == null) + _textureMemory = MakeTex(width, height, new Color32(36, 67, 76, 200); + var style = new GUIStyle(GUI.skin.box) { normal = new GUIStyleState() { - background = MakeTex(width, height, new Color32(36,67,76,200)) + background = _textureMemory }, }; From f08e95453244738a892d4038e5db7ba2e977facb Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Wed, 24 Jul 2024 02:11:28 +0100 Subject: [PATCH 4/8] Added missing closing bracket to MakeTex call --- NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs b/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs index 1860ec7cc..f7b6a91bb 100644 --- a/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs +++ b/NebulaWorld/UIPlayerList/UIStyles/DialogStyles.cs @@ -13,7 +13,7 @@ public static GUIStyle WindowBackgroundStyle() var height = 32; if (_textureMemory == null) - _textureMemory = MakeTex(width, height, new Color32(36, 67, 76, 200); + _textureMemory = MakeTex(width, height, new Color32(36, 67, 76, 200)); var style = new GUIStyle(GUI.skin.box) { From 0eac716f6f4559b91a1daf6e0ea98729ffc0735c Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Wed, 24 Jul 2024 09:34:31 +0100 Subject: [PATCH 5/8] Changed playerwindow hotkey to F1 --- NebulaModel/MultiplayerOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NebulaModel/MultiplayerOptions.cs b/NebulaModel/MultiplayerOptions.cs index 743e411d0..6534668b6 100644 --- a/NebulaModel/MultiplayerOptions.cs +++ b/NebulaModel/MultiplayerOptions.cs @@ -131,7 +131,7 @@ public bool StreamerMode [DisplayName("Player List Hotkey")] [Description("Keyboard shortcut to display the Connected Players Window")] - public KeyboardShortcut PlayerListHotkey { get; set; } = new(KeyCode.Tab); + public KeyboardShortcut PlayerListHotkey { get; set; } = new(KeyCode.F1); [DisplayName("Auto Open Chat")] [Category("Chat")] From cf4683c50627ae87c2985b9400ee9c6cb5f39ac4 Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Wed, 24 Jul 2024 09:34:53 +0100 Subject: [PATCH 6/8] Don't display window if some other UI's are open --- NebulaWorld/UIPlayerList/UIPlayerWindow.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs index 045ee1cf2..a76a94659 100644 --- a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs +++ b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs @@ -38,7 +38,10 @@ public void OnGUI() } } - if (!_windowVisible) + if (!_windowVisible || + UIRoot.instance.uiGame.techTree.active || + UIRoot.instance.uiGame.escMenu.active || + UIRoot.instance.uiGame.dysonEditor.active) return; windowSize = GUI.Window(6245814, windowSize, WindowHandler, WindowName, UIStyles.DialogStyles.WindowBackgroundStyle()); From 2df976f025941333f14eae94eb2b4d0f5c32015b Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Wed, 24 Jul 2024 10:33:42 +0100 Subject: [PATCH 7/8] Changed hotkey and updated key detection Also ensured the window cant open if the chat window is open. --- NebulaModel/MultiplayerOptions.cs | 2 +- NebulaWorld/UIPlayerList/UIPlayerWindow.cs | 47 ++++++++++++++++------ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/NebulaModel/MultiplayerOptions.cs b/NebulaModel/MultiplayerOptions.cs index 6534668b6..0e1c88d1f 100644 --- a/NebulaModel/MultiplayerOptions.cs +++ b/NebulaModel/MultiplayerOptions.cs @@ -131,7 +131,7 @@ public bool StreamerMode [DisplayName("Player List Hotkey")] [Description("Keyboard shortcut to display the Connected Players Window")] - public KeyboardShortcut PlayerListHotkey { get; set; } = new(KeyCode.F1); + public KeyboardShortcut PlayerListHotkey { get; set; } = new(KeyCode.BackQuote); [DisplayName("Auto Open Chat")] [Category("Chat")] diff --git a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs index a76a94659..5dbc0ab49 100644 --- a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs +++ b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs @@ -1,7 +1,9 @@ using System; +using System.Linq; using NebulaModel; using NebulaModel.Logger; using NebulaWorld.Combat; +using NebulaWorld.MonoBehaviours.Local.Chat; using UnityEngine; using Object = System.Object; @@ -17,7 +19,32 @@ public class UIPlayerWindow : MonoBehaviour private readonly Object _lockable = new Object(); private bool _windowVisible; + private ChatWindow _chatWindow; + public void OnInit() + { + var parent = UIRoot.instance.uiGame.inventoryWindow.transform.parent; + var chatGo = parent.Find("Chat Window") ? parent.Find("Chat Window").gameObject : null; + _chatWindow = chatGo.transform.GetComponentInChildren(); + } + + public void Update() + { + var hasModifier = Config.Options.PlayerListHotkey.Modifiers.Any(); + + _windowVisible = false; + if (Input.GetKey(Config.Options.PlayerListHotkey.MainKey)) + { + if (Config.Options.PlayerListHotkey.Modifiers.All(Input.GetKey)) + { + // If we have no modifier but a modifier is pressed, do not progress + if (!hasModifier && Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.LeftControl) || + Input.GetKey(KeyCode.RightAlt) || Input.GetKey(KeyCode.RightControl)) return; + + _windowVisible = true; + } + } + } public void OnGUI() { @@ -26,19 +53,8 @@ public void OnGUI() try { - if (Event.current.isKey && Event.current.keyCode == Config.Options.PlayerListHotkey.MainKey) - { - if (Event.current.type == EventType.KeyDown) - { - _windowVisible = true; - } - else - { - _windowVisible = false; - } - } - - if (!_windowVisible || + if (!_windowVisible || + IsChatWindowActive() || UIRoot.instance.uiGame.techTree.active || UIRoot.instance.uiGame.escMenu.active || UIRoot.instance.uiGame.dysonEditor.active) @@ -187,5 +203,10 @@ private bool AmIAlone() return connectedPlayerCount == 0; } + + private bool IsChatWindowActive() + { + return _chatWindow != null && _chatWindow.IsActive; + } } } From 595bb196ffaa00ef83c7a14642ee075b8fea4f8c Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Wed, 24 Jul 2024 12:34:04 +0100 Subject: [PATCH 8/8] Check for Null --- NebulaWorld/UIPlayerList/UIPlayerWindow.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs index 5dbc0ab49..0917e3e64 100644 --- a/NebulaWorld/UIPlayerList/UIPlayerWindow.cs +++ b/NebulaWorld/UIPlayerList/UIPlayerWindow.cs @@ -25,7 +25,11 @@ public void OnInit() { var parent = UIRoot.instance.uiGame.inventoryWindow.transform.parent; var chatGo = parent.Find("Chat Window") ? parent.Find("Chat Window").gameObject : null; - _chatWindow = chatGo.transform.GetComponentInChildren(); + + if (chatGo != null) + { + _chatWindow = chatGo.transform.GetComponentInChildren(); + } } public void Update()