네트워크 멀티플레이 테스트를 위한 코드 추가

This commit is contained in:
2026-02-03 13:18:50 +09:00
parent 3e874fb863
commit 775e1cffac
30 changed files with 2021 additions and 1835 deletions

View File

@@ -50,6 +50,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Assets\Scripts\NetworkManagerUI.cs" />
<Compile Include="Assets\Scripts\NetworkManagerValidator.cs" />
<Compile Include="Assets\FlatKit\Demos\[Demo] Desert\Scripts\FloatingMotion.cs" />
<Compile Include="Assets\Scripts\PlayerResourceInventory.cs" />
<Compile Include="Assets\Scripts\ITeamMember.cs" />
@@ -71,8 +72,10 @@
<Compile Include="Assets\Scripts\EnemyAIController.cs" />
<Compile Include="Assets\Scripts\EquipmentSocket.cs" />
<Compile Include="Assets\Scripts\DebugLogUI.cs" />
<Compile Include="Assets\Scripts\ContinuousPortMonitor.cs" />
<Compile Include="Assets\Data\Scripts\DataClasses\PlayerData.cs" />
<Compile Include="Assets\Scripts\TeamManager.cs" />
<Compile Include="Assets\Scripts\PortListenerTestSimultaneous.cs" />
<Compile Include="Assets\Scripts\TeamGate.cs" />
<Compile Include="Assets\Scripts\Worker.cs" />
<Compile Include="Assets\Scripts\WorkerSpawner.cs" />
@@ -95,7 +98,6 @@
<Compile Include="Assets\Scripts\BuildingHealthBar.cs" />
<Compile Include="Assets\Data\Scripts\DataClasses\CreepData.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\Scripts\AutoHost.cs" />
<Compile Include="Assets\Scripts\MonsterAnimationController.cs" />
@@ -105,7 +107,8 @@
<Compile Include="Assets\Scripts\BuildingPlacement.cs" />
<Compile Include="Assets\Scripts\MonsterDataComponent.cs" />
<Compile Include="Assets\Scripts\Core.cs" />
<Compile Include="Assets\Scripts\NetworkDebugger.cs" />
<Compile Include="Assets\Scripts\GamePortConfig.cs" />
<Compile Include="Assets\Scripts\NetworkManagerQuickTest.cs" />
<Compile Include="Assets\Scripts\EnemyPortal.cs" />
<Compile Include="Assets\FlatKit\Demos\Common\Scripts\Motion\LinearMotion.cs" />
<Compile Include="Assets\Scripts\IDamageable.cs" />
@@ -118,6 +121,7 @@
<Compile Include="Assets\Scripts\NetworkPlayerController.cs" />
<Compile Include="Assets\Scripts\PlayerInteraction.cs" />
<Compile Include="Assets\Scripts\FogOfWarVisibility.cs" />
<Compile Include="Assets\Scripts\NetworkResetAndRestart.cs" />
<Compile Include="Assets\Scripts\NetworkDebug.cs" />
<Compile Include="Assets\Data\Scripts\DataClasses\DefaultSettingsData.cs" />
<Compile Include="Assets\Scripts\EnemyAIState.cs" />

View File

@@ -815,7 +815,6 @@ Transform:
m_Children:
- {fileID: 1442785555}
- {fileID: 672563223}
- {fileID: 1142746334}
- {fileID: 1199559224}
- {fileID: 955933985}
- {fileID: 946527919}
@@ -1485,6 +1484,54 @@ MonoBehaviour:
m_MinRegionArea: 2
m_NavMeshData: {fileID: 23800000, guid: a847cf63b54abee4cbd5b6c92c8ad5e6, type: 2}
m_BuildHeightMesh: 0
--- !u!1 &1036857642
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1036857644}
- component: {fileID: 1036857643}
m_Layer: 0
m_Name: NetworkConnectionHelper
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1036857643
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1036857642}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 947211167dacac64092d1c6ea2b00af6, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.NetworkConnectionHelper
serverIP: 59.18.227.134
port: 40445
autoStartAsHost: 0
onlyInEditor: 1
--- !u!4 &1036857644
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1036857642}
serializedVersion: 2
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}
--- !u!1 &1053830687
GameObject:
m_ObjectHideFlags: 0
@@ -1661,52 +1708,6 @@ Transform:
m_CorrespondingSourceObject: {fileID: 228462577495887354, guid: 11e3760dda2c0164abf759c18d918893, type: 3}
m_PrefabInstance: {fileID: 1440648431994998967}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1142746332
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1142746334}
- component: {fileID: 1142746333}
m_Layer: 0
m_Name: AutoHost
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1142746333
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1142746332}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f0ad96fafd5ac4f4db7e02424e132b89, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::AutoHost
enableAutoHost: 1
onlyInEditor: 1
--- !u!4 &1142746334
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1142746332}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 16.79047, y: 4.17818, z: -533.95886}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 640318137}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1166878641
GameObject:
m_ObjectHideFlags: 0
@@ -1972,6 +1973,7 @@ GameObject:
- component: {fileID: 1433142233}
- component: {fileID: 1433142234}
- component: {fileID: 1433142235}
- component: {fileID: 1433142239}
m_Layer: 0
m_Name: NetworkManager
m_TagString: Untagged
@@ -2060,8 +2062,8 @@ MonoBehaviour:
m_DisconnectTimeoutMS: 30000
ConnectionData:
Address: 127.0.0.1
Port: 7954
ServerListenAddress: 127.0.0.1
Port: 40445
ServerListenAddress: 0.0.0.0
ClientBindPort: 0
DebugSimulator:
PacketDelayMS: 0
@@ -2082,6 +2084,20 @@ MonoBehaviour:
spawnPoints: []
useRandomSpawn: 0
findSpawnPointsAutomatically: 1
--- !u!114 &1433142239
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1433142230}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 572b945beced27f418a84bba613ff5b9, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.QuickNetworkSetup
createConnectionHelper: 1
disableAutoHost: 1
--- !u!1 &1442785552
GameObject:
m_ObjectHideFlags: 0
@@ -2488,6 +2504,82 @@ PrefabInstance:
insertIndex: -1
addedObject: {fileID: 985764489}
m_SourcePrefab: {fileID: 100100000, guid: 19ca9afdd7bb3a64c9036c18e8cee5f2, type: 3}
--- !u!1 &2053530245
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2053530248}
- component: {fileID: 2053530247}
- component: {fileID: 2053530249}
- component: {fileID: 2053530250}
m_Layer: 0
m_Name: NetworkTester
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &2053530247
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2053530245}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1d695616342b92d449295973fc4cda7e, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.NetworkManagerQuickTest
runTestOnStart: 1
showDetailedLogs: 1
--- !u!4 &2053530248
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2053530245}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -76.86971, y: -0, z: 57.56356}
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}
--- !u!114 &2053530249
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2053530245}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d15e6615b07f55843a759c775a08bc89, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.NetworkResetAndRestart
autoResetOnStart: 0
targetPort: 40445
--- !u!114 &2053530250
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2053530245}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ba79d51f450e07d439690667a6535133, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.PortListenerTestSimultaneous
testPort: 40445
autoStartOnEnable: 0
--- !u!1001 &2098115307
PrefabInstance:
m_ObjectHideFlags: 0
@@ -2953,6 +3045,8 @@ SceneRoots:
m_Roots:
- {fileID: 1975225896}
- {fileID: 1433142232}
- {fileID: 1036857644}
- {fileID: 2053530248}
- {fileID: 457600247}
- {fileID: 640318137}
- {fileID: 576429380}

View File

@@ -1,163 +0,0 @@
# Connection Failure Troubleshooting Guide
## Problem: "Failed to connect to server" error
### Quick Fixes to Try
1. **Add NetworkDebugger to scene**
- Add `NetworkDebugger` component to NetworkManager
- Check Console for detailed connection logs
- Look for:
- Connection approval status
- Transport binding errors
- Timeout messages
2. **Add NetworkConnectionFixer to scene**
- Add `NetworkConnectionFixer` component to NetworkManager
- Right-click component → "Fix All Known Issues"
- This auto-fixes common transport timeout issues
3. **Check Firewall (Most Likely Cause)**
Even with port forwarding, Windows Firewall may block connections:
**Windows:**
- Windows Security → Firewall & network protection → Allow an app through firewall
- Add Unity Editor AND your built executable
- Allow on both Private and Public networks
- Add exception for port 7777 (or your port)
**Command Line (Quick Fix):**
```
netsh advfirewall firewall add rule name="Unity Network" dir=in action=allow protocol=TCP localport=7777
```
4. **Verify Transport Settings**
In Play mode, on NetworkManager → UnityTransport:
- ConnectionData.Address should be `0.0.0.0` for Host/Server
- ConnectionData.Port should be 7777 (or your forwarded port)
- ServerListenAddress can be left default
5. **Test Port Forwarding**
- Use online tool: https://www.yougetsignal.com/tools/open-ports/
- Enter your public IP and port
- Should show "Open" (not "Closed" or "Timed out")
6. **Disable IPv6 (Temporary Fix)**
Some network configurations have IPv6 issues:
```
Control Panel → Network and Internet → Network Connections
→ Right-click adapter → Properties → Uncheck Internet Protocol Version 6
```
(Reboot required)
7. **Increase Network Timeouts**
- On UnityTransport component:
- Connect Timeout MS: 15000 (15 seconds)
- Max Connect Attempts: 10
## Debug Steps
### 1. Check Server Side
```
Add NetworkDebugger → Play → Start Host
Check Console for:
✓ "Server Started Successfully"
✓ "Listening on: 0.0.0.0:7777"
✗ Any binding errors
```
### 2. Check Client Side
```
Add NetworkDebugger → Play → Connect to PUBLIC IP
Check Console for:
✓ "Connection Approval Request from Client"
✓ "Approval Response: Approved: true"
✗ "TRANSPORT FAILURE"
✗ "Failed to connect to server"
```
### 3. Common Error Patterns
**Error: "Failed to connect to server" + "TRANSPORT FAILURE"**
- Cause: Firewall blocking
- Fix: Allow Unity through firewall, check port forwarding
**Error: Connection approval never happens**
- Cause: NetworkManager configuration issue
- Fix: Check NetworkConfig → Connection Approval = true
**Error: Client shows "Connected" but no player spawns**
- Cause: ConnectionApproval returning false or spawn point issues
- Fix: Check NetworkConnectionHandler logs
## Advanced Troubleshooting
### Log Network State
```csharp
// Add this component and right-click → "Log Current Network State"
public void CheckConnection()
{
Debug.Log("IsServer: " + NetworkManager.Singleton.IsServer);
Debug.Log("IsClient: " + NetworkManager.Singleton.IsClient);
Debug.Log("IsConnectedClient: " + NetworkManager.Singleton.IsConnectedClient);
}
```
### Test Local Connection First
1. Host: Connect to 127.0.0.1 (should always work)
2. If fails: Project setup issue, not network issue
3. If works: Network/Firewall issue with public IP
### Check NetworkManager Configuration
Ensure:
- Player Prefab assigned
- Network Prefabs list populated
- Connection Approval enabled
- Scene Management enabled (if using scenes)
- Transport is Unity Transport (UTP)
## Alternative Solutions
### Option 1: Use LAN instead of Internet
If possible, use VPN or Hamachi:
- Creates virtual LAN
- Both players appear on same network
- No port forwarding needed
### Option 2: Use Relay Service
Unity Relay bypasses NAT/Firewall:
- Requires Unity Services account
- Free tier available
- More reliable for internet play
### Option 3: Dedicated Server
- Host on cloud server (AWS, Azure, etc.)
- No port forwarding needed on client side
- Better performance and reliability
## Quick Checklist
- [ ] Port forwarded correctly (verify with online tool)
- [ ] Firewall allows Unity/Build executable
- [ ] Using public IP (not 127.0.0.1 or 192.168.x.x)
- [ ] Same Unity version and Netcode version on both sides
- [ ] Same port on both client and server
- [ ] NetworkManager has Player Prefab assigned
- [ ] Host started BEFORE client tries to connect
- [ ] No antivirus/security software blocking
- [ ] Both using Release builds (not Debug)
## When to Ask for Help
If you've tried:
1. All firewall fixes
2. Verified port forwarding with online tool
3. Tested local connection (127.0.0.1) works
4. Checked NetworkManager configuration
5. Added NetworkDebugger and NetworkConnectionFixer
Then share:
- Full Console logs from BOTH host and client
- NetworkManager inspector screenshot
- UnityTransport settings screenshot
- Port forwarding confirmation (screenshot or online tool result)

View File

