개발자용 멀티플레이 기능 추가
This commit is contained in:
@@ -49,10 +49,12 @@
|
|||||||
<Analyzer Include="C:\Program Files\Unity\Hub\Editor\6000.3.5f2\Editor\Data\Tools\BuildPipeline\Unity.SourceGenerators\Unity.UIToolkit.SourceGenerator.dll" />
|
<Analyzer Include="C:\Program Files\Unity\Hub\Editor\6000.3.5f2\Editor\Data\Tools\BuildPipeline\Unity.SourceGenerators\Unity.UIToolkit.SourceGenerator.dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Assets\Scripts\Editor\NetworkUIBuilder.cs" />
|
||||||
<Compile Include="Assets\Scripts\Editor\MonsterPrefabSetup.cs" />
|
<Compile Include="Assets\Scripts\Editor\MonsterPrefabSetup.cs" />
|
||||||
<Compile Include="Assets\FlatKit\[Render Pipeline] URP\Water\Editor\Tooltips.cs" />
|
<Compile Include="Assets\FlatKit\[Render Pipeline] URP\Water\Editor\Tooltips.cs" />
|
||||||
<Compile Include="Assets\Scripts\Editor\EnemyPortalEditor.cs" />
|
<Compile Include="Assets\Scripts\Editor\EnemyPortalEditor.cs" />
|
||||||
<Compile Include="Assets\Scripts\Editor\ObstacleSpawnerEditor.cs" />
|
<Compile Include="Assets\Scripts\Editor\ObstacleSpawnerEditor.cs" />
|
||||||
|
<Compile Include="Assets\Scripts\Editor\QuickNetworkSetupEditor.cs" />
|
||||||
<Compile Include="Assets\Scripts\Editor\IPrefabSetup.cs" />
|
<Compile Include="Assets\Scripts\Editor\IPrefabSetup.cs" />
|
||||||
<Compile Include="Assets\FlatKit\[Render Pipeline] URP\Water\Editor\WaterEditor.cs" />
|
<Compile Include="Assets\FlatKit\[Render Pipeline] URP\Water\Editor\WaterEditor.cs" />
|
||||||
<Compile Include="Assets\Scripts\Editor\TowerPopulator.cs" />
|
<Compile Include="Assets\Scripts\Editor\TowerPopulator.cs" />
|
||||||
@@ -65,7 +67,9 @@
|
|||||||
<Compile Include="Assets\Scripts\Editor\CreepPrefabSetup.cs" />
|
<Compile Include="Assets\Scripts\Editor\CreepPrefabSetup.cs" />
|
||||||
<Compile Include="Assets\Scripts\Editor\TemplateCreator.cs" />
|
<Compile Include="Assets\Scripts\Editor\TemplateCreator.cs" />
|
||||||
<Compile Include="Assets\FlatKit\Shaders\Editor\Tooltips.cs" />
|
<Compile Include="Assets\FlatKit\Shaders\Editor\Tooltips.cs" />
|
||||||
|
<Compile Include="Assets\Scripts\Editor\NetworkConnectionWindow.cs" />
|
||||||
<Compile Include="Assets\FlatKit\Shaders\Editor\StylizedSurfaceEditor.cs" />
|
<Compile Include="Assets\FlatKit\Shaders\Editor\StylizedSurfaceEditor.cs" />
|
||||||
|
<Compile Include="Assets\Scripts\Editor\NetworkConnectionHelperEditor.cs" />
|
||||||
<Compile Include="Assets\Scripts\Editor\FogOfWarVisibilitySetup.cs" />
|
<Compile Include="Assets\Scripts\Editor\FogOfWarVisibilitySetup.cs" />
|
||||||
<Compile Include="Assets\FlatKit\Shaders\Editor\MaterialPropertyExtensions.cs" />
|
<Compile Include="Assets\FlatKit\Shaders\Editor\MaterialPropertyExtensions.cs" />
|
||||||
<Compile Include="Assets\FlatKit\Shaders\Editor\TerrainEditor.cs" />
|
<Compile Include="Assets\FlatKit\Shaders\Editor\TerrainEditor.cs" />
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
<Compile Include="Assets\Scripts\AttackAction.cs" />
|
<Compile Include="Assets\Scripts\AttackAction.cs" />
|
||||||
<Compile Include="Assets\Scripts\IInteractable.cs" />
|
<Compile Include="Assets\Scripts\IInteractable.cs" />
|
||||||
<Compile Include="Assets\Scripts\ServerResourceManager.cs" />
|
<Compile Include="Assets\Scripts\ServerResourceManager.cs" />
|
||||||
|
<Compile Include="Assets\Scripts\QuickNetworkSetup.cs" />
|
||||||
<Compile Include="Assets\FlatKit\Demos\Common\Scripts\UvScroller.cs" />
|
<Compile Include="Assets\FlatKit\Demos\Common\Scripts\UvScroller.cs" />
|
||||||
<Compile Include="Assets\Data\Scripts\DataClasses\TowerDataExtensions.cs" />
|
<Compile Include="Assets\Data\Scripts\DataClasses\TowerDataExtensions.cs" />
|
||||||
<Compile Include="Assets\Scripts\GlobalTimer.cs" />
|
<Compile Include="Assets\Scripts\GlobalTimer.cs" />
|
||||||
@@ -94,6 +95,7 @@
|
|||||||
<Compile Include="Assets\Scripts\BuildingHealthBar.cs" />
|
<Compile Include="Assets\Scripts\BuildingHealthBar.cs" />
|
||||||
<Compile Include="Assets\Data\Scripts\DataClasses\CreepData.cs" />
|
<Compile Include="Assets\Data\Scripts\DataClasses\CreepData.cs" />
|
||||||
<Compile Include="Assets\Scripts\PlayerSpawnPoint.cs" />
|
<Compile Include="Assets\Scripts\PlayerSpawnPoint.cs" />
|
||||||
|
<Compile Include="Assets\Scripts\NetworkJoinUI.cs" />
|
||||||
<Compile Include="Assets\FlatKit\Demos\Common\Scripts\AutoLoadPipelineAsset.cs" />
|
<Compile Include="Assets\FlatKit\Demos\Common\Scripts\AutoLoadPipelineAsset.cs" />
|
||||||
<Compile Include="Assets\Scripts\AutoHost.cs" />
|
<Compile Include="Assets\Scripts\AutoHost.cs" />
|
||||||
<Compile Include="Assets\Scripts\MonsterAnimationController.cs" />
|
<Compile Include="Assets\Scripts\MonsterAnimationController.cs" />
|
||||||
@@ -120,6 +122,7 @@
|
|||||||
<Compile Include="Assets\Scripts\EnemyAIState.cs" />
|
<Compile Include="Assets\Scripts\EnemyAIState.cs" />
|
||||||
<Compile Include="Assets\Scripts\ShortcutNetworkStarter.cs" />
|
<Compile Include="Assets\Scripts\ShortcutNetworkStarter.cs" />
|
||||||
<Compile Include="Assets\Scripts\EquipmentData.cs" />
|
<Compile Include="Assets\Scripts\EquipmentData.cs" />
|
||||||
|
<Compile Include="Assets\Scripts\NetworkConnectionHelper.cs" />
|
||||||
<Compile Include="Assets\Scripts\NetworkConnectionHandler.cs" />
|
<Compile Include="Assets\Scripts\NetworkConnectionHandler.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -3,24 +3,38 @@ using Unity.Netcode;
|
|||||||
|
|
||||||
public class AutoHost : MonoBehaviour
|
public class AutoHost : MonoBehaviour
|
||||||
{
|
{
|
||||||
// 에디터에서만 작동하도록 설정
|
[Header("Auto Host Settings")]
|
||||||
void Start()
|
[SerializeField] private bool enableAutoHost = true;
|
||||||
|
[SerializeField] private bool onlyInEditor = true;
|
||||||
|
|
||||||
|
private void Start()
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
if (ShouldAutoStart())
|
||||||
// 1. NetworkManager가 씬에 존재하는지 확인
|
|
||||||
if (NetworkManager.Singleton != null)
|
|
||||||
{
|
{
|
||||||
// 2. 이미 서버나 클라이언트가 실행 중이 아닐 때만 실행
|
if (NetworkManager.Singleton != null)
|
||||||
if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsClient)
|
|
||||||
{
|
{
|
||||||
NetworkManager.Singleton.StartHost();
|
if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsClient)
|
||||||
Debug.Log("<color=yellow><b>[AutoHost]</b> 에디터 전용 호스트 자동 시작됨</color>");
|
{
|
||||||
|
NetworkManager.Singleton.StartHost();
|
||||||
|
Debug.Log("<color=yellow><b>[AutoHost]</b> Auto-host started</color>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("[AutoHost] NetworkManager not found!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
Debug.LogError("[AutoHost] NetworkManager를 찾을 수 없습니다!");
|
private bool ShouldAutoStart()
|
||||||
}
|
{
|
||||||
|
if (!enableAutoHost)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return !onlyInEditor;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
176
Assets/Scripts/Editor/NetworkConnectionHelperEditor.cs
Normal file
176
Assets/Scripts/Editor/NetworkConnectionHelperEditor.cs
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using Unity.Netcode;
|
||||||
|
|
||||||
|
namespace Northbound.Editor
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(NetworkConnectionHelper))]
|
||||||
|
public class NetworkConnectionHelperEditor : UnityEditor.Editor
|
||||||
|
{
|
||||||
|
private NetworkConnectionHelper _helper;
|
||||||
|
private GUIStyle _statusStyle;
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
_helper = (NetworkConnectionHelper)target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
_statusStyle = new GUIStyle(EditorStyles.boldLabel);
|
||||||
|
_statusStyle.alignment = TextAnchor.MiddleCenter;
|
||||||
|
_statusStyle.fontSize = 12;
|
||||||
|
|
||||||
|
DrawDefaultInspector();
|
||||||
|
EditorGUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawConnectionControls();
|
||||||
|
EditorGUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawStatus();
|
||||||
|
EditorGUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawQuickActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawConnectionControls()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Network Controls", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
EditorGUI.BeginDisabledGroup(IsConnected());
|
||||||
|
|
||||||
|
if (GUILayout.Button("Start Host", GUILayout.Height(30)))
|
||||||
|
{
|
||||||
|
_helper.StartHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Start Server", GUILayout.Height(30)))
|
||||||
|
{
|
||||||
|
_helper.StartServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Start Client", GUILayout.Height(30)))
|
||||||
|
{
|
||||||
|
_helper.StartClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.EndDisabledGroup();
|
||||||
|
|
||||||
|
EditorGUI.BeginDisabledGroup(!IsConnected());
|
||||||
|
|
||||||
|
if (GUILayout.Button("Disconnect", GUILayout.Height(30)))
|
||||||
|
{
|
||||||
|
_helper.Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.EndDisabledGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawStatus()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Status", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
string status = GetDetailedStatus();
|
||||||
|
Color bgColor = GetStatusColor();
|
||||||
|
|
||||||
|
var oldBgColor = GUI.backgroundColor;
|
||||||
|
GUI.backgroundColor = bgColor;
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField(status, _statusStyle, GUILayout.Height(25));
|
||||||
|
|
||||||
|
GUI.backgroundColor = oldBgColor;
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton != null && IsConnected())
|
||||||
|
{
|
||||||
|
DrawNetworkInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawNetworkInfo()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Network Information", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton.IsHost)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField($"Mode: Host");
|
||||||
|
}
|
||||||
|
else if (NetworkManager.Singleton.IsServer)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField($"Mode: Server");
|
||||||
|
}
|
||||||
|
else if (NetworkManager.Singleton.IsClient)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField($"Mode: Client");
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField($"Connected Clients: {NetworkManager.Singleton.ConnectedClients.Count}");
|
||||||
|
EditorGUILayout.LabelField($"Local Client ID: {NetworkManager.Singleton.LocalClientId}");
|
||||||
|
|
||||||
|
var transport = NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField($"Address: {transport.ConnectionData.Address}");
|
||||||
|
EditorGUILayout.LabelField($"Port: {transport.ConnectionData.Port}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawQuickActions()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Quick Actions", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Open Connection Window"))
|
||||||
|
{
|
||||||
|
NetworkConnectionWindow.ShowWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Test Connection"))
|
||||||
|
{
|
||||||
|
TestConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsConnected()
|
||||||
|
{
|
||||||
|
return NetworkManager.Singleton != null &&
|
||||||
|
(NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetDetailedStatus()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
return "NetworkManager Not Found";
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton.IsHost)
|
||||||
|
return "HOSTING";
|
||||||
|
if (NetworkManager.Singleton.IsServer)
|
||||||
|
return "SERVER RUNNING";
|
||||||
|
if (NetworkManager.Singleton.IsClient)
|
||||||
|
return "CONNECTED";
|
||||||
|
|
||||||
|
return "NOT CONNECTED";
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color GetStatusColor()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
return new Color(0.8f, 0.3f, 0.3f);
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
|
||||||
|
return new Color(0.3f, 0.8f, 0.3f);
|
||||||
|
|
||||||
|
return new Color(0.8f, 0.6f, 0.3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestConnection()
|
||||||
|
{
|
||||||
|
Debug.Log($"[NetworkConnectionHelper] Connection test - Status: {_helper.GetStatus()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 36e75e477fa8d69459450bd36b5c6878
|
||||||
295
Assets/Scripts/Editor/NetworkConnectionWindow.cs
Normal file
295
Assets/Scripts/Editor/NetworkConnectionWindow.cs
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using Unity.Netcode;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
namespace Northbound.Editor
|
||||||
|
{
|
||||||
|
public class NetworkConnectionWindow : UnityEditor.EditorWindow
|
||||||
|
{
|
||||||
|
private string _serverIP = "127.0.0.1";
|
||||||
|
private string _port = "7777";
|
||||||
|
private bool _isHost = true;
|
||||||
|
private NetworkConnectionMode _connectionMode = NetworkConnectionMode.Host;
|
||||||
|
private string _savedSettingsPath;
|
||||||
|
|
||||||
|
private enum NetworkConnectionMode
|
||||||
|
{
|
||||||
|
Host,
|
||||||
|
Client,
|
||||||
|
Server
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Window/Network/Connection Manager %#n")]
|
||||||
|
public static void ShowWindow()
|
||||||
|
{
|
||||||
|
var window = GetWindow<NetworkConnectionWindow>("Network Connection");
|
||||||
|
window.minSize = new Vector2(350, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
_savedSettingsPath = Path.Combine(Application.persistentDataPath, "NetworkConnectionSettings.json");
|
||||||
|
LoadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
EditorGUILayout.Space(10);
|
||||||
|
|
||||||
|
GUILayout.Label("Network Connection Manager", EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.Space(5);
|
||||||
|
|
||||||
|
DrawConnectionModeUI();
|
||||||
|
EditorGUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawConnectionSettings();
|
||||||
|
EditorGUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawStatusDisplay();
|
||||||
|
EditorGUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawActionButtons();
|
||||||
|
EditorGUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawSettingsButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawConnectionModeUI()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Connection Mode", EditorStyles.boldLabel);
|
||||||
|
_connectionMode = (NetworkConnectionMode)EditorGUILayout.EnumPopup("Mode", _connectionMode);
|
||||||
|
|
||||||
|
if (_connectionMode == NetworkConnectionMode.Host)
|
||||||
|
{
|
||||||
|
_isHost = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawConnectionSettings()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Connection Settings", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
if (_connectionMode == NetworkConnectionMode.Client)
|
||||||
|
{
|
||||||
|
_serverIP = EditorGUILayout.TextField("Server IP", _serverIP);
|
||||||
|
_port = EditorGUILayout.TextField("Port", _port);
|
||||||
|
}
|
||||||
|
else if (_connectionMode == NetworkConnectionMode.Host || _connectionMode == NetworkConnectionMode.Server)
|
||||||
|
{
|
||||||
|
_port = EditorGUILayout.TextField("Port", _port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUI.changed)
|
||||||
|
{
|
||||||
|
SaveSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawStatusDisplay()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Status", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
string status = GetNetworkStatus();
|
||||||
|
Color statusColor = GetStatusColor();
|
||||||
|
|
||||||
|
var oldColor = GUI.color;
|
||||||
|
GUI.color = statusColor;
|
||||||
|
EditorGUILayout.LabelField(status, EditorStyles.helpBox);
|
||||||
|
GUI.color = oldColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawActionButtons()
|
||||||
|
{
|
||||||
|
EditorGUI.BeginDisabledGroup(IsNetworkActive());
|
||||||
|
|
||||||
|
if (GUILayout.Button(_connectionMode == NetworkConnectionMode.Client ? "Connect" : "Start", GUILayout.Height(30)))
|
||||||
|
{
|
||||||
|
StartConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.EndDisabledGroup();
|
||||||
|
|
||||||
|
EditorGUI.BeginDisabledGroup(!IsNetworkActive());
|
||||||
|
|
||||||
|
if (GUILayout.Button("Disconnect", GUILayout.Height(30)))
|
||||||
|
{
|
||||||
|
Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.EndDisabledGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawSettingsButtons()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Save Settings"))
|
||||||
|
{
|
||||||
|
SaveSettings();
|
||||||
|
Debug.Log("[NetworkConnectionWindow] Settings saved.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Load Settings"))
|
||||||
|
{
|
||||||
|
LoadSettings();
|
||||||
|
Debug.Log("[NetworkConnectionWindow] Settings loaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartConnection()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("Error", "NetworkManager not found in the scene!", "OK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ushort port;
|
||||||
|
if (!ushort.TryParse(_port, out port))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("Error", "Invalid port number!", "OK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>()?.SetConnectionData(
|
||||||
|
_serverIP,
|
||||||
|
port
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (_connectionMode)
|
||||||
|
{
|
||||||
|
case NetworkConnectionMode.Host:
|
||||||
|
NetworkManager.Singleton.StartHost();
|
||||||
|
Debug.Log($"[NetworkConnectionWindow] Started Host on port {port}");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NetworkConnectionMode.Client:
|
||||||
|
NetworkManager.Singleton.StartClient();
|
||||||
|
Debug.Log($"[NetworkConnectionWindow] Started Client connecting to {_serverIP}:{port}");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NetworkConnectionMode.Server:
|
||||||
|
NetworkManager.Singleton.StartServer();
|
||||||
|
Debug.Log($"[NetworkConnectionWindow] Started Server on port {port}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Disconnect()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton != null)
|
||||||
|
{
|
||||||
|
NetworkManager.Singleton.Shutdown();
|
||||||
|
Debug.Log("[NetworkConnectionWindow] Disconnected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsNetworkActive()
|
||||||
|
{
|
||||||
|
return NetworkManager.Singleton != null &&
|
||||||
|
(NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetNetworkStatus()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
return "NetworkManager not found";
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton.IsHost)
|
||||||
|
return $"Hosting (Port: {GetActivePort()})";
|
||||||
|
if (NetworkManager.Singleton.IsServer)
|
||||||
|
return $"Server (Port: {GetActivePort()})";
|
||||||
|
if (NetworkManager.Singleton.IsClient)
|
||||||
|
return $"Client connected to {GetActiveIP()}:{GetActivePort()}";
|
||||||
|
|
||||||
|
return "Not connected";
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color GetStatusColor()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
return Color.red;
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
|
||||||
|
return new Color(0f, 0.7f, 0f);
|
||||||
|
|
||||||
|
return new Color(1f, 0.7f, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetActiveIP()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null) return "N/A";
|
||||||
|
|
||||||
|
var transport = NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
return transport.ConnectionData.Address;
|
||||||
|
}
|
||||||
|
return "N/A";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetActivePort()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null) return "N/A";
|
||||||
|
|
||||||
|
var transport = NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
return transport.ConnectionData.Port.ToString();
|
||||||
|
}
|
||||||
|
return "N/A";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string json = $"{{\"serverIP\":\"{_serverIP}\",\"port\":\"{_port}\",\"connectionMode\":{_connectionMode}}}";
|
||||||
|
File.WriteAllText(_savedSettingsPath, json);
|
||||||
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError($"[NetworkConnectionWindow] Failed to save settings: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (File.Exists(_savedSettingsPath))
|
||||||
|
{
|
||||||
|
string json = File.ReadAllText(_savedSettingsPath);
|
||||||
|
var settings = JsonUtility.FromJson<ConnectionSettings>(json);
|
||||||
|
_serverIP = settings.serverIP;
|
||||||
|
_port = settings.port;
|
||||||
|
_connectionMode = (NetworkConnectionMode)settings.connectionMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError($"[NetworkConnectionWindow] Failed to load settings: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (IsNetworkActive())
|
||||||
|
{
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Serializable]
|
||||||
|
private class ConnectionSettings
|
||||||
|
{
|
||||||
|
public string serverIP;
|
||||||
|
public string port;
|
||||||
|
public int connectionMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/Scripts/Editor/NetworkConnectionWindow.cs.meta
Normal file
2
Assets/Scripts/Editor/NetworkConnectionWindow.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b7b2610829b9bba4f801fb9d527963c9
|
||||||
176
Assets/Scripts/Editor/NetworkUIBuilder.cs
Normal file
176
Assets/Scripts/Editor/NetworkUIBuilder.cs
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace Northbound.Editor
|
||||||
|
{
|
||||||
|
public class NetworkUIBuilder
|
||||||
|
{
|
||||||
|
[MenuItem("GameObject/Network/Create Network Join UI")]
|
||||||
|
public static void CreateNetworkJoinUI()
|
||||||
|
{
|
||||||
|
Canvas canvas = FindOrCreateCanvas();
|
||||||
|
GameObject panel = CreatePanel(canvas.transform);
|
||||||
|
|
||||||
|
InputField ipInput = CreateInputField(panel.transform, "IP Input", "127.0.0.1", 150);
|
||||||
|
InputField portInput = CreateInputField(panel.transform, "Port Input", "7777", 100);
|
||||||
|
|
||||||
|
Button joinButton = CreateButton(panel.transform, "Join", new Vector2(0, -80));
|
||||||
|
Button hostButton = CreateButton(panel.transform, "Host", new Vector2(-60, -80));
|
||||||
|
Button disconnectButton = CreateButton(panel.transform, "Disconnect", new Vector2(60, -80));
|
||||||
|
|
||||||
|
Text statusText = CreateStatusText(panel.transform);
|
||||||
|
|
||||||
|
NetworkJoinUI networkJoinUI = panel.AddComponent<NetworkJoinUI>();
|
||||||
|
networkJoinUI.SetUIReferences(panel, ipInput, portInput, joinButton, hostButton, disconnectButton, statusText);
|
||||||
|
|
||||||
|
Selection.activeGameObject = panel;
|
||||||
|
Debug.Log("[NetworkUIBuilder] Network Join UI created!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Canvas FindOrCreateCanvas()
|
||||||
|
{
|
||||||
|
Canvas[] canvases = Object.FindObjectsByType<Canvas>(FindObjectsSortMode.None);
|
||||||
|
|
||||||
|
if (canvases.Length > 0)
|
||||||
|
{
|
||||||
|
return canvases[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject canvasObj = new GameObject("NetworkCanvas");
|
||||||
|
Canvas canvas = canvasObj.AddComponent<Canvas>();
|
||||||
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||||
|
canvasObj.AddComponent<CanvasScaler>();
|
||||||
|
canvasObj.AddComponent<GraphicRaycaster>();
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject CreatePanel(Transform parent)
|
||||||
|
{
|
||||||
|
GameObject panel = new GameObject("NetworkJoinPanel");
|
||||||
|
panel.transform.SetParent(parent, false);
|
||||||
|
|
||||||
|
RectTransform rect = panel.AddComponent<RectTransform>();
|
||||||
|
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.sizeDelta = new Vector2(300, 250);
|
||||||
|
rect.anchoredPosition = Vector2.zero;
|
||||||
|
|
||||||
|
Image image = panel.AddComponent<Image>();
|
||||||
|
image.color = new Color(0.1f, 0.1f, 0.1f, 0.95f);
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InputField CreateInputField(Transform parent, string name, string placeholder, float width)
|
||||||
|
{
|
||||||
|
GameObject fieldObj = new GameObject(name);
|
||||||
|
fieldObj.transform.SetParent(parent, false);
|
||||||
|
|
||||||
|
RectTransform rect = fieldObj.AddComponent<RectTransform>();
|
||||||
|
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.sizeDelta = new Vector2(width, 30);
|
||||||
|
|
||||||
|
int yPos = name.Contains("IP") ? 80 : 40;
|
||||||
|
rect.anchoredPosition = new Vector2(0, yPos);
|
||||||
|
|
||||||
|
Image bgImage = fieldObj.AddComponent<Image>();
|
||||||
|
bgImage.color = new Color(0.2f, 0.2f, 0.2f, 1f);
|
||||||
|
|
||||||
|
InputField inputField = fieldObj.AddComponent<InputField>();
|
||||||
|
inputField.textComponent = CreateTextComponent(fieldObj.transform, "");
|
||||||
|
inputField.text = placeholder;
|
||||||
|
inputField.contentType = InputField.ContentType.Standard;
|
||||||
|
|
||||||
|
Text placeholderText = CreateTextComponent(fieldObj.transform, placeholder);
|
||||||
|
placeholderText.color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
|
||||||
|
inputField.placeholder = placeholderText;
|
||||||
|
|
||||||
|
Text label = CreateTextComponent(parent, name.ToUpper());
|
||||||
|
RectTransform labelRect = label.GetComponent<RectTransform>();
|
||||||
|
labelRect.anchoredPosition = new Vector2(-width / 2 - 30, yPos);
|
||||||
|
|
||||||
|
return inputField;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Button CreateButton(Transform parent, string text, Vector2 position)
|
||||||
|
{
|
||||||
|
GameObject buttonObj = new GameObject(text + "Button");
|
||||||
|
buttonObj.transform.SetParent(parent, false);
|
||||||
|
|
||||||
|
RectTransform rect = buttonObj.AddComponent<RectTransform>();
|
||||||
|
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.sizeDelta = new Vector2(80, 30);
|
||||||
|
rect.anchoredPosition = position;
|
||||||
|
|
||||||
|
Image bgImage = buttonObj.AddComponent<Image>();
|
||||||
|
bgImage.color = new Color(0.3f, 0.5f, 0.8f, 1f);
|
||||||
|
|
||||||
|
Button button = buttonObj.AddComponent<Button>();
|
||||||
|
|
||||||
|
Text buttonText = CreateTextComponent(buttonObj.transform, text);
|
||||||
|
buttonText.alignment = TextAnchor.MiddleCenter;
|
||||||
|
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Text CreateTextComponent(Transform parent, string text)
|
||||||
|
{
|
||||||
|
GameObject textObj = new GameObject("Text");
|
||||||
|
textObj.transform.SetParent(parent, false);
|
||||||
|
|
||||||
|
RectTransform rect = textObj.AddComponent<RectTransform>();
|
||||||
|
rect.anchorMin = Vector2.zero;
|
||||||
|
rect.anchorMax = Vector2.one;
|
||||||
|
rect.offsetMin = Vector2.zero;
|
||||||
|
rect.offsetMax = Vector2.zero;
|
||||||
|
|
||||||
|
Text textComponent = textObj.AddComponent<Text>();
|
||||||
|
textComponent.text = text;
|
||||||
|
textComponent.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||||
|
textComponent.fontSize = 14;
|
||||||
|
textComponent.color = Color.white;
|
||||||
|
textComponent.alignment = TextAnchor.MiddleCenter;
|
||||||
|
|
||||||
|
return textComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Text CreateStatusText(Transform parent)
|
||||||
|
{
|
||||||
|
GameObject textObj = new GameObject("StatusText");
|
||||||
|
textObj.transform.SetParent(parent, false);
|
||||||
|
|
||||||
|
RectTransform rect = textObj.AddComponent<RectTransform>();
|
||||||
|
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||||
|
rect.sizeDelta = new Vector2(280, 30);
|
||||||
|
rect.anchoredPosition = new Vector2(0, -120);
|
||||||
|
|
||||||
|
Text textComponent = textObj.AddComponent<Text>();
|
||||||
|
textComponent.text = "Not connected";
|
||||||
|
textComponent.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||||
|
textComponent.fontSize = 12;
|
||||||
|
textComponent.color = Color.yellow;
|
||||||
|
textComponent.alignment = TextAnchor.MiddleCenter;
|
||||||
|
|
||||||
|
return textComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("GameObject/Network/Create Network Helper")]
|
||||||
|
public static void CreateNetworkHelper()
|
||||||
|
{
|
||||||
|
GameObject helperObj = new GameObject("NetworkConnectionHelper");
|
||||||
|
helperObj.AddComponent<NetworkConnectionHelper>();
|
||||||
|
|
||||||
|
Selection.activeGameObject = helperObj;
|
||||||
|
Debug.Log("[NetworkUIBuilder] Network Connection Helper created!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/Scripts/Editor/NetworkUIBuilder.cs.meta
Normal file
2
Assets/Scripts/Editor/NetworkUIBuilder.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 010611d682d1a064caa47bc3667f0675
|
||||||
93
Assets/Scripts/Editor/QuickNetworkSetupEditor.cs
Normal file
93
Assets/Scripts/Editor/QuickNetworkSetupEditor.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace Northbound.Editor
|
||||||
|
{
|
||||||
|
public class QuickNetworkSetupEditor
|
||||||
|
{
|
||||||
|
[MenuItem("Tools/Network/Quick Setup for IP Connection")]
|
||||||
|
public static void QuickSetup()
|
||||||
|
{
|
||||||
|
bool disableAutoHost = EditorUtility.DisplayDialog(
|
||||||
|
"Quick Network Setup",
|
||||||
|
"This will set up your scene for manual IP-based network connections.\n\n" +
|
||||||
|
"It will:\n" +
|
||||||
|
"- Create a NetworkConnectionHelper component\n" +
|
||||||
|
"- Disable AutoHost (to prevent auto-start)\n\n" +
|
||||||
|
"Do you want to disable AutoHost?",
|
||||||
|
"Yes, disable AutoHost",
|
||||||
|
"No, keep AutoHost"
|
||||||
|
);
|
||||||
|
|
||||||
|
CreateNetworkHelper();
|
||||||
|
|
||||||
|
if (disableAutoHost)
|
||||||
|
{
|
||||||
|
DisableAutoHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorUtility.DisplayDialog(
|
||||||
|
"Setup Complete",
|
||||||
|
"Quick network setup complete!\n\n" +
|
||||||
|
"Next steps:\n" +
|
||||||
|
"1. Open Window > Network > Connection Manager\n" +
|
||||||
|
"2. Or use the NetworkConnectionHelper in Inspector\n" +
|
||||||
|
"3. Start Host on one instance\n" +
|
||||||
|
"4. Start Client on other instances with the Host's IP",
|
||||||
|
"OK"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Tools/Network/Create Connection Helper")]
|
||||||
|
public static void CreateNetworkHelper()
|
||||||
|
{
|
||||||
|
if (Object.FindObjectOfType<NetworkConnectionHelper>() == null)
|
||||||
|
{
|
||||||
|
GameObject helperObj = new GameObject("NetworkConnectionHelper");
|
||||||
|
helperObj.AddComponent<NetworkConnectionHelper>();
|
||||||
|
Selection.activeGameObject = helperObj;
|
||||||
|
Debug.Log("[QuickNetworkSetup] NetworkConnectionHelper created");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log("[QuickNetworkSetup] NetworkConnectionHelper already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Tools/Network/Disable AutoHost")]
|
||||||
|
public static void DisableAutoHost()
|
||||||
|
{
|
||||||
|
AutoHost[] autoHosts = Object.FindObjectsByType<AutoHost>(FindObjectsSortMode.None);
|
||||||
|
if (autoHosts.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var autoHost in autoHosts)
|
||||||
|
{
|
||||||
|
autoHost.enabled = false;
|
||||||
|
}
|
||||||
|
Debug.Log($"[QuickNetworkSetup] Disabled {autoHosts.Length} AutoHost component(s)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log("[QuickNetworkSetup] No AutoHost components found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Tools/Network/Enable AutoHost")]
|
||||||
|
public static void EnableAutoHost()
|
||||||
|
{
|
||||||
|
AutoHost[] autoHosts = Object.FindObjectsByType<AutoHost>(FindObjectsSortMode.None);
|
||||||
|
if (autoHosts.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var autoHost in autoHosts)
|
||||||
|
{
|
||||||
|
autoHost.enabled = true;
|
||||||
|
}
|
||||||
|
Debug.Log($"[QuickNetworkSetup] Enabled {autoHosts.Length} AutoHost component(s)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log("[QuickNetworkSetup] No AutoHost components found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/Scripts/Editor/QuickNetworkSetupEditor.cs.meta
Normal file
2
Assets/Scripts/Editor/QuickNetworkSetupEditor.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d84f5c07a6e69614dad5178e0f994335
|
||||||
176
Assets/Scripts/NETWORK_CONNECTION_GUIDE_KO.md
Normal file
176
Assets/Scripts/NETWORK_CONNECTION_GUIDE_KO.md
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
# 네트워크 연결 기능 사용 가이드
|
||||||
|
|
||||||
|
에디터와 빌드 모두에서 IP 주소를 통해 서버에 접속할 수 있는 기능이 추가되었습니다.
|
||||||
|
|
||||||
|
## 새로 추가된 기능
|
||||||
|
|
||||||
|
### 1. 네트워크 연결 윈도우 (NetworkConnectionWindow)
|
||||||
|
GUI 기반의 전용 에디터 윈도우
|
||||||
|
|
||||||
|
**사용 방법:**
|
||||||
|
- 메뉴: `Window > Network > Connection Manager` 또는 단축키 `Ctrl+Shift+N` / `Cmd+Shift+N`
|
||||||
|
- 기능:
|
||||||
|
- 연결 모드 선택 (호스트/클라이언트/서버)
|
||||||
|
- 서버 IP와 포트 입력
|
||||||
|
- 연결 시작/중지
|
||||||
|
- 연결 상태 확인
|
||||||
|
- 연결 설정 저장/로드
|
||||||
|
|
||||||
|
### 2. 네트워크 연결 헬퍼 (NetworkConnectionHelper)
|
||||||
|
커스텀 인스펙터가 포함된 컴포넌트
|
||||||
|
|
||||||
|
**사용 방법:**
|
||||||
|
1. 씬의 게임오브젝트에 `NetworkConnectionHelper` 컴포넌트 추가
|
||||||
|
2. 인스펙터에서 설정:
|
||||||
|
- 서버 IP (클라이언트 모드용)
|
||||||
|
- 포트 번호
|
||||||
|
- 자동 시작 옵션
|
||||||
|
3. 인스펙터 버튼으로 제어:
|
||||||
|
- Start Host
|
||||||
|
- Start Server
|
||||||
|
- Start Client
|
||||||
|
- Disconnect
|
||||||
|
4. 실시간 연결 상태와 네트워크 정보 확인
|
||||||
|
|
||||||
|
### 3. 네트워크 조인 UI (NetworkJoinUI)
|
||||||
|
인게임 UI로 IP를 통한 접속 지원 (에디터/빌드 모두 작동)
|
||||||
|
|
||||||
|
**사용 방법:**
|
||||||
|
1. 메뉴에서 `GameObject > Network > Create Network Join UI` 선택
|
||||||
|
2. `J` 키로 UI 패널 토글
|
||||||
|
3. UI 버튼으로 접속:
|
||||||
|
- Join: 입력된 IP로 접속
|
||||||
|
- Host: 호스트로 시작
|
||||||
|
- Disconnect: 연결 종료
|
||||||
|
|
||||||
|
### 4. AutoHost 업데이트
|
||||||
|
에디터 모드에서 자동 호스트 시작 (설정 가능)
|
||||||
|
|
||||||
|
**사용 방법:**
|
||||||
|
- `AutoHost` 컴포넌트 확인
|
||||||
|
- 설정:
|
||||||
|
- `Enable Auto Host`: 자동 시작 활성화/비활성화
|
||||||
|
- `Only In Editor`: 에디터에서만 자동 시작 (빌드에서는 비활성화)
|
||||||
|
|
||||||
|
## 빠른 설정
|
||||||
|
|
||||||
|
### 방법 A: 퀵 설정 메뉴 사용 (추천)
|
||||||
|
```
|
||||||
|
Tools > Network > Quick Setup for IP Connection
|
||||||
|
```
|
||||||
|
이 옵션은:
|
||||||
|
- NetworkConnectionHelper 생성
|
||||||
|
- AutoHost 비활성화 (선택 사항)
|
||||||
|
|
||||||
|
### 방법 B: 수동 설정
|
||||||
|
1. `Tools > Network > Create Connection Helper`로 헬퍼 생성
|
||||||
|
2. `Tools > Network > Disable AutoHost`로 자동 시작 비활성화
|
||||||
|
|
||||||
|
## 멀티플레이어 테스트 방법
|
||||||
|
|
||||||
|
### 1. 로컬 테스트 (같은 컴퓨터)
|
||||||
|
1. 윈도우: `Window > Network > Connection Manager` 열기
|
||||||
|
2. **인스턴스 1:**
|
||||||
|
- 모드: Host 선택
|
||||||
|
- 포트: 7777 (기본값)
|
||||||
|
- "Start" 클릭
|
||||||
|
3. **인스턴스 2:**
|
||||||
|
- 모드: Client 선택
|
||||||
|
- IP: 127.0.0.1 또는 localhost
|
||||||
|
- 포트: 7777
|
||||||
|
- "Connect" 클릭
|
||||||
|
|
||||||
|
### 2. 네트워크 테스트 (같은 네트워크)
|
||||||
|
1. 호스트 컴퓨터에서 로컬 IP 확인 (cmd에서 `ipconfig` 실행)
|
||||||
|
2. **호스트:**
|
||||||
|
- Connection Manager에서 Host 모드로 시작
|
||||||
|
3. **클라이언트:**
|
||||||
|
- Connection Manager에서 Client 모드 선택
|
||||||
|
- IP: 호스트 컴퓨터의 로컬 IP (예: 192.168.1.100)
|
||||||
|
- 포트: 7777
|
||||||
|
- "Connect" 클릭
|
||||||
|
|
||||||
|
### 3. 인스펙터로 테스트
|
||||||
|
1. `NetworkConnectionHelper` 컴포넌트 추가
|
||||||
|
2. 인스펙터 버튼으로 호스트/클라이언트 시작
|
||||||
|
3. 상태와 연결 정보 확인
|
||||||
|
|
||||||
|
## 연결 모드 설명
|
||||||
|
|
||||||
|
### Host
|
||||||
|
- 서버와 클라이언트 모두 역할 수행
|
||||||
|
- 멀티플레이어 게임 호스팅
|
||||||
|
- 플레이어들이 당신의 IP로 접속
|
||||||
|
|
||||||
|
### Client
|
||||||
|
- 기존 서버에 접속
|
||||||
|
- 서버 IP 주소 필요
|
||||||
|
|
||||||
|
### Server
|
||||||
|
- 전용 서버 모드 (플레이어 없음)
|
||||||
|
- 전용 서버용
|
||||||
|
|
||||||
|
## 네트워크 정보 표시
|
||||||
|
|
||||||
|
모든 연결 방법에서 다음을 표시:
|
||||||
|
- 현재 모드 (호스트/클라이언트/서버)
|
||||||
|
- 연결 상태
|
||||||
|
- IP 주소와 포트
|
||||||
|
- 접속된 클라이언트 수
|
||||||
|
- 로컬 클라이언트 ID
|
||||||
|
|
||||||
|
## 팁
|
||||||
|
|
||||||
|
1. **로컬 테스트:**
|
||||||
|
- `127.0.0.1` 또는 `localhost` 사용
|
||||||
|
- 같은 네트워크에서 테스트할 때 로컬 IP 사용
|
||||||
|
|
||||||
|
2. **기본 포트:**
|
||||||
|
- 기본 포트는 `7777`
|
||||||
|
- 연결 컴포넌트 설정에서 변경 가능
|
||||||
|
|
||||||
|
3. **방화벽:**
|
||||||
|
- 네트워크 연결을 위해 포트 개방 필요
|
||||||
|
- Windows 방화벽이 연결을 차단할 수 있음
|
||||||
|
|
||||||
|
4. **여러 에디터 인스턴스:**
|
||||||
|
- Unity의 멀티플레이 툴 사용
|
||||||
|
- 또는 여러 빌드 실행
|
||||||
|
|
||||||
|
## 기존 시스템과의 호환성
|
||||||
|
|
||||||
|
새 기능들은 기존 시스템과 통합:
|
||||||
|
- 플레이어 스폰은 `NetworkConnectionHandler`가 자동 처리
|
||||||
|
- 연결 승인은 `NetworkConnectionHandler`가 담당
|
||||||
|
- 기존 멀티플레이어 시스템과 호환
|
||||||
|
- 기존 코드 수정 불필요
|
||||||
|
|
||||||
|
## 파일 목록
|
||||||
|
|
||||||
|
### 새로 생성된 파일
|
||||||
|
- `Assets/Scripts/NetworkConnectionHelper.cs` - 네트워크 헬퍼 컴포넌트
|
||||||
|
- `Assets/Scripts/NetworkJoinUI.cs` - 인게임 연결 UI
|
||||||
|
- `Assets/Scripts/QuickNetworkSetup.cs` - 빠른 설정 스크립트
|
||||||
|
- `Assets/Scripts/Editor/NetworkConnectionWindow.cs` - 연결 관리자 윈도우
|
||||||
|
- `Assets/Scripts/Editor/NetworkConnectionHelperEditor.cs` - 헬퍼 커스텀 인스펙터
|
||||||
|
- `Assets/Scripts/Editor/NetworkUIBuilder.cs` - UI 생성 도구
|
||||||
|
- `Assets/Scripts/Editor/QuickNetworkSetupEditor.cs` - 빠른 설정 에디터 도구
|
||||||
|
|
||||||
|
### 수정된 파일
|
||||||
|
- `Assets/Scripts/AutoHost.cs` - 설정 가능한 옵션 추가
|
||||||
|
|
||||||
|
## 문제 해결
|
||||||
|
|
||||||
|
### 연결 실패 시
|
||||||
|
1. IP 주소와 포트 번호 확인
|
||||||
|
2. 방화벽 설정 확인
|
||||||
|
3. 같은 네트워크에 있는지 확인
|
||||||
|
4. 호스트가 먼저 실행 중인지 확인
|
||||||
|
|
||||||
|
### 자동 시작 비활성화 방법
|
||||||
|
1. `Tools > Network > Disable AutoHost` 선택
|
||||||
|
2. 또는 `AutoHost` 컴포넌트의 `Enable Auto Host` 체크 해제
|
||||||
|
|
||||||
|
### UI가 보이지 않을 때
|
||||||
|
1. `J` 키 눌러 토글
|
||||||
|
2. 또는 인스펙터에서 `NetworkJoinUI` 활성화 확인
|
||||||
7
Assets/Scripts/NETWORK_CONNECTION_GUIDE_KO.md.meta
Normal file
7
Assets/Scripts/NETWORK_CONNECTION_GUIDE_KO.md.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9e44a64498019a7468946f609fb954cd
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
137
Assets/Scripts/NETWORK_CONNECTION_README.md
Normal file
137
Assets/Scripts/NETWORK_CONNECTION_README.md
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
# Network Connection Features
|
||||||
|
|
||||||
|
This project provides multiple ways to connect to multiplayer servers by IP address, both in the editor and in standalone builds.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### 1. Editor Window (NetworkConnectionWindow)
|
||||||
|
A dedicated Editor window for managing network connections with a GUI.
|
||||||
|
|
||||||
|
**How to Use:**
|
||||||
|
- Open via: `Window > Network > Connection Manager` or press `Ctrl+Shift+N` / `Cmd+Shift+N`
|
||||||
|
- Features:
|
||||||
|
- Select connection mode (Host/Client/Server)
|
||||||
|
- Enter server IP and port
|
||||||
|
- Start/Stop network connections
|
||||||
|
- View connection status
|
||||||
|
- Save/load connection settings
|
||||||
|
|
||||||
|
### 2. NetworkConnectionHelper Component
|
||||||
|
A MonoBehaviour component with custom inspector for quick network control.
|
||||||
|
|
||||||
|
**How to Use:**
|
||||||
|
1. Add `NetworkConnectionHelper` component to any GameObject in your scene
|
||||||
|
2. Configure settings in Inspector:
|
||||||
|
- Server IP (for client mode)
|
||||||
|
- Port
|
||||||
|
- Auto-start options
|
||||||
|
3. Use inspector buttons to:
|
||||||
|
- Start Host
|
||||||
|
- Start Server
|
||||||
|
- Start Client
|
||||||
|
- Disconnect
|
||||||
|
4. View real-time connection status and network info
|
||||||
|
|
||||||
|
### 3. NetworkJoinUI Component
|
||||||
|
In-game UI for connecting to servers by IP (works in both editor and standalone builds).
|
||||||
|
|
||||||
|
**How to Use:**
|
||||||
|
1. Create UI elements:
|
||||||
|
- InputField for IP address
|
||||||
|
- InputField for port
|
||||||
|
- Buttons: Join, Host, Disconnect
|
||||||
|
- Text for status display
|
||||||
|
2. Add `NetworkJoinUI` component to a GameObject
|
||||||
|
3. Assign UI references in Inspector
|
||||||
|
4. Press `J` key (default) to toggle the UI panel
|
||||||
|
5. Connect using the UI buttons
|
||||||
|
|
||||||
|
### 4. AutoHost Component (Updated)
|
||||||
|
Auto-starts as host in editor mode (configurable).
|
||||||
|
|
||||||
|
**How to Use:**
|
||||||
|
- Add `AutoHost` component to any GameObject
|
||||||
|
- Settings:
|
||||||
|
- `Enable Auto Host`: Enable/disable auto-start
|
||||||
|
- `Only In Editor`: Only auto-start in editor (not in standalone builds)
|
||||||
|
|
||||||
|
## Setup Instructions
|
||||||
|
|
||||||
|
### For Editor Testing:
|
||||||
|
|
||||||
|
**Option A: Using Editor Window (Recommended)**
|
||||||
|
1. Open `Window > Network > Connection Manager`
|
||||||
|
2. Select mode: `Host` or `Client`
|
||||||
|
3. Enter IP/port if needed
|
||||||
|
4. Click `Start` or `Connect`
|
||||||
|
|
||||||
|
**Option B: Using NetworkConnectionHelper**
|
||||||
|
1. Add `NetworkConnectionHelper` component to your scene
|
||||||
|
2. Use Inspector buttons to control connections
|
||||||
|
3. For auto-start on play, enable `Auto Start As Host`
|
||||||
|
|
||||||
|
**Option C: Using AutoHost (Original Behavior)**
|
||||||
|
1. Keep or add `AutoHost` component
|
||||||
|
2. It will auto-start as host when playing in editor
|
||||||
|
|
||||||
|
### For Standalone Builds:
|
||||||
|
|
||||||
|
**Option A: Using NetworkJoinUI (In-Game UI)**
|
||||||
|
1. Add `NetworkJoinUI` component with UI references
|
||||||
|
2. Build and run
|
||||||
|
3. Press `J` to open connection panel
|
||||||
|
4. Enter IP and connect
|
||||||
|
|
||||||
|
**Option B: Using NetworkConnectionHelper**
|
||||||
|
1. Add `NetworkConnectionHelper` component
|
||||||
|
2. Set `Auto Start As Host = true` and `Only In Editor = false`
|
||||||
|
3. Build - it will auto-start as host
|
||||||
|
|
||||||
|
## Connection Modes
|
||||||
|
|
||||||
|
### Host
|
||||||
|
- Acts as both server and client
|
||||||
|
- Can host multiplayer games
|
||||||
|
- Players connect to your IP
|
||||||
|
|
||||||
|
### Client
|
||||||
|
- Connects to an existing server
|
||||||
|
- Requires server IP address
|
||||||
|
|
||||||
|
### Server
|
||||||
|
- Server-only mode (no player)
|
||||||
|
- Used for dedicated servers
|
||||||
|
|
||||||
|
## Network Info Display
|
||||||
|
|
||||||
|
All connection methods display:
|
||||||
|
- Current mode (Host/Client/Server)
|
||||||
|
- Connection status
|
||||||
|
- IP address and port
|
||||||
|
- Number of connected clients
|
||||||
|
- Local Client ID
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
1. **Testing Multiplayer Locally:**
|
||||||
|
- Use `127.0.0.1` or `localhost` for local testing
|
||||||
|
- Or use your local IP for testing on same network
|
||||||
|
|
||||||
|
2. **Default Port:**
|
||||||
|
- Default port is `7777`
|
||||||
|
- Change in any connection component's settings
|
||||||
|
|
||||||
|
3. **Firewall:**
|
||||||
|
- Ensure port is open for network connections
|
||||||
|
- Windows Firewall may block connections
|
||||||
|
|
||||||
|
4. **Multiple Editor Instances:**
|
||||||
|
- Use Unity's `ParrelSync` or run multiple standalone builds
|
||||||
|
- Each instance needs different settings
|
||||||
|
|
||||||
|
## Integration
|
||||||
|
|
||||||
|
All features integrate with existing `NetworkManager` and `NetworkConnectionHandler`:
|
||||||
|
- Player spawning is handled automatically
|
||||||
|
- Connection approval is handled by `NetworkConnectionHandler`
|
||||||
|
- Compatible with existing multiplayer systems
|
||||||
7
Assets/Scripts/NETWORK_CONNECTION_README.md.meta
Normal file
7
Assets/Scripts/NETWORK_CONNECTION_README.md.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f75d808bc7fb71441b7c599cf75ab9a6
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
192
Assets/Scripts/NETWORK_CONNECTION_SUMMARY.md
Normal file
192
Assets/Scripts/NETWORK_CONNECTION_SUMMARY.md
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
# Network Connection Feature Summary
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Added comprehensive IP-based network connection features for both editor testing and standalone builds.
|
||||||
|
|
||||||
|
## Files Created
|
||||||
|
|
||||||
|
### Runtime Components
|
||||||
|
1. **NetworkConnectionHelper.cs** (3.6KB)
|
||||||
|
- MonoBehaviour component for network connection management
|
||||||
|
- Start Host/Server/Client methods
|
||||||
|
- Auto-start configuration
|
||||||
|
- Status monitoring
|
||||||
|
|
||||||
|
2. **NetworkJoinUI.cs** (7.7KB)
|
||||||
|
- In-game UI component for IP connection
|
||||||
|
- Works in both editor and standalone builds
|
||||||
|
- Toggle panel with J key
|
||||||
|
- Supports Join/Host/Disconnect
|
||||||
|
|
||||||
|
3. **QuickNetworkSetup.cs** (1.6KB)
|
||||||
|
- Quick scene setup script
|
||||||
|
- Creates NetworkConnectionHelper
|
||||||
|
- Optionally disables AutoHost
|
||||||
|
|
||||||
|
### Editor Tools
|
||||||
|
4. **NetworkConnectionWindow.cs** (9.2KB)
|
||||||
|
- Dedicated Editor window for network management
|
||||||
|
- GUI-based IP/port configuration
|
||||||
|
- Connection mode selection
|
||||||
|
- Status display and settings persistence
|
||||||
|
|
||||||
|
5. **NetworkConnectionHelperEditor.cs** (5.8KB)
|
||||||
|
- Custom Inspector for NetworkConnectionHelper
|
||||||
|
- Quick action buttons
|
||||||
|
- Real-time status display
|
||||||
|
- Network information panel
|
||||||
|
|
||||||
|
6. **NetworkUIBuilder.cs** (7.4KB)
|
||||||
|
- Automated UI creation for NetworkJoinUI
|
||||||
|
- Creates complete UI structure
|
||||||
|
- Menu integration
|
||||||
|
|
||||||
|
7. **QuickNetworkSetupEditor.cs** (2.0KB)
|
||||||
|
- Menu items for quick setup
|
||||||
|
- Tools menu integration
|
||||||
|
- Enable/Disable AutoHost functionality
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
8. **NETWORK_CONNECTION_README.md**
|
||||||
|
- Comprehensive English documentation
|
||||||
|
- Setup instructions
|
||||||
|
- Usage examples
|
||||||
|
|
||||||
|
9. **NETWORK_CONNECTION_GUIDE_KO.md**
|
||||||
|
- Korean translation of documentation
|
||||||
|
- Step-by-step guide
|
||||||
|
- Troubleshooting section
|
||||||
|
|
||||||
|
## Files Modified
|
||||||
|
|
||||||
|
1. **AutoHost.cs**
|
||||||
|
- Made auto-start configurable
|
||||||
|
- Added editor-only option
|
||||||
|
- Added enable/disable toggle
|
||||||
|
|
||||||
|
## Features Added
|
||||||
|
|
||||||
|
### 1. Editor Window (NetworkConnectionWindow)
|
||||||
|
- Open via: Window > Network > Connection Manager (Ctrl+Shift+N)
|
||||||
|
- Connection modes: Host/Client/Server
|
||||||
|
- IP and port configuration
|
||||||
|
- Start/Stop connections
|
||||||
|
- Real-time status
|
||||||
|
- Settings persistence
|
||||||
|
|
||||||
|
### 2. NetworkConnectionHelper Component
|
||||||
|
- Add to any GameObject in scene
|
||||||
|
- Custom Inspector with quick buttons
|
||||||
|
- Auto-start configuration
|
||||||
|
- Status display
|
||||||
|
- Network information panel
|
||||||
|
|
||||||
|
### 3. In-Game UI (NetworkJoinUI)
|
||||||
|
- Works in editor and standalone builds
|
||||||
|
- IP/port input fields
|
||||||
|
- Join/Host/Disconnect buttons
|
||||||
|
- Status display
|
||||||
|
- Toggle with J key
|
||||||
|
- Auto-generated via menu
|
||||||
|
|
||||||
|
### 4. Quick Setup Tools
|
||||||
|
- Tools > Network > Quick Setup for IP Connection
|
||||||
|
- Automatically disables AutoHost
|
||||||
|
- Creates NetworkConnectionHelper
|
||||||
|
|
||||||
|
## Integration
|
||||||
|
|
||||||
|
All new features integrate seamlessly with existing systems:
|
||||||
|
- **NetworkManager**: Works with Unity Netcode for GameObjects
|
||||||
|
- **NetworkConnectionHandler**: Handles player spawning and approval
|
||||||
|
- **AutoHost**: Configurable to avoid conflicts
|
||||||
|
- **Transport**: Uses Unity Transport (UTP)
|
||||||
|
|
||||||
|
## Testing Workflow
|
||||||
|
|
||||||
|
### Method 1: Editor Window
|
||||||
|
1. Window > Network > Connection Manager
|
||||||
|
2. Select Host on instance 1
|
||||||
|
3. Select Client on instance 2 with Host's IP
|
||||||
|
4. Start/Connect
|
||||||
|
|
||||||
|
### Method 2: NetworkConnectionHelper
|
||||||
|
1. Add component to scene
|
||||||
|
2. Use Inspector buttons
|
||||||
|
3. View status in real-time
|
||||||
|
|
||||||
|
### Method 3: Quick Setup
|
||||||
|
1. Tools > Network > Quick Setup for IP Connection
|
||||||
|
2. Use preferred connection method
|
||||||
|
|
||||||
|
### Method 4: In-Game UI
|
||||||
|
1. GameObject > Network > Create Network Join UI
|
||||||
|
2. Press J to open
|
||||||
|
3. Enter IP and connect
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Default Settings
|
||||||
|
- Default IP: 127.0.0.1
|
||||||
|
- Default Port: 7777
|
||||||
|
- Toggle Key: J (for UI)
|
||||||
|
|
||||||
|
### Options
|
||||||
|
- Auto-start: Enable/disable in AutoHost
|
||||||
|
- Editor-only: Configure per component
|
||||||
|
- Persistence: Save/load in Editor Window
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
|
||||||
|
1. **Easy Testing**: No standalone build required
|
||||||
|
2. **Team Collaboration**: Join teammates by IP
|
||||||
|
3. **Production Ready**: Works in standalone builds
|
||||||
|
4. **Flexible**: Multiple connection methods
|
||||||
|
5. **Intuitive**: GUI-based interfaces
|
||||||
|
6. **Integrated**: Works with existing systems
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
Potential improvements:
|
||||||
|
- Server list browsing
|
||||||
|
- Favorites/Saved connections
|
||||||
|
- LAN discovery
|
||||||
|
- Connection history
|
||||||
|
- Advanced transport settings
|
||||||
|
- Password protection
|
||||||
|
|
||||||
|
## Usage Example
|
||||||
|
|
||||||
|
### Editor Testing
|
||||||
|
```csharp
|
||||||
|
// Instance 1 (Host)
|
||||||
|
Tools > Network > Quick Setup for IP Connection
|
||||||
|
Window > Network > Connection Manager > Start Host
|
||||||
|
|
||||||
|
// Instance 2 (Client)
|
||||||
|
Tools > Network > Quick Setup for IP Connection
|
||||||
|
Window > Network > Connection Manager > Connect to 127.0.0.1:7777
|
||||||
|
```
|
||||||
|
|
||||||
|
### Standalone Build
|
||||||
|
```csharp
|
||||||
|
// Build with NetworkJoinUI component
|
||||||
|
Press J to open connection panel
|
||||||
|
Enter IP: 192.168.1.X
|
||||||
|
Click Join
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
- Unity Netcode for GameObjects 2.8.1
|
||||||
|
- Unity Transport (UTP)
|
||||||
|
- Unity 2022.x+
|
||||||
|
- Windows/Mac/Linux
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- All components are optional
|
||||||
|
- AutoHost can be disabled
|
||||||
|
- Existing AutoHost behavior preserved (when enabled)
|
||||||
|
- No breaking changes to existing code
|
||||||
|
- Works with custom scenes and setups
|
||||||
7
Assets/Scripts/NETWORK_CONNECTION_SUMMARY.md.meta
Normal file
7
Assets/Scripts/NETWORK_CONNECTION_SUMMARY.md.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ef125ff435342b64f86eeea8dbef234f
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
117
Assets/Scripts/NetworkConnectionHelper.cs
Normal file
117
Assets/Scripts/NetworkConnectionHelper.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using Unity.Netcode;
|
||||||
|
|
||||||
|
namespace Northbound
|
||||||
|
{
|
||||||
|
public class NetworkConnectionHelper : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Connection Settings")]
|
||||||
|
[SerializeField] private string serverIP = "127.0.0.1";
|
||||||
|
[SerializeField] private ushort port = 7777;
|
||||||
|
|
||||||
|
[Header("Auto Start")]
|
||||||
|
[SerializeField] private bool autoStartAsHost = false;
|
||||||
|
[SerializeField] private bool onlyInEditor = true;
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
if (autoStartAsHost && ShouldAutoStart())
|
||||||
|
{
|
||||||
|
StartHost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldAutoStart()
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return !onlyInEditor;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartHost()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[NetworkConnectionHelper] NetworkManager not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigureTransport("0.0.0.0", port);
|
||||||
|
|
||||||
|
if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsClient)
|
||||||
|
{
|
||||||
|
NetworkManager.Singleton.StartHost();
|
||||||
|
Debug.Log($"[NetworkConnectionHelper] Started Host on port {port}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartClient()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[NetworkConnectionHelper] NetworkManager not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigureTransport(serverIP, port);
|
||||||
|
|
||||||
|
if (!NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
|
||||||
|
{
|
||||||
|
NetworkManager.Singleton.StartClient();
|
||||||
|
Debug.Log($"[NetworkConnectionHelper] Connecting to {serverIP}:{port}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartServer()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[NetworkConnectionHelper] NetworkManager not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigureTransport("0.0.0.0", port);
|
||||||
|
|
||||||
|
if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsClient)
|
||||||
|
{
|
||||||
|
NetworkManager.Singleton.StartServer();
|
||||||
|
Debug.Log($"[NetworkConnectionHelper] Started Server on port {port}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disconnect()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton != null)
|
||||||
|
{
|
||||||
|
NetworkManager.Singleton.Shutdown();
|
||||||
|
Debug.Log("[NetworkConnectionHelper] Disconnected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetStatus()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
return "NetworkManager not found";
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton.IsHost)
|
||||||
|
return "Hosting";
|
||||||
|
if (NetworkManager.Singleton.IsServer)
|
||||||
|
return "Server";
|
||||||
|
if (NetworkManager.Singleton.IsClient)
|
||||||
|
return "Client";
|
||||||
|
|
||||||
|
return "Not connected";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureTransport(string ip, ushort portNum)
|
||||||
|
{
|
||||||
|
var transport = NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
transport.SetConnectionData(ip, portNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/Scripts/NetworkConnectionHelper.cs.meta
Normal file
2
Assets/Scripts/NetworkConnectionHelper.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 947211167dacac64092d1c6ea2b00af6
|
||||||
269
Assets/Scripts/NetworkJoinUI.cs
Normal file
269
Assets/Scripts/NetworkJoinUI.cs
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using Unity.Netcode;
|
||||||
|
|
||||||
|
namespace Northbound
|
||||||
|
{
|
||||||
|
public class NetworkJoinUI : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("UI References")]
|
||||||
|
[SerializeField] private GameObject joinPanel;
|
||||||
|
[SerializeField] private InputField ipInputField;
|
||||||
|
[SerializeField] private InputField portInputField;
|
||||||
|
[SerializeField] private Button joinButton;
|
||||||
|
[SerializeField] private Button hostButton;
|
||||||
|
[SerializeField] private Button disconnectButton;
|
||||||
|
[SerializeField] private Text statusText;
|
||||||
|
[SerializeField] private KeyCode toggleKey = KeyCode.J;
|
||||||
|
|
||||||
|
[Header("Settings")]
|
||||||
|
[SerializeField] private string defaultIP = "127.0.0.1";
|
||||||
|
[SerializeField] private string defaultPort = "7777";
|
||||||
|
|
||||||
|
private bool _isVisible = false;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
InitializeUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
SetupDefaultValues();
|
||||||
|
SubscribeToEvents();
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (Input.GetKeyDown(toggleKey))
|
||||||
|
{
|
||||||
|
TogglePanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton != null &&
|
||||||
|
(NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer))
|
||||||
|
{
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeUI()
|
||||||
|
{
|
||||||
|
if (joinPanel != null)
|
||||||
|
{
|
||||||
|
joinPanel.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupDefaultValues()
|
||||||
|
{
|
||||||
|
if (ipInputField != null)
|
||||||
|
{
|
||||||
|
ipInputField.text = defaultIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portInputField != null)
|
||||||
|
{
|
||||||
|
portInputField.text = defaultPort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeToEvents()
|
||||||
|
{
|
||||||
|
if (joinButton != null)
|
||||||
|
{
|
||||||
|
joinButton.onClick.AddListener(OnJoinClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostButton != null)
|
||||||
|
{
|
||||||
|
hostButton.onClick.AddListener(OnHostClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disconnectButton != null)
|
||||||
|
{
|
||||||
|
disconnectButton.onClick.AddListener(OnDisconnectClicked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnsubscribeFromEvents()
|
||||||
|
{
|
||||||
|
if (joinButton != null)
|
||||||
|
{
|
||||||
|
joinButton.onClick.RemoveListener(OnJoinClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostButton != null)
|
||||||
|
{
|
||||||
|
hostButton.onClick.RemoveListener(OnHostClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disconnectButton != null)
|
||||||
|
{
|
||||||
|
disconnectButton.onClick.RemoveListener(OnDisconnectClicked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnJoinClicked()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
{
|
||||||
|
ShowError("NetworkManager not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ip = ipInputField != null ? ipInputField.text : defaultIP;
|
||||||
|
string port = portInputField != null ? portInputField.text : defaultPort;
|
||||||
|
|
||||||
|
ushort portNum;
|
||||||
|
if (!ushort.TryParse(port, out portNum))
|
||||||
|
{
|
||||||
|
ShowError("Invalid port number!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
|
||||||
|
{
|
||||||
|
ShowError("Already connected!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var transport = NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
transport.SetConnectionData(ip, portNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkManager.Singleton.StartClient();
|
||||||
|
UpdateStatus();
|
||||||
|
Debug.Log($"[NetworkJoinUI] Connecting to {ip}:{port}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnHostClicked()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
{
|
||||||
|
ShowError("NetworkManager not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string port = portInputField != null ? portInputField.text : defaultPort;
|
||||||
|
|
||||||
|
ushort portNum;
|
||||||
|
if (!ushort.TryParse(port, out portNum))
|
||||||
|
{
|
||||||
|
ShowError("Invalid port number!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)
|
||||||
|
{
|
||||||
|
ShowError("Already connected!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var transport = NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
transport.SetConnectionData("0.0.0.0", portNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkManager.Singleton.StartHost();
|
||||||
|
UpdateStatus();
|
||||||
|
Debug.Log($"[NetworkJoinUI] Started Host on port {port}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisconnectClicked()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton != null)
|
||||||
|
{
|
||||||
|
NetworkManager.Singleton.Shutdown();
|
||||||
|
UpdateStatus();
|
||||||
|
Debug.Log("[NetworkJoinUI] Disconnected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateStatus()
|
||||||
|
{
|
||||||
|
if (statusText == null) return;
|
||||||
|
|
||||||
|
string status = GetNetworkStatus();
|
||||||
|
statusText.text = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetNetworkStatus()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null)
|
||||||
|
return "NetworkManager not found";
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton.IsHost)
|
||||||
|
return $"Hosting (Port: {GetActivePort()})";
|
||||||
|
if (NetworkManager.Singleton.IsServer)
|
||||||
|
return $"Server (Port: {GetActivePort()})";
|
||||||
|
if (NetworkManager.Singleton.IsClient)
|
||||||
|
return $"Client connected to {GetActiveIP()}:{GetActivePort()}";
|
||||||
|
|
||||||
|
return "Not connected";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetActiveIP()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null) return "N/A";
|
||||||
|
|
||||||
|
var transport = NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
return transport.ConnectionData.Address;
|
||||||
|
}
|
||||||
|
return "N/A";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetActivePort()
|
||||||
|
{
|
||||||
|
if (NetworkManager.Singleton == null) return "N/A";
|
||||||
|
|
||||||
|
var transport = NetworkManager.Singleton.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
return transport.ConnectionData.Port.ToString();
|
||||||
|
}
|
||||||
|
return "N/A";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TogglePanel()
|
||||||
|
{
|
||||||
|
if (joinPanel != null)
|
||||||
|
{
|
||||||
|
_isVisible = !_isVisible;
|
||||||
|
joinPanel.SetActive(_isVisible);
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowError(string message)
|
||||||
|
{
|
||||||
|
Debug.LogError($"[NetworkJoinUI] {message}");
|
||||||
|
if (statusText != null)
|
||||||
|
{
|
||||||
|
statusText.text = $"Error: {message}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
UnsubscribeFromEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetUIReferences(GameObject panel, InputField ipField, InputField portField, Button joinBtn, Button hostBtn, Button disconnectBtn, Text status)
|
||||||
|
{
|
||||||
|
joinPanel = panel;
|
||||||
|
ipInputField = ipField;
|
||||||
|
portInputField = portField;
|
||||||
|
joinButton = joinBtn;
|
||||||
|
hostButton = hostBtn;
|
||||||
|
disconnectButton = disconnectBtn;
|
||||||
|
statusText = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/Scripts/NetworkJoinUI.cs.meta
Normal file
2
Assets/Scripts/NetworkJoinUI.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 824b1e5b92d2ce946b9f2c121a535c73
|
||||||
54
Assets/Scripts/QuickNetworkSetup.cs
Normal file
54
Assets/Scripts/QuickNetworkSetup.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Northbound
|
||||||
|
{
|
||||||
|
public class QuickNetworkSetup : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Quick Setup Options")]
|
||||||
|
[Tooltip("Create a NetworkConnectionHelper component")]
|
||||||
|
[SerializeField] private bool createConnectionHelper = true;
|
||||||
|
|
||||||
|
[Tooltip("Disable AutoHost to prevent auto-start")]
|
||||||
|
[SerializeField] private bool disableAutoHost = true;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
SetupScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupScene()
|
||||||
|
{
|
||||||
|
if (createConnectionHelper)
|
||||||
|
{
|
||||||
|
CreateConnectionHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disableAutoHost)
|
||||||
|
{
|
||||||
|
DisableAutoHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
Destroy(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateConnectionHelper()
|
||||||
|
{
|
||||||
|
if (FindObjectOfType<NetworkConnectionHelper>() == null)
|
||||||
|
{
|
||||||
|
GameObject helperObj = new GameObject("NetworkConnectionHelper");
|
||||||
|
helperObj.AddComponent<NetworkConnectionHelper>();
|
||||||
|
Debug.Log("[QuickNetworkSetup] NetworkConnectionHelper created");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisableAutoHost()
|
||||||
|
{
|
||||||
|
AutoHost[] autoHosts = FindObjectsByType<AutoHost>(FindObjectsSortMode.None);
|
||||||
|
foreach (var autoHost in autoHosts)
|
||||||
|
{
|
||||||
|
autoHost.enabled = false;
|
||||||
|
Debug.Log("[QuickNetworkSetup] AutoHost disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/Scripts/QuickNetworkSetup.cs.meta
Normal file
2
Assets/Scripts/QuickNetworkSetup.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 572b945beced27f418a84bba613ff5b9
|
||||||
Reference in New Issue
Block a user