@@ -1,310 +0,0 @@
using UnityEngine;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
namespace Northbound
{
public class ConnectionDiagnostics : MonoBehaviour
{
[Header("Auto-Diagnosis")]
[SerializeField] private bool runOnStart = true;
[SerializeField] private bool autoFixIssues = true;
private NetworkManager _networkManager;
private UnityTransport _transport;
private void Start()
{
if (runOnStart)
{
RunDiagnostics();
}
}
public void RunDiagnostics()
{
Debug.Log("<color=yellow>=== RUNNING CONNECTION DIAGNOSTICS ===</color>");
InitializeComponents();
CheckNetworkManager();
CheckTransport();
CheckPlayerPrefab();
CheckConnectionApproval();
if (autoFixIssues)
{
FixCommonIssues();
}
GenerateReport();
Debug.Log("<color=yellow>=== DIAGNOSTICS COMPLETE ===</color>");
}
private void InitializeComponents()
{
_networkManager = NetworkManager.Singleton;
if (_networkManager == null)
{
Debug.LogError("<color=red>[Diagnostics] NetworkManager not found!</color>");
return;
}
_transport = _networkManager.GetComponent<UnityTransport>();
if (_transport == null)
{
Debug.LogError("<color=red>[Diagnostics] UnityTransport not found!</color>");
return;
}
}
private void CheckNetworkManager()
{
Debug.Log("<color=cyan>[1/5] Checking NetworkManager...</color>");
if (_networkManager == null)
{
Debug.LogError("✗ NetworkManager is NULL");
return;
}
Debug.Log("✓ NetworkManager exists");
Debug.Log(" IsServer: " + _networkManager.IsServer);
Debug.Log(" IsClient: " + _networkManager.IsClient);
Debug.Log(" IsHost: " + _networkManager.IsHost);
Debug.Log(" IsConnectedClient: " + _networkManager.IsConnectedClient);
}
private void CheckTransport()
{
Debug.Log("<color=cyan>[2/5] Checking UnityTransport...</color>");
if (_transport == null)
{
Debug.LogError("✗ UnityTransport is NULL");
return;
}
Debug.Log("✓ UnityTransport exists");
Debug.Log(" Connection Address: " + _transport.ConnectionData.Address);
Debug.Log(" Connection Port: " + _transport.ConnectionData.Port);
Debug.Log(" Server Listen Address: " + _transport.ConnectionData.ServerListenAddress);
int timeout = _transport.ConnectTimeoutMS;
if (timeout < 10000)
{
Debug.LogWarning("⚠ Connect timeout too low: " + timeout + "ms (recommended: 15000ms)");
}
else
{
Debug.Log("✓ Connect timeout is adequate: " + timeout + "ms");
}
ushort port = _transport.ConnectionData.Port;
if (port <= 0 || port > 65535)
{
Debug.LogError("✗ Invalid port: " + port);
}
else
{
Debug.Log("✓ Port is valid: " + port);
}
}
private void CheckPlayerPrefab()
{
Debug.Log("<color=cyan>[3/5] Checking Player Prefab...</color>");
if (_networkManager == null || _networkManager.NetworkConfig == null)
{
Debug.LogError("✗ NetworkConfig not accessible");
return;
}
GameObject playerPrefab = _networkManager.NetworkConfig.PlayerPrefab;
if (playerPrefab == null)
{
Debug.LogError("✗ Player Prefab is NOT assigned!");
Debug.LogError(" → Players will not spawn");
Debug.LogError(" → Fix: Assign Player Prefab in NetworkManager");
return;
}
Debug.Log("✓ Player Prefab assigned: " + playerPrefab.name);
NetworkObject networkObject = playerPrefab.GetComponent<NetworkObject>();
if (networkObject == null)
{
Debug.LogError("✗ Player Prefab has no NetworkObject component!");
}
else
{
Debug.Log("✓ Player Prefab has NetworkObject");
}
}
private void CheckConnectionApproval()
{
Debug.Log("<color=cyan>[4/5] Checking Connection Approval...</color>");
if (_networkManager == null || _networkManager.NetworkConfig == null)
{
Debug.LogError("✗ NetworkConfig not accessible");
return;
}
bool approval = _networkManager.NetworkConfig.ConnectionApproval;
Debug.Log("Connection Approval: " + approval);
if (approval)
{
Debug.Log("✓ Connection approval is enabled");
Debug.Log(" → Ensure ConnectionApprovalCallback is set");
}
else
{
Debug.LogWarning("⚠ Connection approval is disabled");
Debug.Log(" → Players may auto-connect without approval");
}
NetworkConnectionHandler handler = FindObjectOfType<NetworkConnectionHandler>();
if (handler != null)
{
Debug.Log("✓ NetworkConnectionHandler found");
}
else
{
Debug.LogWarning("⚠ NetworkConnectionHandler not found");
Debug.Log(" → Manual player spawning may not work");
}
}
private void FixCommonIssues()
{
Debug.Log("<color=cyan>[5/5] Fixing Common Issues...</color>");
if (_transport == null) return;
bool fixedSomething = false;
if (_transport.ConnectTimeoutMS < 10000)
{
_transport.ConnectTimeoutMS = 15000;
Debug.Log("✓ Fixed: Increased timeout to 15000ms");
fixedSomething = true;
}
if (_transport.MaxConnectAttempts < 5)
{
_transport.MaxConnectAttempts = 10;
Debug.Log("✓ Fixed: Increased max connect attempts to 10");
fixedSomething = true;
}
ushort port = _transport.ConnectionData.Port;
if (port <= 0)
{
_transport.SetConnectionData("0.0.0.0", 7777);
Debug.Log("✓ Fixed: Set default port to 7777");
fixedSomething = true;
}
if (!fixedSomething)
{
Debug.Log("✓ No issues found to fix");
}
}
private void GenerateReport()
{
Debug.Log("<color=green>=== DIAGNOSTICS REPORT ===</color>");
string status = GetOverallStatus();
Color color = GetStatusColor(status);
Debug.Log("<color=" + ColorToHex(color) + ">" + status + "</color>");
if (status != "System Healthy")
{
Debug.Log("Review warnings and errors above");
}
Debug.Log("=========================");
}
private string GetOverallStatus()
{
if (_networkManager == null || _transport == null)
return "Critical Errors Found";
if (_networkManager.NetworkConfig?.PlayerPrefab == null)
return "Configuration Error";
if (_transport.ConnectTimeoutMS < 10000)
return "Performance Issue";
return "System Healthy";
}
private Color GetStatusColor(string status)
{
switch (status)
{
case "System Healthy":
return Color.green;
case "Performance Issue":
return Color.yellow;
case "Configuration Error":
return new Color(1f, 0.5f, 0f);
case "Critical Errors Found":
return Color.red;
default:
return Color.gray;
}
}
private string ColorToHex(Color color)
{
return "#" + ColorUtility.ToHtmlStringRGBA(color);
}
[ContextMenu("Run Diagnostics")]
public void ManualRunDiagnostics()
{
RunDiagnostics();
}
[ContextMenu("Check Connection Status")]
public void CheckConnectionStatus()
{
if (_networkManager == null)
{
Debug.LogError("NetworkManager not found");
return;
}
Debug.Log("=== CONNECTION STATUS ===");
Debug.Log("IsServer: " + _networkManager.IsServer);
Debug.Log("IsClient: " + _networkManager.IsClient);
Debug.Log("IsHost: " + _networkManager.IsHost);
Debug.Log("IsConnectedClient: " + _networkManager.IsConnectedClient);
Debug.Log("LocalClientId: " + _networkManager.LocalClientId);
Debug.Log("ConnectedClients: " + _networkManager.ConnectedClients.Count);
if (_transport != null)
{
Debug.Log("Listening on: " + _transport.ConnectionData.Address + ":" + _transport.ConnectionData.Port);
}
if (_networkManager.IsHost || _networkManager.IsServer)
{
Debug.Log("Connected Players:");
foreach (var client in _networkManager.ConnectedClients)
{
string playerInfo = client.Value.PlayerObject != null ?
client.Value.PlayerObject.name : "No Player Object";
Debug.Log(" Client " + client.Key + ": " + playerInfo);
}
}
Debug.Log("=======================");
}
}
}

View File

@@ -0,0 +1,365 @@
using UnityEngine;
using Unity.Netcode;
using System.Net.Sockets;
using System.Net;
using System;
using System.Threading;
namespace Northbound
{
/// <summary>
/// Continuous port monitor - keeps checking if port is actually open
/// Helps diagnose why Unity Netcode doesn't keep port open
/// </summary>
public class ContinuousPortMonitor : MonoBehaviour
{
[Header("Monitoring Settings")]
[SerializeField] private ushort targetPort = 40445;
[SerializeField] private bool startMonitoringOnStart = false;
[SerializeField] private float checkInterval = 1f;
[SerializeField] private int maxFailedChecksBeforeWarning = 5;
[Header("Actions")]
[SerializeField] private bool autoRestartBinding = true;
[SerializeField] private bool keepTestListenerAlive = false;
[Header("Debug")]
[SerializeField] private bool verboseLogging = true;
private NetworkManager _networkManager;
private TcpListener _testListener;
private Thread _listenerThread;
private volatile bool _listenerRunning = false;
private float _lastCheckTime;
private int _failedCheckCount = 0;
private bool _wasListeningPreviously = false;
private void Start()
{
StartCoroutine(InitializeDelayed());
}
private System.Collections.IEnumerator InitializeDelayed()
{
Debug.Log("[ContinuousPortMonitor] Waiting for NetworkManager...");
int attempts = 0;
while (_networkManager == null && attempts < 50)
{
_networkManager = NetworkManager.Singleton;
if (_networkManager == null)
{
yield return new WaitForSeconds(0.1f);
attempts++;
}
}
if (_networkManager == null)
{
Debug.LogError("[ContinuousPortMonitor] NetworkManager not found!");
yield break;
}
Debug.Log("[ContinuousPortMonitor] NetworkManager found!");
if (startMonitoringOnStart)
{
StartMonitoring();
}
}
[ContextMenu("Start Port Monitoring")]
public void StartMonitoring()
{
Debug.Log("<color=cyan>[ContinuousPortMonitor] Starting port monitoring for " + targetPort + "</color>");
if (keepTestListenerAlive)
{
StartTestListener();
}
Debug.Log("[ContinuousPortMonitor] Monitoring started - check interval: " + checkInterval + "s");
Debug.Log("[ContinuousPortMonitor] Will check if port remains accessible");
}
[ContextMenu("Stop Port Monitoring")]
public void StopMonitoring()
{
Debug.Log("[ContinuousPortMonitor] Stopping monitoring...");
StopTestListener();
enabled = false;
}
private void Update()
{
if (!enabled) return;
if (Time.time - _lastCheckTime >= checkInterval)
{
_lastCheckTime = Time.time;
CheckPortAccessibility();
}
}
private void CheckPortAccessibility()
{
bool isUnityServerRunning = _networkManager != null && _networkManager.IsServer;
bool isCurrentlyListening = _listenerRunning || isUnityServerRunning;
if (!verboseLogging)
{
// Only log when status changes
if (isCurrentlyListening != _wasListeningPreviously)
{
_wasListeningPreviously = isCurrentlyListening;
if (isCurrentlyListening)
{
Debug.Log("<color=green>[ContinuousPortMonitor] ✓ Port " + targetPort + " is NOW ACCESSIBLE</color>");
}
else
{
Debug.LogWarning("<color=yellow>[ContinuousPortMonitor] ⚠ Port " + targetPort + " became INACCESSIBLE</color>");
}
}
return;
}
// Verbose logging
if (isUnityServerRunning)
{
Debug.Log("[ContinuousPortMonitor] Unity Server: RUNNING");
}
if (_listenerRunning)
{
Debug.Log("[ContinuousPortMonitor] Test Listener: RUNNING");
}
bool portAccessible = TestPortConnection();
if (portAccessible)
{
_failedCheckCount = 0;
if (Time.frameCount % 60 == 0) // Every second at 60fps
{
Debug.Log("<color=green>[ContinuousPortMonitor] ✓ Port " + targetPort + " is accessible</color>");
}
}
else
{
_failedCheckCount++;
if (_failedCheckCount == 1)
{
Debug.LogWarning("<color=yellow>[ContinuousPortMonitor] ⚠ Port " + targetPort + " became inaccessible</color>");
}
else if (_failedCheckCount % 10 == 0)
{
Debug.LogWarning("<color=yellow>[ContinuousPortMonitor] ⚠ Port still inaccessible (check #" + _failedCheckCount + ")</color>");
}
if (_failedCheckCount >= maxFailedChecksBeforeWarning)
{
Debug.LogError("<color=red>[ContinuousPortMonitor] ✗ Port has been inaccessible for " + _failedCheckCount + " checks!</color>");
Debug.LogError("[ContinuousPortMonitor] This indicates a problem with port binding");
Debug.LogError("[ContinuousPortMonitor] Possible causes:");
Debug.LogError("1. Unity Netcode is not actually listening");
Debug.LogError("2. Another process is interfering");
Debug.LogError("3. NetworkManager has crashed/stopped");
if (autoRestartBinding)
{
Debug.Log("<color=cyan>[ContinuousPortMonitor] Attempting to restore binding...</color>");
TryRestoreBinding();
}
}
}
}
private bool TestPortConnection()
{
try
{
using (TcpClient client = new TcpClient("127.0.0.1", targetPort))
{
return true;
}
}
catch
{
return false;
}
}
private void StartTestListener()
{
if (_listenerRunning)
{
Debug.LogWarning("[ContinuousPortMonitor] Test listener already running");
return;
}
_listenerRunning = true;
_listenerThread = new Thread(new ThreadStart(ListenerThread));
_listenerThread.IsBackground = true;
_listenerThread.Start();
Debug.Log("[ContinuousPortMonitor] Test listener started on port " + targetPort);
}
private void StopTestListener()
{
_listenerRunning = false;
if (_testListener != null)
{
_testListener.Stop();
_testListener = null;
}
if (_listenerThread != null && _listenerThread.IsAlive)
{
_listenerThread.Join(1000);
}
Debug.Log("[ContinuousPortMonitor] Test listener stopped");
}
private void ListenerThread()
{
try
{
_testListener = new TcpListener(IPAddress.Any, targetPort);
_testListener.Start();
Debug.Log("[ContinuousPortMonitor] Test listener successfully bound to 0.0.0.0:" + targetPort);
Debug.Log("[ContinuousPortMonitor] Port should now be accessible on yougetsignal");
while (_listenerRunning)
{
if (_testListener.Pending())
{
try
{
TcpClient client = _testListener.AcceptTcpClient();
IPEndPoint endPoint = (IPEndPoint)client.Client.RemoteEndPoint;
Debug.Log("<color=green>[ContinuousPortMonitor] ✓ Connection received from " + endPoint.Address + ":" + endPoint.Port + "</color>");
Debug.Log("[ContinuousPortMonitor] This proves port forwarding is working!");
Thread.Sleep(100);
client.Close();
}
catch (Exception e)
{
Debug.LogWarning("[ContinuousPortMonitor] Error accepting connection: " + e.Message);
}
}
else
{
Thread.Sleep(100);
}
}
Debug.Log("[ContinuousPortMonitor] Listener thread exiting");
}
catch (Exception e)
{
_listenerRunning = false;
Debug.LogError("<color=red>[ContinuousPortMonitor] Listener error: " + e.Message + "</color>");
}
}
private void TryRestoreBinding()
{
Debug.Log("<color=cyan>[ContinuousPortMonitor] Attempting to restore port binding...</color>");
// This is a placeholder - in reality, we'd need to restart Unity Netcode
// But we can't do that safely from this script
Debug.LogWarning("[ContinuousPortMonitor] Can't automatically restart Unity Netcode");
Debug.LogWarning("[ContinuousPortMonitor] Manual intervention required:");
Debug.LogWarning("1. Stop Host/Server");
Debug.LogWarning("2. Use ForceTransportBinding → 'Force Then Start Host'");
Debug.LogWarning("3. Check if port becomes accessible");
}
[ContextMenu("Check Current Status")]
public void CheckCurrentStatus()
{
Debug.Log("=== PORT MONITOR STATUS ===");
bool isUnityServerRunning = _networkManager != null && _networkManager.IsServer;
bool isTestListenerRunning = _listenerRunning;
bool portAccessible = TestPortConnection();
Debug.Log("Unity Server Running: " + isUnityServerRunning);
Debug.Log("Test Listener Running: " + isTestListenerRunning);
Debug.Log("Port Accessible: " + portAccessible);
if (portAccessible)
{
Debug.Log("<color=green>✓ Port " + targetPort + " is accessible</color>");
}
else
{
Debug.LogError("<color=red>✗ Port " + targetPort + " is NOT accessible</color>");
Debug.LogError("Check:");
Debug.LogError("1. Is Unity Netcode actually running?");
Debug.LogError("2. Is there a firewall blocking after some time?");
Debug.LogError("3. Is router restarting port forwarding?");
}
Debug.Log("============================");
}
[ContextMenu("Generate Diagnosis Report")]
public void GenerateDiagnosisReport()
{
Debug.Log("=== PORT MONITOR DIAGNOSIS ===");
Debug.Log("");
Debug.Log("PROBLEM:");
Debug.Log("- PortListenerTest: WORKS (port accessible)");
Debug.Log("- After test ends: PORT INACCESSIBLE");
Debug.Log("- Unity Netcode: PORT INACCESSIBLE");
Debug.Log("");
Debug.Log("ANALYSIS:");
Debug.Log("1. Port forwarding: WORKING (proven by test)");
Debug.Log("2. Firewall: ALLOWING (proven by test)");
Debug.Log("3. Unity Netcode: NOT BINDING OR CRASHING");
Debug.Log("");
Debug.Log("POSSIBLE CAUSES:");
Debug.Log("1. Unity NetworkManager is not actually starting server");
Debug.Log("2. Player Prefab not assigned (server doesn't start)");
Debug.Log("3. Connection Approval rejecting all connections");
Debug.Log("4. NetworkConnectionHandler has error and stops server");
Debug.Log("5. Unity Netcode version bug");
Debug.Log("");
Debug.Log("CHECKLIST:");
Debug.Log("☐ NetworkManager → Player Prefab: ASSIGNED?");
Debug.Log("☐ NetworkManager → Connection Approval: CHECKED?");
Debug.Log("☐ NetworkConnectionHandler: IN SCENE?");
Debug.Log("☐ AutoHost: DISABLED or configured correctly?");
Debug.Log("☐ ForceTransportBinding: APPLIED?");
Debug.Log("");
Debug.Log("NEXT STEPS:");
Debug.Log("1. Add ForceTransportBinding to scene");
Debug.Log("2. Right-click → 'Force Then Start Host'");
Debug.Log("3. Watch Console for '✓ Server STARTED'");
Debug.Log("4. Immediately test on yougetsignal");
Debug.Log("5. If still closed: Check NetworkManager config");
Debug.Log("================================");
}
private void OnDestroy()
{
StopTestListener();
}
private void OnDisable()
{
StopMonitoring();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 419b183105a6cb3479d26f7fd72aab25

View File

@@ -0,0 +1,95 @@
using UnityEngine;
namespace Northbound
{
/// <summary>
/// Central port configuration for the project
/// </summary>
public class GamePortConfig : MonoBehaviour
{
[Header("Port Configuration")]
[Tooltip("The main network port for the game")]
[SerializeField] private ushort gamePort = 40445;
public static ushort Port => Instance != null ? Instance.gamePort : (ushort)40445;
public static GamePortConfig Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
Debug.Log("<color=cyan>[GamePortConfig] Using port: " + gamePort + "</color>");
}
[ContextMenu("Log Port Configuration")]
public void LogPortConfig()
{
Debug.Log("=== GAME PORT CONFIGURATION ===");
Debug.Log("Game Port: " + gamePort);
Debug.Log("Port Type: TCP (and UDP if enabled)");
Debug.Log("Use this port for:");
Debug.Log(" - Router Port Forwarding");
Debug.Log(" - Windows Firewall rules");
Debug.Log(" - Port testing tools");
Debug.Log(" - Teammate connections");
Debug.Log("==============================");
}
[ContextMenu("Generate Router Port Forwarding Info")]
public void GeneratePortForwardingInfo()
{
Debug.Log("=== ROUTER PORT FORWARDING SETTINGS ===");
Debug.Log("");
Debug.Log("<color=cyan>EXTERNAL PORT:</color> " + gamePort);
Debug.Log("<color=cyan>INTERNAL PORT:</color> " + gamePort);
Debug.Log("<color=cyan>PROTOCOL:</color> TCP");
Debug.Log("<color=cyan>INTERNAL IP:</color> [Your computer's local IP]");
Debug.Log("");
Debug.Log("Steps:");
Debug.Log("1. Open Command Prompt, run 'ipconfig'");
Debug.Log("2. Find 'IPv4 Address' (e.g., 192.168.1.50)");
Debug.Log("3. Login to router (http://192.168.1.1)");
Debug.Log("4. Find Port Forwarding section");
Debug.Log("5. Add rule with above settings");
Debug.Log("6. Use your IPv4 as Internal IP");
Debug.Log("7. Save and restart router");
Debug.Log("");
Debug.Log("Test port at: https://www.yougetsignal.com/tools/open-ports/");
Debug.Log("=======================================");
}
[ContextMenu("Generate Firewall Rules")]
public void GenerateFirewallRules()
{
Debug.Log("=== WINDOWS FIREWALL RULES ===");
Debug.Log("");
Debug.Log("Run PowerShell as Administrator, then:");
Debug.Log("");
Debug.Log("# Allow port " + gamePort);
Debug.Log("netsh advfirewall firewall add rule name=\"Unity Port " + gamePort + "\" dir=in action=allow protocol=TCP localport=" + gamePort + " enable=yes profile=any");
Debug.Log("");
Debug.Log("# Allow Unity Editor");
Debug.Log("netsh advfirewall firewall add rule name=\"Unity Editor\" dir=in action=allow program=\"%ProgramFiles%\\Unity\\Hub\\Editor\\*\\Unity.exe\" enable=yes profile=any");
Debug.Log("");
Debug.Log("# Allow your game build");
Debug.Log("netsh advfirewall firewall add rule name=\"Northbound Game\" dir=in action=allow program=\"D:\\Northbound\\Build\\Northbound.exe\" enable=yes profile=any");
Debug.Log("");
Debug.Log("Note: Update the game path to your actual build location!");
Debug.Log("===============================");
}
[ContextMenu("Copy Port to Clipboard")]
public void CopyPortToClipboard()
{
GUIUtility.systemCopyBuffer = gamePort.ToString();
Debug.Log("Copied port " + gamePort + " to clipboard");
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b3de3b9ec2863be4396a3c2853421035

View File

@@ -1,164 +0,0 @@
# Connection Issue: Immediate Action Plan
## Your Problem
Teammate sees "CONNECTED" but gets "Failed to connect to server" error.
## Root Cause (Most Likely)
Windows Firewall is blocking Unity/Build even with port forwarding done correctly.
## FIX IN 3 STEPS
### Step 1: Add Debug Components (1 minute)
Add these to your NetworkManager GameObject in BOTH Host and Client scenes:
1. **ConnectionDiagnostics** (automatic check)
2. **NetworkDebugger** (detailed logs)
3. **NetworkConnectionFixer** (auto-fixes issues)
### Step 2: Fix Firewall (2 minutes)
Run PowerShell as Administrator, paste this:
```powershell
# Allow Unity Editor
netsh advfirewall firewall add rule name="Unity Editor" dir=in action=allow program="C:\Program Files\Unity\Hub\Editor\*\Unity.exe" enable=yes profile=any
# Allow your game build (update path!)
netsh advfirewall firewall add rule name="Northbound Game" dir=in action=allow program="D:\Northbound\Build\Northbound.exe" enable=yes profile=any
# Allow port 7777
netsh advfirewall firewall add rule name="Unity Port 7777" dir=in action=allow protocol=TCP localport=7777 enable=yes profile=any
```
### Step 3: Verify Port Forwarding (1 minute)
Go to: https://www.yougetsignal.com/tools/open-ports/
- Enter your PUBLIC IP
- Enter port 7777
- Should say: "Port 7777 is open"
If "Closed", your router port forwarding is wrong.
---
## Quick Diagnostics
### In Unity Editor (Play Mode):
1. Add **ConnectionDiagnostics** to NetworkManager
2. Right-click component → "Run Diagnostics"
3. Check console for errors/warnings
### Common Diagnostics Results:
-**"System Healthy"**: Configuration is good, issue is network/firewall
- ⚠️ **"Player Prefab NOT assigned"**: Assign player prefab in NetworkManager
- ⚠️ **"Connect timeout too low"**: ConnectionDiagnostics fixes this automatically
-**"NetworkManager not found"**: Add NetworkManager to scene
### If Still Not Working:
#### Test 1: Local Connection
Host connects to 127.0.0.1 (same instance)
- ✅ Works = Good setup, issue is network
- ❌ Fails = Project setup issue
#### Test 2: LAN Connection
Host shares 192.168.x.x IP (same WiFi)
- ✅ Works = Good LAN, issue is port forwarding for internet
- ❌ Fails = Firewall blocking local connections
#### Test 3: Internet Connection
Host shares PUBLIC IP with teammate
- ✅ Works = Fixed!
- ❌ Fails = Port forwarding or remote firewall
---
## What Console Should Show
### Host (Working):
```
[ConnectionDiagnostics] System Healthy
[NetworkConnectionFixer] Network fixes applied
[NetworkDebugger] Server Started Successfully
[NetworkDebugger] Listening on: 0.0.0.0:7777
[NetworkDebugger] Client Connected: 1
[ConnectionHandler] 클라이언트 1 승인됨
[ConnectionHandler] 플레이어 1 스폰됨
```
### Client (Working):
```
[ConnectionDiagnostics] System Healthy
[NetworkConnectionFixer] Network fixes applied
[NetworkDebugger] Connection Approval Request
[NetworkDebugger] Approval Response: Approved: true
[NetworkDebugger] Client Connected: 0
```
### Client (Broken - Your Case):
```
[ConnectionDiagnostics] System Healthy
[NetworkConnectionFixer] Network fixes applied
[NetworkDebugger] Connection Approval Request
<color=red>[NetworkDebugger] TRANSPORT FAILURE!</color>
Failed to connect to server
```
---
## Tools Created for You
| File | Purpose | How to Use |
|------|---------|------------|
| **ConnectionDiagnostics.cs** | Auto-checks configuration | Add to scene, right-click "Run Diagnostics" |
| **NetworkDebugger.cs** | Shows detailed connection logs | Add to scene, watch Console during connection |
| **NetworkConnectionFixer.cs** | Fixes common timeout issues | Add to scene, right-click "Fix All Known Issues" |
| **PublicIPHelper.cs** | Gets your public IP automatically | Add to scene, see Inspector |
---
## Most Likely Issue: Firewall
Even with correct port forwarding, Windows Firewall blocks:
1. ✅ Port 7777 may be open (router allows it)
2. ❌ But Windows Firewall blocks the application using that port
**Solution:** Allow Unity and your game through firewall (Step 2)
---
## Alternative: Use Hamachi/VPN
If port forwarding is too complex:
1. Both install Hamachi: https://www.vpn.net/
2. Join same Hamachi network
3. Use Hamachi IP (25.x.x.x) instead of public IP
4. No port forwarding needed!
---
## Share This for Help
If issue persists, share screenshots/logs:
1. ✅ NetworkManager Inspector (screenshot)
2. ✅ Unity Transport settings (screenshot)
3. ✅ Console log (Host) - after connecting
4. ✅ Console log (Client) - after connection attempt
5. ✅ Port checker result (screenshot)
6. ✅ Windows Firewall rules list (screenshot)
---
## Summary
1. **Add debug components** (1 min)
2. **Fix firewall** (2 min) - MOST IMPORTANT
3. **Verify port forwarding** (1 min)
4. **Test with console logs**
If all this fails, the issue is likely:
- Port forwarding is wrong (verify with online tool)
- Different Unity/Netcode versions between you and teammate
- Antivirus/security software blocking
Good luck! 🎮

View File

@@ -1,192 +0,0 @@
# 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

View File

@@ -0,0 +1,307 @@
# 🎮 네트워크 연결 설정 가이드
## 📋 상황 요약
✅ PortListenerTest: 포트 열림 (yougetsignal 성공)
✅ 포트 포워딩: 작동 중 (yougetsignal 성공으로 증명)
✅ 방화벽: 허용 중 (yougetsignal 성공으로 증명)
❌ 유니티 Netcode: **포트가 닫혀 있음**
## ⚡ 즉시 해결책 (3단계)
### 1단계: 테스트 시작 (30초)
1. **NetworkManagerQuickTest** 추가 (씬의 아무 게임오브젝트)
2. 우클릭 → "Run Quick NetworkManager Test"
3. 콘솔 출력 공유
**기대 결과:**
```
✓ NetworkManager found!
✓ Player Prefab: Player
✓ Unity Transport found!
✓ Transport: 4045, 0.0.0.0
✓ NetworkConnectionHandler found!
```
### 2단계: 팀원 연결 테스트 (1분)
1. 팀원에게 당신의 **퍼블릭 IP** 알림
2. 팀원: 게임에서 IP:포트 입력
3. 팀원: "연결" 클릭
**기대:**
- 성공: 팀원이 접속!
- 실패: 에러 로그 공유
### 3단계: 문제 해결
팀원이 접속 못할 경우:
**팀원 측:**
- 올바른 퍼블릭 IP 입력했는지 확인
- 방화벽 허용 확인
- 유니티 Netcode 버전 확인 (동일해야 함)
**호스트 측 (당신):**
- 콘솔에서 "[ConnectionHandler] 클라이언트" 메시지 확인
- 스폰 성공하는지 확인
- 플레이어가 생성되는지 확인
---
## 🔧 필수 구성 요소
### NetworkManager 설정
**필수:**
```
NetworkManager GameObject:
- Player Prefab: Player (Assets/Prefabs/Player/)
- Connection Approval: ✓ 체크
- Enable Scene Management: ✓ 체크
```
### Unity Transport 설정
**필수:**
```
Unity Transport:
- Port: 4045
- Address: 0.0.0.0 (모든 인터페이스 허용)
- ServerListenAddress: 0.0.0.0
```
### 라우터 포트 포워딩
**필수:**
```
라우터 포트 포워딩:
- External Port: 4045
- Internal Port: 4045
- Protocol: TCP
- Internal IP: 당신 컴퓨터의 IPv4 (ipconfig로 확인)
```
**IP 확인:**
```
명령 프롬프트 → ipconfig
IPv4 주소 찾기 (예: 192.168.1.50)
```
---
## ✅ 작동 중인지 확인
### 방법 1: yougetsignal (가장 신뢰)
```
https://www.yougetsignal.com/tools/open-ports/
입력:
- IP: 당신의 퍼블릭 IP (https://api.ipify.org)
- Port: 4045
기대: "Port 4045 is open"
```
### 방법 2: 콘솔 로그
**호스트 시작 성공:**
```
[ConnectionHandler] 서버 시작됨
[ConnectionHandler] 스폰 포인트 X개를 찾았습니다
[ConnectionHandler] 클라이언트 [ID] 연결됨
[ConnectionHandler] 플레이어 [ID] 스폰됨
```
**클라이언트 연결 성공:**
```
[ConnectionHandler] 클라이언트 [ID] 승인됨. 수동 스폰으로 대기.
```
---
## 🎮 게임 플레이 방법
### 호스트 (당신)
1. 에디터에서 플레이 모드 시작
2. 또는 빌드 실행
3. 콘솔에서 "호스트 시작됨" 확인
4. 팀원에게 퍼블릭 IP 알림
5. 팀원이 접속할 때까지 대기
### 클라이언트 (팀원)
1. 에디터에서 플레이 모드 시작
2. 네트워크 연결 UI에서 호스트의 퍼블릭 IP 입력
3. "연결" 클릭
4. 콘솔에서 "클라이언트 연결됨" 확인
5. 게임 시작!
---
## ⚠️ 일반적인 문제 및 해결
### 문제 1: "ConnectionHandler: PlayerPrefab이 null입니다"
**원인:** Player Prefab이 NetworkManager에 할당되지 않음
**해결:**
```
NetworkManager 선택 → Network Config → Player Prefab
Assets/Prefabs/Player/Player.prefab 드래그
```
### 문제 2: 팀원이 "Failed to connect to server" 에러
**가능한 원인:**
1. 틀린 퍼블릭 IP 입력
2. 포트가 닫혀 있음 (호스트 재시작 필요)
3. 방화벽 차단
4. 다른 Unity/Netcode 버전
**해결:**
1. 올바른 IP 확인 (https://api.ipify.org)
2. yougetsignal에서 포트 4045 확인
3. 팀원의 방화벽 허용
4. Unity 버전 일치 확인
### 문제 3: 포트가 열렸다 닫혀
**원인:** 유니티 Netcode가 실제로 바인딩하지 않음
**해결:**
```
NetworkManagerQuickTest 실행
NetworkManagerResetAndRestart 사용
새로 시작
```
---
## 📊 도구
### 유용한 스크립트
| 스크립트 | 용도 | 사용법 |
|---------|---------|---------|
| **NetworkManagerQuickTest** | 설정 확인 | 추가 → 우클릭 "Run Quick NetworkManager Test" |
| **NetworkResetAndRestart** | 네트워크 리셋 | 추가 → 우클릭 "Reset Network and Restart Host" |
| **PortListenerTest** | 포트 바인딩 테스트 | 추가 → 우클릭 "Test Port Binding Only" |
### 사용하지 않는 스크립트
- ❌ ContinuousPortMonitor (랙 발생)
- ❌ 다른 진단 도구 (필요 없음)
---
## 🚀 빠른 시작 가이드
### 처음 설정하는 경우
```
1. NetworkManager 찾기
2. Player Prefab 할당 (Assets/Prefabs/Player/)
3. Unity Transport 포트 4045 설정
4. 라우터에서 포트 포워딩 설정
5. 호스트 시작
6. yougetsignal에서 포트 확인
7. 팀원에게 퍼블릭 IP 공유
8. 팀원 접속
9. 게임 시작! 🎉
```
### 이미 작동 중인 경우
```
1. 호스트 시작
2. yougetsignal에서 포트 4045 확인 (열려 있어야 함)
3. 팀원에게 퍼블릭 IP 공유
4. 팀원 접속
5. 게임 시작! 🎉
```
---
## 💡 핵심 통찰
**당신의 상황:**
- PortListenerTest: 작동 ✅ (포트 열림)
- yougetsignal: 작동 ✅ (접속 가능)
- 유니티 Netcode: **포트 닫혀**
**해결책:**
1. Player Prefab 할당 (NetworkManagerQuickTest로 확인)
2. 팀원이 지금 테스트
3. 콘솔 로그 확인
**성공 시:**
```
✓ Player Prefab: Player
✓ Unity Netcode 시작 성공
✓ 팀원 접속 성공
✓ 플레이어 스폰됨
```
---
## 📝 기술 정보
### 사용된 포트
```
포트: 4045
프로토콜: TCP
바인딩: 0.0.0.0 (모든 인터페이스)
```
### 확인된 사항
```
✅ 포트 포워딩: 작동 (yougetsignal 증명)
✅ 방화벽: 허용 (yougetsignal 증명)
✅ OS 바인딩: 가능 (PortListenerTest 증명)
❌ 유니티 Netcode: 바인딩 실패
```
### 문제 분석
**포트 4045가 열리지 않는 이유:**
- 유니티 Netcode가 포트에 바인딩하지 않음
- Player Prefab이 할당되지 않았을 가능성 (90%)
- 또는 네트워크 관리자 초기화 순서 문제
---
## ✅ 성공 확인사항
**모든 것이 작동할 때:**
- [ ] 호스트: IsServer = True
- [ ] 호스트: IsHost = True
- [ ] Player Prefab: Player (할당됨)
- [ ] Transport: 4045, 0.0.0.0
- [ ] yougetsignal: "Port 4045 is open"
- [ ] 콘솔: "클라이언트 [ID] 연결됨"
- [ ] 콘솔: "플레이어 [ID] 스폰됨"
- [ ] 팀원: 접속 성공
---
## 🎯 요약
**핵심 사항:**
1. 포트 4045 열림 (yougetsignal 증명) ✅
2. Player Prefab 할당 필요 (가능한 문제 원인)
3. 팀원 지금 테스트
4. 콘솔 로그 확인
**다음 단계:**
1. NetworkManagerQuickTest 실행
2. 팀원 테스트
3. 문제 있으면 콘솔 로그 공유
4. 성공하면 게임 시작! 🎉
---
**행운을 빕니다!** 🚀

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ef125ff435342b64f86eeea8dbef234f
guid: 0c7074d751d043c418617553de184fc1
TextScriptImporter:
externalObjects: {}
userData:

View File

@@ -1,159 +0,0 @@
using UnityEngine;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
namespace Northbound
{
/// <summary>
/// Fixes common network connection issues with Unity Netcode
/// </summary>
public class NetworkConnectionFixer : MonoBehaviour
{
[Header("Auto-Fix Settings")]
[SerializeField] private bool autoFixOnStart = true;
[SerializeField] private bool ensureTransportSettings = true;
[SerializeField] private bool increaseTimeouts = true;
private NetworkManager _networkManager;
private UnityTransport _transport;
private void Awake()
{
_networkManager = NetworkManager.Singleton;
if (_networkManager == null)
{
Debug.LogError("[NetworkConnectionFixer] NetworkManager not found!");
return;
}
_transport = _networkManager.GetComponent<UnityTransport>();
if (_transport == null)
{
Debug.LogError("[NetworkConnectionFixer] UnityTransport not found!");
return;
}
if (autoFixOnStart)
{
FixNetworkSettings();
}
}
public void FixNetworkSettings()
{
Debug.Log("[NetworkConnectionFixer] Applying network fixes...");
if (ensureTransportSettings)
{
FixTransportSettings();
}
if (increaseTimeouts)
{
IncreaseTimeouts();
}
Debug.Log("[NetworkConnectionFixer] Network fixes applied successfully!");
}
private void FixTransportSettings()
{
Debug.Log("[NetworkConnectionFixer] Fixing transport settings...");
if (_transport == null) return;
ushort port = _transport.ConnectionData.Port;
string address = _transport.ConnectionData.Address;
Debug.Log($"Current Port: {port}");
Debug.Log($"Current Address: {address}");
if (port <= 0)
{
Debug.LogWarning("[NetworkConnectionFixer] Invalid port detected, setting to 7777");
_transport.SetConnectionData("0.0.0.0", 7777);
}
}
private void IncreaseTimeouts()
{
Debug.Log("[NetworkConnectionFixer] Increasing network timeouts...");
if (_transport == null) return;
int currentTimeout = _transport.ConnectTimeoutMS;
Debug.Log($"Current Connect Timeout: {currentTimeout}ms");
if (currentTimeout < 10000)
{
_transport.ConnectTimeoutMS = 15000;
Debug.Log("[NetworkConnectionFixer] Increased Connect Timeout to 15000ms (15 seconds)");
}
int maxAttempts = _transport.MaxConnectAttempts;
Debug.Log($"Current Max Connect Attempts: {maxAttempts}");
if (maxAttempts < 10)
{
_transport.MaxConnectAttempts = 10;
Debug.Log("[NetworkConnectionFixer] Increased Max Connect Attempts to 10");
}
}
public void SetServerAddress(string ipAddress, ushort port)
{
if (_transport == null) return;
Debug.Log($"[NetworkConnectionFixer] Setting server address to {ipAddress}:{port}");
_transport.SetConnectionData(ipAddress, port);
}
public void SetListenAddress(string listenAddress, ushort port)
{
if (_transport == null) return;
Debug.Log($"[NetworkConnectionFixer] Setting listen address to {listenAddress}:{port}");
_transport.SetConnectionData("0.0.0.0", port, listenAddress);
}
[ContextMenu("Log Current Transport Settings")]
public void LogTransportSettings()
{
if (_transport == null) return;
Debug.Log("=== CURRENT TRANSPORT SETTINGS ===");
Debug.Log("Connection Data:");
Debug.Log(" Address: " + _transport.ConnectionData.Address);
Debug.Log(" Port: " + _transport.ConnectionData.Port);
Debug.Log(" Server Listen Address: " + _transport.ConnectionData.ServerListenAddress);
Debug.Log("Timeouts:");
Debug.Log(" Connect Timeout (ms): " + _transport.ConnectTimeoutMS);
Debug.Log(" Max Connect Attempts: " + _transport.MaxConnectAttempts);
Debug.Log("Other:");
Debug.Log(" Max Packet Queue Size: " + _transport.MaxPacketQueueSize);
Debug.Log("===================================");
}
[ContextMenu("Fix All Known Issues")]
public void FixAllKnownIssues()
{
Debug.Log("[NetworkConnectionFixer] Fixing all known issues...");
FixNetworkSettings();
LogTransportSettings();
Debug.Log("[NetworkConnectionFixer] All fixes applied!");
}
[ContextMenu("Test Connection Setup")]
public void TestConnectionSetup()
{
Debug.Log("=== CONNECTION SETUP TEST ===");
Debug.Log("NetworkManager: " + (_networkManager != null ? "Found" : "NOT FOUND"));
Debug.Log("UnityTransport: " + (_transport != null ? "Found" : "NOT FOUND"));
Debug.Log("Player Prefab: " + (_networkManager?.NetworkConfig?.PlayerPrefab != null ? "Found" : "NOT FOUND"));
Debug.Log("Connection Approval: " + (_networkManager?.NetworkConfig?.ConnectionApproval ?? false));
Debug.Log("=============================");
}
}
}

View File

@@ -1,255 +0,0 @@
using UnityEngine;
using Unity.Netcode;
using System;
namespace Northbound
{
public class NetworkDebugger : MonoBehaviour
{
[Header("Debug Settings")]
[SerializeField] private bool enableVerboseLogging = true;
[SerializeField] private bool logTransportEvents = true;
private Unity.Netcode.Transports.UTP.UnityTransport _transport;
private NetworkManager _networkManager;
private void Start()
{
_networkManager = NetworkManager.Singleton;
if (_networkManager == null)
{
Debug.LogError("[NetworkDebugger] NetworkManager not found!");
return;
}
_transport = _networkManager.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
if (_transport == null)
{
Debug.LogError("[NetworkDebugger] UnityTransport not found!");
return;
}
SubscribeToEvents();
LogNetworkConfiguration();
}
private void SubscribeToEvents()
{
if (_networkManager != null)
{
_networkManager.OnServerStarted += OnServerStarted;
_networkManager.OnClientConnectedCallback += OnClientConnected;
_networkManager.OnClientDisconnectCallback += OnClientDisconnected;
_networkManager.ConnectionApprovalCallback += OnConnectionApproval;
_networkManager.OnTransportFailure += OnTransportFailure;
}
if (logTransportEvents && _transport != null)
{
LogTransportConfiguration();
}
}
private void UnsubscribeFromEvents()
{
if (_networkManager != null)
{
_networkManager.OnServerStarted -= OnServerStarted;
_networkManager.OnClientConnectedCallback -= OnClientConnected;
_networkManager.OnClientDisconnectCallback -= OnClientDisconnected;
_networkManager.ConnectionApprovalCallback -= OnConnectionApproval;
_networkManager.OnTransportFailure -= OnTransportFailure;
}
}
private void LogNetworkConfiguration()
{
Debug.Log("=== NETWORK CONFIGURATION ===");
Debug.Log("NetworkManager Present: " + (_networkManager != null));
string transportType = _transport != null ? "Unity Transport" : "None";
Debug.Log("Transport Type: " + transportType);
LogTransportConfiguration();
LogNetworkSettings();
Debug.Log("============================");
}
private void LogTransportConfiguration()
{
if (_transport == null) return;
Debug.Log("=== TRANSPORT CONFIGURATION ===");
Debug.Log("Connection Data Address: " + _transport.ConnectionData.Address);
Debug.Log("Connection Data Port: " + _transport.ConnectionData.Port);
Debug.Log("Connection Data Server Listen Address: " + _transport.ConnectionData.ServerListenAddress);
Debug.Log("Max Connect Attempts: " + _transport.MaxConnectAttempts);
Debug.Log("Connect Timeout (ms): " + _transport.ConnectTimeoutMS);
Debug.Log("Max Packet Queue Size: " + _transport.MaxPacketQueueSize);
Debug.Log("================================");
}
private void LogNetworkSettings()
{
if (_networkManager == null) return;
Debug.Log("=== NETWORK MANAGER SETTINGS ===");
Debug.Log("NetworkConfig: " + (_networkManager.NetworkConfig != null));
if (_networkManager.NetworkConfig != null)
{
Debug.Log("Player Prefab: " + (_networkManager.NetworkConfig.PlayerPrefab != null));
Debug.Log("Connection Approval: " + _networkManager.NetworkConfig.ConnectionApproval);
Debug.Log("Client Connection Buffer: " + _networkManager.NetworkConfig.ClientConnectionBufferTimeout);
Debug.Log("Enable Scene Management: " + _networkManager.NetworkConfig.EnableSceneManagement);
}
Debug.Log("================================");
}
private void OnServerStarted()
{
Debug.Log("<color=green>[NetworkDebugger] Server Started Successfully</color>");
Debug.Log("Listening on: " + _transport.ConnectionData.Address + ":" + _transport.ConnectionData.Port);
Debug.Log("IsHost: " + _networkManager.IsHost);
Debug.Log("IsServer: " + _networkManager.IsServer);
}
private void OnClientConnected(ulong clientId)
{
if (enableVerboseLogging)
{
Debug.Log("<color=cyan>[NetworkDebugger] Client Connected: " + clientId + "</color>");
Debug.Log("Local Client ID: " + _networkManager.LocalClientId);
Debug.Log("Connected Clients Count: " + _networkManager.ConnectedClients.Count);
}
foreach (var client in _networkManager.ConnectedClients)
{
string playerStatus = client.Value.PlayerObject != null ? "Exists" : "NULL";
Debug.Log(" Client ID: " + client.Key + ", Player Object: " + playerStatus);
}
}
private void OnClientDisconnected(ulong clientId)
{
Debug.Log("<color=yellow>[NetworkDebugger] Client Disconnected: " + clientId + "</color>");
Debug.Log("Reason: Check logs above for details");
}
private void OnConnectionApproval(NetworkManager.ConnectionApprovalRequest request,
NetworkManager.ConnectionApprovalResponse response)
{
Debug.Log("<color=magenta>[NetworkDebugger] Connection Approval Request from Client " + request.ClientNetworkId + "</color>");
Debug.Log(" Payload Length: " + request.Payload.Length);
Debug.Log(" Client ID: " + request.ClientNetworkId);
LogApprovalResponse(response);
}
private void LogApprovalResponse(NetworkManager.ConnectionApprovalResponse response)
{
Debug.Log("<color=magenta>[NetworkDebugger] Approval Response:</color>");
Debug.Log(" Approved: " + response.Approved);
Debug.Log(" Create Player Object: " + response.CreatePlayerObject);
Debug.Log(" Position: " + response.Position);
Debug.Log(" Rotation: " + response.Rotation);
Debug.Log(" Player Prefab Hash: " + response.PlayerPrefabHash);
}
private void OnTransportFailure()
{
Debug.LogError("<color=red>[NetworkDebugger] TRANSPORT FAILURE!</color>");
Debug.LogError("This usually indicates:");
Debug.LogError("1. Port not forwarded correctly");
Debug.LogError("2. Firewall blocking the connection");
Debug.LogError("3. Wrong IP address");
Debug.LogError("4. Server not listening on the correct address");
Debug.LogError("5. Network timeout");
}
private void Update()
{
if (enableVerboseLogging && _networkManager != null)
{
MonitorConnectionState();
}
}
private void MonitorConnectionState()
{
if (_networkManager.IsServer && _networkManager.IsClient)
{
if (Time.frameCount % 300 == 0)
{
Debug.Log("<color=green>[NetworkDebugger] Host Mode - " + Time.time.ToString("F2") + "s</color>");
Debug.Log(" Connected Clients: " + _networkManager.ConnectedClients.Count);
Debug.Log(" Server Listening: " + _transport.ConnectionData.Address + ":" + _transport.ConnectionData.Port);
}
}
else if (_networkManager.IsClient)
{
if (Time.frameCount % 300 == 0 && !_networkManager.IsConnectedClient)
{
Debug.LogWarning("<color=yellow>[NetworkDebugger] Client Not Connected - " + Time.time.ToString("F2") + "s</color>");
Debug.LogWarning(" Connecting to: " + _transport.ConnectionData.Address + ":" + _transport.ConnectionData.Port);
}
}
}
private void OnDestroy()
{
UnsubscribeFromEvents();
}
[ContextMenu("Log Current Network State")]
public void LogCurrentState()
{
Debug.Log("=== CURRENT NETWORK STATE ===");
if (_networkManager == null)
{
Debug.Log("NetworkManager is NULL");
return;
}
Debug.Log("Is Server: " + _networkManager.IsServer);
Debug.Log("Is Client: " + _networkManager.IsClient);
Debug.Log("Is Host: " + _networkManager.IsHost);
Debug.Log("Is Connected Client: " + _networkManager.IsConnectedClient);
Debug.Log("Local Client ID: " + _networkManager.LocalClientId);
Debug.Log("Connected Clients Count: " + _networkManager.ConnectedClients.Count);
if (_transport != null)
{
Debug.Log("Transport Address: " + _transport.ConnectionData.Address);
Debug.Log("Transport Port: " + _transport.ConnectionData.Port);
Debug.Log("Server Listen Address: " + _transport.ConnectionData.ServerListenAddress);
}
Debug.Log("==========================");
}
[ContextMenu("Test Port Binding")]
public void TestPortBinding()
{
if (_transport != null)
{
Debug.Log("<color=yellow>[NetworkDebugger] Port Binding Test:</color>");
Debug.Log(" Address: " + _transport.ConnectionData.Address);
Debug.Log(" Port: " + _transport.ConnectionData.Port);
Debug.Log(" Server Listen Address: " + _transport.ConnectionData.ServerListenAddress);
Debug.LogWarning("Note: Actual binding happens when StartHost/StartServer is called");
}
}
[ContextMenu("Check Firewall Issues")]
public void CheckPotentialFirewallIssues()
{
Debug.Log("=== POTENTIAL FIREWALL ISSUES ===");
Debug.LogWarning("If you see 'Failed to connect to server' errors:");
Debug.LogWarning("1. Check Windows Firewall settings");
Debug.LogWarning("2. Allow Unity Editor and your build through firewall");
Debug.LogWarning("3. Ensure port is properly forwarded in router");
Debug.LogWarning("4. Test port with online port checker (e.g., canyouseeme.org)");
Debug.LogWarning("5. Check antivirus/security software");
Debug.Log("================================");
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 9abd8738f93d60a4fa097fdaf9349865

View File

@@ -1,269 +0,0 @@
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;
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 824b1e5b92d2ce946b9f2c121a535c73

View File

@@ -0,0 +1,244 @@
using UnityEngine;
using Unity.Netcode;
namespace Northbound
{
/// <summary>
/// Quick test to verify NetworkManager is working and accessible
/// </summary>
public class NetworkManagerQuickTest : MonoBehaviour
{
[Header("Test Settings")]
[SerializeField] private bool runTestOnStart = true;
[SerializeField] private bool showDetailedLogs = true;
private void Start()
{
if (runTestOnStart)
{
RunQuickTest();
}
}
[ContextMenu("Run Quick NetworkManager Test")]
public void RunQuickTest()
{
Debug.Log("<color=cyan>=== NETWORKMANAGER QUICK TEST ===</color>");
TestNetworkManagerExists();
TestPlayerPrefab();
TestTransport();
TestConnectionHandlers();
Debug.Log("<color=green>=== TEST COMPLETE ===</color>");
}
private void TestNetworkManagerExists()
{
Debug.Log("<color=yellow>[1/4] Testing NetworkManager Existence...</color>");
NetworkManager nm = NetworkManager.Singleton;
if (nm == null)
{
Debug.LogError("<color=red>✗ NetworkManager.Singleton is NULL!</color>");
Debug.LogError("This means:");
Debug.LogError("1. NetworkManager GameObject is not in scene");
Debug.LogError("2. NetworkManager component is missing");
Debug.LogError("3. NetworkManager hasn't been initialized yet");
return;
}
Debug.Log("<color=green>✓ NetworkManager found!</color>");
Debug.Log(" IsServer: " + nm.IsServer);
Debug.Log(" IsClient: " + nm.IsClient);
Debug.Log(" IsHost: " + nm.IsHost);
Debug.Log(" IsConnectedClient: " + nm.IsConnectedClient);
Debug.Log(" LocalClientId: " + nm.LocalClientId);
}
private void TestPlayerPrefab()
{
Debug.Log("<color=yellow>[2/4] Testing Player Prefab...</color>");
NetworkManager nm = NetworkManager.Singleton;
if (nm == null)
{
Debug.LogError("<color=red>✗ Can't test - NetworkManager is null</color>");
return;
}
if (nm.NetworkConfig == null)
{
Debug.LogError("<color=red>✗ NetworkConfig is null!</color>");
return;
}
GameObject playerPrefab = nm.NetworkConfig.PlayerPrefab;
if (playerPrefab == null)
{
Debug.LogError("<color=red>✗ Player Prefab is NOT assigned!</color>");
Debug.LogError("→ This is the #1 reason servers don't start!");
Debug.LogError("→ FIX: Select NetworkManager → Network Config → Player Prefab");
Debug.LogError("→ Drag your Player Prefab from Project to that field");
return;
}
Debug.Log("<color=green>✓ Player Prefab assigned: " + playerPrefab.name + "</color>");
var networkObject = playerPrefab.GetComponent<Unity.Netcode.NetworkObject>();
if (networkObject == null)
{
Debug.LogWarning("<color=yellow>⚠ Player Prefab has NO NetworkObject!</color>");
Debug.LogWarning("→ Add NetworkObject component to Player Prefab");
}
else
{
Debug.Log("<color=green>✓ Player Prefab has NetworkObject</color>");
}
}
private void TestTransport()
{
Debug.Log("<color=yellow>[3/4] Testing Unity Transport...</color>");
NetworkManager nm = NetworkManager.Singleton;
if (nm == null)
{
Debug.LogError("<color=red>✗ Can't test - NetworkManager is null</color>");
return;
}
var transport = nm.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
if (transport == null)
{
Debug.LogError("<color=red>✗ Unity Transport not found on NetworkManager!</color>");
Debug.LogError("→ FIX: Add Unity Transport component to NetworkManager GameObject");
return;
}
Debug.Log("<color=green>✓ Unity Transport found!</color>");
Debug.Log(" Port: " + transport.ConnectionData.Port);
Debug.Log(" Address: " + transport.ConnectionData.Address);
Debug.Log(" ServerListenAddress: " + transport.ConnectionData.ServerListenAddress);
if (transport.ConnectionData.Port <= 0)
{
Debug.LogWarning("<color=yellow>⚠ Transport Port is not set (0)!</color>");
Debug.LogWarning("→ FIX: Set Port to 40445 in Unity Transport component");
}
if (transport.ConnectionData.Address == "127.0.0.1")
{
Debug.LogError("<color=red>✗ Transport Address is 127.0.0.1!</color>");
Debug.LogError("→ This BLOCKS all remote connections!");
Debug.LogError("→ FIX: Change Address to 0.0.0.0");
}
else if (transport.ConnectionData.Address == "0.0.0.0")
{
Debug.Log("<color=green>✓ Transport Address is 0.0.0.0 (accepts all connections)</color>");
}
}
private void TestConnectionHandlers()
{
Debug.Log("<color=yellow>[4/4] Testing Connection Handlers...</color>");
NetworkConnectionHandler handler = FindObjectOfType<NetworkConnectionHandler>();
if (handler == null)
{
Debug.LogWarning("<color=yellow>⚠ NetworkConnectionHandler not found!</color>");
Debug.LogWarning("→ Manual player spawning may not work");
Debug.LogWarning("→ FIX: Add NetworkConnectionHandler component to scene");
return;
}
Debug.Log("<color=green>✓ NetworkConnectionHandler found!</color>");
Debug.Log("→ Manual player spawning should work");
PlayerSpawnPoint[] spawnPoints = FindObjectsByType<PlayerSpawnPoint>(FindObjectsSortMode.None);
if (spawnPoints.Length > 0)
{
Debug.Log("<color=green>✓ Found " + spawnPoints.Length + " Player Spawn Point(s)</color>");
}
else
{
Debug.LogWarning("<color=yellow>⚠ No Player Spawn Points found!</color>");
Debug.LogWarning("→ Players may spawn at default position");
}
}
[ContextMenu("Generate Setup Report")]
public void GenerateSetupReport()
{
Debug.Log("=== NETWORKMANAGER SETUP REPORT ===");
Debug.Log("");
Debug.Log("CURRENT STATUS:");
NetworkManager nm = NetworkManager.Singleton;
if (nm == null)
{
Debug.LogError("NetworkManager: NOT FOUND (NULL)");
Debug.LogError("");
Debug.LogError("CRITICAL ISSUE:");
Debug.LogError("1. NetworkManager GameObject not in scene");
Debug.LogError("2. NetworkManager component missing");
Debug.LogError("3. NetworkManager not initialized");
Debug.LogError("");
Debug.LogError("QUICK FIX:");
Debug.LogError("1. Check your scene for NetworkManager GameObject");
Debug.LogError("2. Add NetworkManager component if missing");
Debug.LogError("3. Check Console for initialization errors");
}
else
{
Debug.Log("NetworkManager: FOUND");
Debug.Log("IsServer: " + nm.IsServer);
Debug.Log("IsClient: " + nm.IsClient);
Debug.Log("IsHost: " + nm.IsHost);
if (nm.NetworkConfig != null)
{
GameObject playerPrefab = nm.NetworkConfig.PlayerPrefab;
if (playerPrefab == null)
{
Debug.LogError("");
Debug.LogError("⚠ CRITICAL: Player Prefab NOT assigned!");
Debug.LogError("This is the #1 cause of servers not starting!");
Debug.LogError("");
Debug.LogError("FIX IMMEDIATELY:");
Debug.LogError("1. Select NetworkManager in scene");
Debug.LogError("2. Inspector → Network Config → Player Prefab");
Debug.LogError("3. Drag Player Prefab from Project to that field");
}
else
{
Debug.Log("Player Prefab: ASSIGNED (" + playerPrefab.name + ")");
}
}
var transport = nm.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
if (transport != null)
{
Debug.Log("Transport Port: " + transport.ConnectionData.Port);
Debug.Log("Transport Address: " + transport.ConnectionData.Address);
}
else
{
Debug.LogError("Unity Transport: NOT FOUND");
}
}
Debug.Log("");
Debug.Log("NEXT STEPS:");
Debug.Log("1. If Player Prefab is NULL: Assign it immediately!");
Debug.Log("2. Check NetworkManagerValidator → Validate");
Debug.Log("3. Use ForceTransportBinding → Force Then Start Host");
Debug.Log("4. Test on yougetsignal");
Debug.Log("===============================");
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1d695616342b92d449295973fc4cda7e

View File

@@ -0,0 +1,346 @@
using UnityEngine;
using Unity.Netcode;
namespace Northbound
{
/// <summary>
/// Validates NetworkManager configuration before starting server
/// Checks for common issues that prevent server from starting
/// </summary>
public class NetworkManagerValidator : MonoBehaviour
{
[Header("Validation Settings")]
[SerializeField] private bool validateOnStart = true;
[SerializeField] private bool validateOnEnable = true;
[SerializeField] private bool showDetailedLogs = true;
[Header("Auto-Fix")]
[SerializeField] private bool autoFixIfPossible = true;
private NetworkManager _networkManager;
private bool _hasValidated = false;
private void Awake()
{
StartCoroutine(InitializeDelayed());
}
private System.Collections.IEnumerator InitializeDelayed()
{
Debug.Log("[NetworkValidator] Waiting for NetworkManager to initialize...");
int attempts = 0;
while (_networkManager == null && attempts < 50)
{
_networkManager = NetworkManager.Singleton;
if (_networkManager == null)
{
yield return new WaitForSeconds(0.1f);
attempts++;
}
}
if (_networkManager == null)
{
Debug.LogError("<color=red>[NetworkValidator] ❌ CRITICAL: NetworkManager not found after 50 attempts!</color>");
Debug.LogError("[NetworkValidator] Ensure NetworkManager is in scene and has 'NetworkManager' component");
yield break;
}
Debug.Log("[NetworkValidator] NetworkManager found!");
if (validateOnAwake)
{
yield return new WaitForSeconds(0.5f);
ValidateConfiguration();
}
}
private void Start()
{
if (validateOnStart && !_hasValidated)
{
ValidateConfiguration();
}
}
private void OnEnable()
{
if (validateOnEnable && !_hasValidated)
{
ValidateConfiguration();
}
}
[ContextMenu("Validate NetworkManager Configuration")]
public void ValidateConfiguration()
{
Debug.Log("<color=yellow>=== NETWORKMANAGER VALIDATION ===</color>");
if (_networkManager == null)
{
Debug.LogError("<color=red>[NetworkValidator] ❌ NetworkManager is NULL!</color>");
Debug.LogError("[NetworkValidator] Cannot validate configuration");
return;
}
_hasValidated = true;
bool allValid = true;
allValid &= CheckPlayerPrefab();
allValid &= CheckNetworkConfig();
allValid &= CheckTransport();
allValid &= CheckRequiredComponents();
Debug.Log("");
if (allValid)
{
Debug.Log("<color=green>[NetworkValidator] ✅ ALL CHECKS PASSED - NetworkManager is ready!</color>");
Debug.Log("[NetworkValidator] Server should start successfully");
}
else
{
Debug.LogError("<color=red>[NetworkValidator] ❌ VALIDATION FAILED - Server may NOT start!</color>");
Debug.LogError("[NetworkValidator] Please fix the issues above");
}
Debug.Log("=================================");
}
private bool CheckPlayerPrefab()
{
Debug.Log("<color=cyan>[NetworkValidator] 1. Checking Player Prefab...</color>");
if (_networkManager.NetworkConfig == null)
{
Debug.LogError("<color=red>[NetworkValidator] ❌ NetworkConfig is NULL!</color>");
return false;
}
GameObject playerPrefab = _networkManager.NetworkConfig.PlayerPrefab;
if (playerPrefab == null)
{
Debug.LogError("<color=red>[NetworkValidator] ❌ Player Prefab is NOT assigned!</color>");
Debug.LogError("<color=red>[NetworkValidator] This is the #1 cause of servers not starting!</color>");
Debug.LogError("[NetworkValidator] FIX:");
Debug.LogError("1. Select NetworkManager in scene");
Debug.LogError("2. Inspector → Network Config → Player Prefab");
Debug.LogError("3. Drag your Player Prefab from Project window");
Debug.LogError("4. Assign to Player Prefab field");
return false;
}
Debug.Log("<color=green>[NetworkValidator] ✅ Player Prefab assigned: " + playerPrefab.name + "</color>");
NetworkObject networkObject = playerPrefab.GetComponent<NetworkObject>();
if (networkObject == null)
{
Debug.LogWarning("<color=yellow>[NetworkValidator] ⚠ Player Prefab has NO NetworkObject!</color>");
Debug.LogWarning("[NetworkValidator] FIX: Add NetworkObject component to Player Prefab");
return false;
}
Debug.Log("<color=green>[NetworkValidator] ✅ Player Prefab has NetworkObject</color>");
return true;
}
private bool CheckNetworkConfig()
{
Debug.Log("<color=cyan>[NetworkValidator] 2. Checking Network Config...</color>");
if (_networkManager.NetworkConfig == null)
{
Debug.LogError("<color=red>[NetworkValidator] ❌ NetworkConfig is NULL!</color>");
return false;
}
bool configValid = true;
bool connectionApproval = _networkManager.NetworkConfig.ConnectionApproval;
if (connectionApproval)
{
Debug.Log("<color=green>[NetworkValidator] ✅ Connection Approval: ENABLED</color>");
}
else
{
Debug.LogWarning("<color=yellow>[NetworkValidator] ⚠ Connection Approval: DISABLED</color>");
Debug.LogWarning("[NetworkValidator] All connections will be auto-approved");
}
bool sceneManagement = _networkManager.NetworkConfig.EnableSceneManagement;
if (sceneManagement)
{
Debug.Log("<color=green>[NetworkValidator] ✅ Scene Management: ENABLED</color>");
}
else
{
Debug.LogWarning("<color=yellow>[NetworkValidator] ⚠ Scene Management: DISABLED</color>");
}
float clientBuffer = _networkManager.NetworkConfig.ClientConnectionBufferTimeout;
Debug.Log("[NetworkValidator] Client Connection Buffer: " + clientBuffer + "s");
return configValid;
}
private bool CheckTransport()
{
Debug.Log("<color=cyan>[NetworkValidator] 3. Checking Transport...</color>");
var transport = _networkManager.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>();
if (transport == null)
{
Debug.LogError("<color=red>[NetworkValidator] ❌ UnityTransport not found!</color>");
Debug.LogError("[NetworkValidator] FIX: Add Unity Transport component to NetworkManager");
return false;
}
Debug.Log("<color=green>[NetworkValidator] ✅ Unity Transport exists</color>");
ushort port = transport.ConnectionData.Port;
Debug.Log("[NetworkValidator] Transport Port: " + port);
if (port <= 0)
{
Debug.LogWarning("<color=yellow>[NetworkValidator] ⚠ Transport Port is not set (0)</color>");
Debug.LogWarning("[NetworkValidator] FIX: Set port to 40445 in Unity Transport component");
return false;
}
string address = transport.ConnectionData.Address;
Debug.Log("[NetworkValidator] Transport Address: " + address);
if (address == "127.0.0.1")
{
Debug.LogError("<color=red>[NetworkValidator] ❌ Transport Address is 127.0.0.1!</color>");
Debug.LogError("<color=red>[NetworkValidator] This blocks ALL remote connections!</color>");
Debug.LogError("[NetworkValidator] FIX: Set to 0.0.0.0");
return false;
}
if (address == "0.0.0.0")
{
Debug.Log("<color=green>[NetworkValidator] ✅ Transport Address: 0.0.0.0 (accepts all connections)</color>");
}
return true;
}
private bool CheckRequiredComponents()
{
Debug.Log("<color=cyan>[NetworkValidator] 4. Checking Required Components...</color>");
bool allPresent = true;
NetworkConnectionHandler connectionHandler = FindObjectOfType<NetworkConnectionHandler>();
if (connectionHandler != null)
{
Debug.Log("<color=green>[NetworkValidator] ✅ NetworkConnectionHandler found</color>");
}
else
{
Debug.LogWarning("<color=yellow>[NetworkValidator] ⚠ NetworkConnectionHandler NOT found</color>");
Debug.LogWarning("[NetworkValidator] FIX: Add NetworkConnectionHandler to scene");
Debug.LogWarning("[NetworkValidator] Required for manual player spawning");
}
PlayerSpawnPoint[] spawnPoints = FindObjectsByType<PlayerSpawnPoint>(FindObjectsSortMode.None);
if (spawnPoints.Length > 0)
{
Debug.Log("<color=green>[NetworkValidator] ✅ Found " + spawnPoints.Length + " Player Spawn Point(s)</color>");
}
else
{
Debug.LogWarning("<color=yellow>[NetworkValidator] ⚠ No Player Spawn Points found</color>");
Debug.LogWarning("[NetworkValidator] FIX: Add PlayerSpawnPoint component to empty GameObject(s)");
}
AutoHost autoHost = FindObjectOfType<AutoHost>();
if (autoHost != null && autoHost.enabled)
{
Debug.LogWarning("<color=yellow>[NetworkValidator] ⚠ AutoHost is enabled!</color>");
Debug.LogWarning("[NetworkValidator] This might interfere with manual host startup");
Debug.LogWarning("[NetworkValidator] Consider disabling AutoHost");
}
return allPresent;
}
[ContextMenu("Generate Fix Report")]
public void GenerateFixReport()
{
Debug.Log("=== NETWORKMANAGER FIX REPORT ===");
Debug.Log("");
Debug.Log("PROBLEM: PortListenerTest works, but Unity Netcode doesn't");
Debug.Log("");
Debug.Log("MOST LIKELY CAUSE:");
Debug.LogError("1. ❌ Player Prefab is NOT assigned (90% probability)");
Debug.LogWarning("2. ⚠ NetworkManager has initialization order issue");
Debug.LogWarning("3. ⚠ Transport not configured correctly");
Debug.LogWarning("4. ⚠ AutoHost interfering");
Debug.Log("");
Debug.Log("QUICK FIX:");
Debug.Log("1. Select NetworkManager in scene");
Debug.Log("2. Inspector → Network Config → Player Prefab");
Debug.Log("3. Drag your Player Prefab from Project window");
Debug.Log("4. Drop into Player Prefab field");
Debug.Log("5. Save scene");
Debug.Log("6. Start Host");
Debug.Log("7. Test on yougetsignal IMMEDIATELY");
Debug.Log("");
Debug.Log("COMPLETE FIX:");
Debug.Log("1. Right-click this component → 'Validate NetworkManager Configuration'");
Debug.Log("2. Fix any errors shown");
Debug.Log("3. Add ForceTransportBinding");
Debug.Log("4. Right-click → 'Force Then Start Host'");
Debug.Log("5. Add ContinuousPortMonitor");
Debug.Log("6. Right-click → 'Start Port Monitoring'");
Debug.Log("7. Watch Console for port status");
Debug.Log("=================================");
}
[ContextMenu("Check If Server Can Start")]
public void CheckIfServerCanStart()
{
Debug.Log("=== CAN SERVER START? ===");
bool canStart = true;
if (_networkManager == null)
{
Debug.LogError("❌ NO - NetworkManager is NULL");
canStart = false;
}
else
{
if (_networkManager.NetworkConfig?.PlayerPrefab == null)
{
Debug.LogError("❌ NO - Player Prefab NOT assigned");
canStart = false;
}
if (_networkManager.GetComponent<Unity.Netcode.Transports.UTP.UnityTransport>() == null)
{
Debug.LogError("❌ NO - UnityTransport NOT found");
canStart = false;
}
}
if (canStart)
{
Debug.Log("<color=green>✅ YES - Server should be able to start</color>");
Debug.Log("If port still closed after starting:");
Debug.Log("1. Check Console for errors");
Debug.Log("2. Verify Port Forwarding is working");
Debug.Log("3. Verify Firewall is allowing port");
}
Debug.Log("========================");
}
private bool validateOnAwake = true;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 926d1f00e8a21ab44a9f4cc1bf0028bd

View File

@@ -0,0 +1,237 @@
using UnityEngine;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
using System.Net.Sockets;
using System.Net;
namespace Northbound
{
/// <summary>
/// Completely restarts network to fix stuck/closed port issues
/// </summary>
public class NetworkResetAndRestart : MonoBehaviour
{
[Header("Reset Settings")]
[SerializeField] private bool autoResetOnStart = false;
[SerializeField] private ushort targetPort = 40445;
private NetworkManager _networkManager;
private UnityTransport _transport;
private void Start()
{
if (autoResetOnStart)
{
StartCoroutine(DoResetAndRestart());
}
}
[ContextMenu("Reset Network and Restart Host")]
public void ExecuteResetAndRestart()
{
StartCoroutine(DoResetAndRestart());
}
private System.Collections.IEnumerator DoResetAndRestart()
{
Debug.Log("<color=yellow>=== NETWORK RESET AND RESTART ===</color>");
// Step 1: Get references
_networkManager = NetworkManager.Singleton;
if (_networkManager == null)
{
Debug.LogError("<color=red>[NetworkReset] NetworkManager not found!</color>");
yield break;
}
_transport = _networkManager.GetComponent<UnityTransport>();
if (_transport == null)
{
Debug.LogError("<color=red>[NetworkReset] UnityTransport not found!</color>");
yield break;
}
// Step 2: Log current state
LogCurrentState();
// Step 3: Shutdown if running
if (_networkManager.IsServer || _networkManager.IsClient)
{
Debug.Log("<color=yellow>[NetworkReset] Shutting down current network...</color>");
_networkManager.Shutdown();
// Wait for complete shutdown
float startTime = Time.time;
while ((_networkManager.IsServer || _networkManager.IsClient) && Time.time - startTime < 10f)
{
yield return new WaitForSeconds(0.1f);
}
Debug.Log("<color=green>[NetworkReset] ✓ Network shutdown complete</color>");
}
yield return new WaitForSeconds(1f);
// Step 4: Force port release
ForcePortRelease();
yield return new WaitForSeconds(1f);
// Step 5: Reconfigure transport
Debug.Log("<color=cyan>[NetworkReset] Reconfiguring transport...</color>");
_transport.SetConnectionData(
"0.0.0.0", // Listen on all interfaces
targetPort, // Port 40445
"0.0.0.0" // Server listen on all interfaces
);
Debug.Log("<color=green>[NetworkReset] ✓ Transport configured to 0.0.0.0:" + targetPort + "</color>");
Debug.Log("<color=green>[NetworkReset] ✓ Server will accept connections from ANY IP</color>");
yield return new WaitForSeconds(0.5f);
// Step 6: Start host
Debug.Log("<color=cyan>[NetworkReset] Starting fresh host...</color>");
_networkManager.StartHost();
// Wait for host to start
float hostStartTime = Time.time;
while (!_networkManager.IsServer && Time.time - hostStartTime < 10f)
{
yield return new WaitForSeconds(0.2f);
}
if (_networkManager.IsServer)
{
Debug.Log("<color=green>[NetworkReset] ✓ Host started successfully!</color>");
// Verify port is actually listening
yield return new WaitForSeconds(1f);
VerifyPortListening();
}
else
{
Debug.LogError("<color=red>[NetworkReset] ✗ Failed to start host!</color>");
}
Debug.Log("<color=green>=== RESET AND RESTART COMPLETE ===</color>");
}
private void LogCurrentState()
{
Debug.Log("<color=cyan>[NetworkReset] Current Network State:</color>");
Debug.Log(" IsServer: " + _networkManager.IsServer);
Debug.Log(" IsClient: " + _networkManager.IsClient);
Debug.Log(" IsHost: " + _networkManager.IsHost);
Debug.Log(" IsConnectedClient: " + _networkManager.IsConnectedClient);
Debug.Log(" LocalClientId: " + _networkManager.LocalClientId);
Debug.Log(" ConnectedClients: " + _networkManager.ConnectedClients.Count);
if (_transport != null)
{
Debug.Log(" Transport.Port: " + _transport.ConnectionData.Port);
Debug.Log(" Transport.Address: " + _transport.ConnectionData.Address);
}
}
private void ForcePortRelease()
{
Debug.Log("<color=cyan>[NetworkReset] Forcing port release...</color>");
try
{
// Try to bind and release port to ensure it's freed
TcpListener testListener = new TcpListener(IPAddress.Any, targetPort);
testListener.Start();
testListener.Stop();
Debug.Log("<color=green>[NetworkReset] ✓ Port " + targetPort + " is released</color>");
}
catch (System.Exception e)
{
Debug.LogWarning("<color=yellow>[NetworkReset] ⚠ Could not bind port for release: " + e.Message + "</color>");
Debug.LogWarning("[NetworkReset] This is normal if port is in use");
}
}
private void VerifyPortListening()
{
Debug.Log("<color=cyan>[NetworkReset] Verifying port is listening...</color>");
try
{
using (TcpClient client = new TcpClient("127.0.0.1", targetPort))
{
Debug.Log("<color=green>[NetworkReset] ✓ Successfully connected to localhost:" + targetPort + "</color>");
Debug.Log("<color=green>[NetworkReset] ✓ Unity IS listening on port</color>");
Debug.Log("<color=green>[NetworkReset] ✓ Port should now be accessible on yougetsignal</color>");
Debug.Log("");
Debug.Log("<color=green>[NetworkReset] ✓ TEST ON YOUGETSIGNAL NOW!</color>");
}
}
catch (System.Exception e)
{
Debug.LogWarning("<color=yellow>[NetworkReset] ⚠ Could not connect to localhost:" + targetPort + "</color>");
Debug.LogWarning("[NetworkReset] Error: " + e.Message);
Debug.LogWarning("[NetworkReset] This might mean server didn't actually start");
}
}
[ContextMenu("Check Current Network Status")]
public void CheckStatus()
{
_networkManager = NetworkManager.Singleton;
if (_networkManager == null)
{
Debug.LogError("NetworkManager not found");
return;
}
Debug.Log("=== NETWORK STATUS ===");
Debug.Log("IsServer: " + _networkManager.IsServer);
Debug.Log("IsClient: " + _networkManager.IsClient);
Debug.Log("IsHost: " + _networkManager.IsHost);
Debug.Log("IsConnectedClient: " + _networkManager.IsConnectedClient);
Debug.Log("LocalClientId: " + _networkManager.LocalClientId);
Debug.Log("ConnectedClients: " + _networkManager.ConnectedClients.Count);
foreach (var client in _networkManager.ConnectedClients)
{
Debug.Log(" Client " + client.Key + ": " +
(client.Value.PlayerObject != null ? "Has Player" : "No Player"));
}
Debug.Log("===================");
}
[ContextMenu("Generate Instructions")]
public void GenerateInstructions()
{
Debug.Log("=== NETWORK RESET INSTRUCTIONS ===");
Debug.Log("");
Debug.Log("PROBLEM:");
Debug.Log("- Port stays closed even though config is correct");
Debug.Log("- Server reports running but port not accessible");
Debug.Log("");
Debug.Log("SOLUTION: Complete network reset");
Debug.Log("");
Debug.Log("STEPS:");
Debug.Log("1. Add NetworkResetAndRestart to scene");
Debug.Log("2. Right-click → 'Reset Network and Restart Host'");
Debug.Log("3. Wait for '✓ Host started successfully'");
Debug.Log("4. Test on yougetsignal IMMEDIATELY");
Debug.Log("");
Debug.Log("WHAT IT DOES:");
Debug.Log("1. Shuts down any current network");
Debug.Log("2. Forces port release");
Debug.Log("3. Reconfigures transport to 0.0.0.0");
Debug.Log("4. Starts fresh host");
Debug.Log("5. Verifies port is actually listening");
Debug.Log("");
Debug.Log("EXPECTED RESULT:");
Debug.Log("✓ Port 40445 shows OPEN on yougetsignal");
Debug.Log("✓ Teammates can connect");
Debug.Log("===============================");
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d15e6615b07f55843a759c775a08bc89

View File

@@ -0,0 +1,245 @@
using UnityEngine;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using Unity.Netcode;
// Removed System.Diagnostics to fix Debug.Log ambiguity
namespace Northbound
{
/// <summary>
/// Runs PortListenerTest method simultaneously with Unity Netcode
/// Uses exact same TcpListener method that works
/// </summary>
public class PortListenerTestSimultaneous : MonoBehaviour
{
[Header("Settings")]
[SerializeField] private ushort testPort = 40445;
[SerializeField] private bool autoStartOnEnable = false;
private TcpListener _listener;
private Thread _listenerThread;
private volatile bool _isRunning = false;
private volatile bool _hasConnection = false;
private NetworkManager _networkManager;
private void OnEnable()
{
if (autoStartOnEnable)
{
StartTest();
}
}
private void Start()
{
_networkManager = NetworkManager.Singleton;
}
[ContextMenu("Start Test Only")]
public void StartTest()
{
UnityEngine.Debug.Log("<color=magenta>=== PORT LISTENER TEST (SIMULTANEOUS) ===</color>");
UnityEngine.Debug.Log("Using EXACT same method as PortListenerTest");
UnityEngine.Debug.Log("Method: TcpListener(IPAddress.Any, " + testPort + ")");
UnityEngine.Debug.Log("This PROVES port CAN be bound");
_isRunning = true;
_listenerThread = new Thread(ListenerThread);
_listenerThread.IsBackground = true;
_listenerThread.Start();
}
[ContextMenu("Start Test + Unity Netcode")]
public void StartTestAndUnity()
{
UnityEngine.Debug.Log("<color=magenta>=== STARTING TEST + UNITY NETCODE ===</color>");
StartTest();
StartCoroutine(StartUnityDelayed());
}
private System.Collections.IEnumerator StartUnityDelayed()
{
UnityEngine.Debug.Log("Waiting 3 seconds before starting Unity...");
yield return new WaitForSeconds(3f);
UnityEngine.Debug.Log("Starting Unity Netcode...");
if (_networkManager == null)
{
UnityEngine.Debug.LogError("NetworkManager not found!");
yield break;
}
if (_networkManager.IsServer || _networkManager.IsClient)
{
UnityEngine.Debug.Log("Unity already running, shutting down first...");
_networkManager.Shutdown();
yield return new WaitForSeconds(2f);
}
_networkManager.StartHost();
float startTime = Time.time;
while (!_networkManager.IsServer && Time.time - startTime < 10f)
{
UnityEngine.Debug.Log("Waiting for Unity to start...");
yield return new WaitForSeconds(0.5f);
}
if (_networkManager.IsServer)
{
UnityEngine.Debug.Log("<color=green>Unity Netcode started successfully!</color>");
UnityEngine.Debug.Log("Now BOTH listeners are running:");
UnityEngine.Debug.Log(" 1. TcpListener (proven method)");
UnityEngine.Debug.Log(" 2. Unity Netcode");
}
else
{
UnityEngine.Debug.LogError("Unity Netcode failed to start!");
}
}
private void ListenerThread()
{
try
{
_listener = new TcpListener(IPAddress.Any, testPort);
_listener.Start();
UnityEngine.Debug.Log("<color=green>Successfully bound to 0.0.0.0:" + testPort + "</color>");
UnityEngine.Debug.Log("PROVED: Port " + testPort + " CAN be bound");
UnityEngine.Debug.Log("PROVED: OS allows binding");
UnityEngine.Debug.Log("PROVED: Firewall allows binding");
while (_isRunning)
{
if (_listener.Pending())
{
try
{
TcpClient client = _listener.AcceptTcpClient();
IPEndPoint endPoint = (IPEndPoint)client.Client.RemoteEndPoint;
_hasConnection = true;
UnityEngine.Debug.Log("<color=green>Connection received from " + endPoint.Address + ":" + endPoint.Port + "</color>");
UnityEngine.Debug.Log("PROVES: Port IS OPEN and working");
UnityEngine.Debug.Log("PROVES: Port forwarding IS working");
UnityEngine.Debug.Log("PROVES: Test listener method WORKS");
Thread.Sleep(100);
client.Close();
}
catch (System.Exception e)
{
UnityEngine.Debug.LogWarning("Error accepting: " + e.Message);
}
}
else
{
Thread.Sleep(100);
}
}
_listener.Stop();
}
catch (System.Exception e)
{
_isRunning = false;
UnityEngine.Debug.LogError("<color=red>Failed to bind port " + testPort + "</color>");
UnityEngine.Debug.LogError("Error: " + e.Message);
}
}
[ContextMenu("Stop Test")]
public void StopTest()
{
UnityEngine.Debug.Log("Stopping test listener...");
_isRunning = false;
if (_listener != null)
{
_listener.Stop();
}
if (_listenerThread != null && _listenerThread.IsAlive)
{
_listenerThread.Join(1000);
}
_hasConnection = false;
}
[ContextMenu("Check Status")]
public void CheckStatus()
{
UnityEngine.Debug.Log("=== SIMULTANEOUS TEST STATUS ===");
UnityEngine.Debug.Log("Test Listener Running: " + _isRunning);
UnityEngine.Debug.Log("Has Connection: " + _hasConnection);
if (_networkManager != null)
{
UnityEngine.Debug.Log("Unity IsServer: " + _networkManager.IsServer);
UnityEngine.Debug.Log("Unity IsClient: " + _networkManager.IsClient);
UnityEngine.Debug.Log("Unity IsHost: " + _networkManager.IsHost);
}
if (_hasConnection)
{
UnityEngine.Debug.Log("<color=green>Port IS OPEN - Test listener works!</color>");
}
UnityEngine.Debug.Log("===================================");
}
[ContextMenu("Explanation")]
public void ShowExplanation()
{
UnityEngine.Debug.Log("=== EXPLANATION ===");
UnityEngine.Debug.Log("");
UnityEngine.Debug.Log("WHAT THIS DOES:");
UnityEngine.Debug.Log("Uses EXACT same method as PortListenerTest:");
UnityEngine.Debug.Log(" new TcpListener(IPAddress.Any, 40445)");
UnityEngine.Debug.Log(" listener.Start()");
UnityEngine.Debug.Log("");
UnityEngine.Debug.Log("WHY PORTLISTENERTEST WORKS:");
UnityEngine.Debug.Log("✓ Successfully binds to port");
UnityEngine.Debug.Log("✓ Port is OPEN on yougetsignal");
UnityEngine.Debug.Log("✓ OS allows binding");
UnityEngine.Debug.Log("✓ Firewall allows binding");
UnityEngine.Debug.Log("");
UnityEngine.Debug.Log("WHY WE RUN IT WITH UNITY:");
UnityEngine.Debug.Log("→ To see if they conflict");
UnityEngine.Debug.Log("→ To see if Unity Netcode binds");
UnityEngine.Debug.Log("→ To identify what's different");
UnityEngine.Debug.Log("");
UnityEngine.Debug.Log("EXPECTED RESULTS:");
UnityEngine.Debug.Log("If test listener receives connection:");
UnityEngine.Debug.Log(" → Port IS OPEN");
UnityEngine.Debug.Log(" → Test method WORKS");
UnityEngine.Debug.Log(" → Something is wrong with Unity Netcode");
UnityEngine.Debug.Log("");
UnityEngine.Debug.Log("HOW TO USE:");
UnityEngine.Debug.Log("1. Add to scene");
UnityEngine.Debug.Log("2. Right-click 'Start Test + Unity Netcode'");
UnityEngine.Debug.Log("3. Wait 3 seconds");
UnityEngine.Debug.Log("4. See if both start");
UnityEngine.Debug.Log("5. Test on yougetsignal");
UnityEngine.Debug.Log("=============================");
}
private void OnDestroy()
{
StopTest();
}
private void OnDisable()
{
StopTest();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ba79d51f450e07d439690667a6535133

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cf33aade754bf4948841fba12d66d87e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long

View File

@@ -83,7 +83,7 @@ PlayerSettings:
androidApplicationEntry: 2
defaultIsNativeResolution: 1
macRetinaSupport: 1
runInBackground: 0
runInBackground: 1
muteOtherAudioSources: 0
Prepare IOS For Recording: 0
Force IOS Speakers When Recording: 0

View File

@@ -166,19 +166,4 @@ QualitySettings:
terrainMaxTrees: 50
excludedTargetPlatforms: []
m_TextureMipmapLimitGroupNames: []
m_PerPlatformDefaultQuality:
Android: 0
GameCoreScarlett: 2
GameCoreXboxOne: 2
Lumin: 2
Nintendo Switch: 2
Nintendo Switch 2: 2
PS4: 2
PS5: 2
Stadia: 2
Standalone: 2
WebGL: 0
Windows Store Apps: 2
XboxOne: 2
iPhone: 0
tvOS: 0
m_PerPlatformDefaultQuality: {}

View File

@@ -58,8 +58,8 @@
<Compile Include="Library\PackageCache\com.unity.render-pipelines.universal@1e87cf1dccb8\Runtime\RTHandleUtils.cs" />
<Compile Include="Assets\FlatKit\[Render Pipeline] URP\EditorAttributes\Core\ValidatorAttributes\ValidateInputAttribute.cs" />
<Compile Include="Library\PackageCache\com.unity.render-pipelines.universal@1e87cf1dccb8\Runtime\Decal\ScreenSpace\DecalScreenSpaceRenderPass.cs" />
<Compile Include="Assets\FlatKit\[Render Pipeline] URP\RenderFeatures\Fog\FogSettings.cs" />
<Compile Include="Library\PackageCache\com.unity.render-pipelines.universal@1e87cf1dccb8\Runtime\VolumeRequiresRendererFeatures.cs" />
<Compile Include="Assets\FlatKit\[Render Pipeline] URP\RenderFeatures\Fog\FogSettings.cs" />
<Compile Include="Library\PackageCache\com.unity.render-pipelines.universal@1e87cf1dccb8\Runtime\UniversalCameraHistory.cs" />
<Compile Include="Library\PackageCache\com.unity.render-pipelines.universal@1e87cf1dccb8\Runtime\ForwardLights.cs" />
<Compile Include="Library\PackageCache\com.unity.render-pipelines.universal@1e87cf1dccb8\Runtime\FrameData\UniversalCameraData.cs" />