Jump to content
Unity Insider Forum

Multiplayer Tutorial mit Unity


DoubleM

Recommended Posts

Ich weiss ja nicht ob das Problem von Gassi noch akut ist aber...

 

Wenn ich einen Server zu Hause stehen habe den ich von außen (Internet) erreichen möchte dann muss man nicht nur in der Firewall den Port "aufmachen" sondern dann benötigt man eigentlich immer ein Port-Forwarding.

 

Hintergrund:

Die Anfrage von außen kommt (via IP oder Name ist da mal egal wir sagen hier aber mal IP) ersteinmal auf deinen Router/Modem.

Der hat nämlich als einzigster die IP des Providers.

 

Neben de IP hat diese Anfrage auch noch einen Port hinten dran.

Der Router kann aber mit der Anfrage selber natürlich nichts anfangen und möchte diese weiterleiten (Forwarding).

 

Also musst du im Router definieren:

Wenn Anfrage über Port XYZ gib sie weiter an IP des HomeServer 192.168.X.X

Und damit wird der Kanal für eine Kommunikation geöffnet.

Das ist Port-Forwarding.

 

Dann erst musst du schauen ob dein Server (lokale Firewall z.B. Zonealarm, etc.) diese Verbindung auf dem Port akzeptiert.

 

Hoffe das kann ein wenig weiterhelfen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

linksys_port_fwd_afp.jpg

 

Nachtrag:

 

Hab mal ein Bild dazu gefügt.

So oder so ähnlich sieht es bei Linksys Routern aus.

 

Eine weitere Hintergrundinfo vielleicht noch.

Durch die Definition im Router kann man z.b auch mehrere Server via unterschiedlicher Ports auf der gleichen ProviderIP oder Internetname erreichen.

 

z.B

Router mit interner IP 192.168.1.1 auf alle Ports hören und extern im Internet mit PROVIDER_IP

Ein Server/Rechner mit IP 192.168.1.10 auf Port 3890 für das Spiel hören

Ein Server/Rechner mit IP 192.168.1.11 auf Port 3891 für den Chat hören

 

Anfrage an PROVIDER_IP:Port3891

trifft auf Router und leitet diese nun um ins interne Netzwerk und weiss durch den Port das es sich hier um einen Chatversuch handelt und leitet die Anfrage an den Server mit der IP 192.168.1.11

Und zwar nur dahin nirgendswo anders.

 

Wenn man sich nicht sicher ist welches Protokoll zu nutzen ist einfach testweise beide nehmen (also TCP und UDP).

 

Bin mir nie sicher ob meine Ausführungen verständlich sind deswegen noch dieser Nachtrag

 

Bei Fragen gerne ne PM

Link zu diesem Kommentar
Auf anderen Seiten teilen

Eigentlich geht es doch im Problem von Gassi darum das er einen Server hosten möchte.

Er mag bestimmt auch selber gerne spielen aber in dem Fall möchte er ja einen "Service anbieten" (Chat, Gameserver, Teamspeak, etc.) wenn ich es richtig verstanden habe.

 

 

 

Die Spieler müssen natürlich nichts dergleichen Unternehmen.

Aber derjenige, der einen solchen Server betreiben möchte, um aus dem Internet erreichbar zu sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 months later...
  • 4 months later...
  • 11 months later...
  • 2 weeks later...
  • 3 months later...

Ich habe ein Problem mit dem Chat Script.

Und zwar sagt mir Unity "you can only call gui functions from inside ongui".

Ich Verstehe schon was der damit meint doch bekomme ich es noch nicht hin den Fehler zu Korrigieren.

Arbeite erst seit knapp 2 Wochen an Unity und wollte nur mal etwas Multiplayer Mäßiges testen^^

Mein Script sieht wie folgt aus:

 

var scrollPosition : Vector2; // Die Position des Skrollbalken
var chatEntrys = ArrayList(); // Ein Array mit dem Chatinhalt
var window = Rect(Screen.width/2-200,Screen.height/2-100,400,200); // Rechteck für das Chatwindow
var inputField : String = "";						   // Textfeldstring
function OnGUI(){
	window = GUI.Window (1, window, GlobalChatWindow, "Chat");
}

function GlobalChatWindow (id : int) {/* noch leer */}
// Skrollbalken erstellen
scrollPosition = GUILayout.BeginScrollView (scrollPosition);

for (var entry : String in chatEntrys) // jeden einzelnen durchgehen
{
	GUILayout.BeginHorizontal();
	GUILayout.Label(entry);				 // und für jeden ein textfeld erstellen
	GUILayout.EndHorizontal();

}
// Skrollbalken Ende
GUILayout.EndScrollView ();

inputField = GUILayout.TextField(inputField);
if (Event.current.type == EventType.keyDown && Event.current.character == "\n" && inputField.Length > 0)
// Wenn Enter gedrückt ist und mehr als 0 zeichen im Textfeld
{
var playerName  = PlayerPrefs.GetString("Player Name");  
// Den Spielernamen aus der Registry auslesen
if(playerName		  == "") // Wenn kein Name eingegeben oder Fehler...
 {
	playerName = "Benutzername"; //... den Namen zu Benutzername setzen
}
 // dann den Namen, einen Doppelpunkt und den Text per rundnachricht im Netzwerk versenden
 networkView.RPC("ChatText", RPCMode.AllBuffered, playerName+": "+inputField);
inputField = ""; // Textfeld zurücksetzen
}

GUI.DragWindow();
@RPC
function ChatText(chatText : String){
chatEntrys.Add(chatText);
}

 

Hoffe jemand Kann mir Helfen, Danke schonmal :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die Meldung bedeutet einfach, dass alles was du da mit GUI.xxx machst in der ONGUI() drin sein muss. Denn nur dort kann es bearbeitet werden.

Deine Funktionen wie GlobalChatWindow können also keine GUI Befehle gebrauchen.

Du kannst in diesen Funktionen ja Dinge machen, die für die Dialoge wichtig sind. Solltest dort aber dann Variablen beschreiben, die du in OnGUI() für die Anzeige nutzt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...

Weiß nicht, ob das Problem noch bei dir besteht, aber falls schon...

Der fehler liegt darann, dass du deine GlobalChatWindow function nich mit einem Block {} versehen hast, bzw. den code außerhalb hast.

 

bei dir steht:

function GlobalChatWindow (id : int) {/* noch leer */} bei noch leer muss der code rein^^

 

@malzbie

Andere functionen können durchaus GUI befehle haben/nutzten solange sie von der OnGUI function aufgerufen werden.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 3 weeks later...

Hallo erstmal xD

 

Ich habe mir das Tutorial ordentlich durchgelesen und ich bin auch dankbar für so ein gutes Tutorial, jedoch habe ich ein kleines Problem beim nutzen xD

 

Wenn ich die Scene teste geht zwar der Chat, jedoch die Verbindungseingabe nicht wo man ip-port etc einträgt die ist bei mir leer außer das Fenster und der Text Verbindungsmanager zeigt er nichts anderes an.

 

Unity spuckt auch keinerlei Fehler aus egal ob Rot oder Gelb xD

 

Hier mein Connect.js

var ip_Address : String = "127.0.0.1"; // Die Variable die die ipAdresse beinhaltet (als Standard localhost)
var Port : String  = "25001";						   // Die Variable für den Port (standardmäßig 25001)
var Status : String = "Standby";						// Ein Statuskommentar das wir in einem Label anzeigen, in etwa  "Verbinde zu Server...."
function OnGUI(){
// Fenster anzeigen [...]
GUI.Window(0,Rect(0,0,200,200),NetworkingWindow,"Verbindungsmanager");
}
/* Die Fensterfunktion vom Hauptmenuefenster */
function NetworkingWindow (id : int) {
if (Network.peerType == NetworkPeerType.Disconnected) // Wenn keine Verbindung besteht...
{					
		// tue etwas...
}
else // Wir sind schon verbunden bzw. der Server läuft schon!
{
						  // tue etwas (oder nichts)
}
if (Network.peerType == NetworkPeerType.Disconnected) // Wenn keine  Verbindung besteht...
{							
  // tue etwas...							
}	
else // Wir sind schon verbunden bzw. der Server läuft schon!
 {										  
// tue etwas (oder nichts)  
if(Status.length > 0) // Wenn der Status-text länger als 0 Zeichen  ist...				  
GUILayout.Label(Status); // Status anzeigen Wenn der Statuskommentar mehr als 0 Zeichen hat zeigen wir ihn mit einem  Label an
// Ein Eingabefeld für den Spielernamen erzeugen und den Text in der Registry speichern
GUILayout.Label("Name:");
PlayerPrefs.SetString("Player Name",GUILayout.TextField(PlayerPrefs.GetString("Player Name")));
// Ein Eingabefeld für den Spielernamen erzeugen und den Text in der  Registry speichern GUILayout.Label("Name:"); PlayerPrefs.SetString("Player  Name",GUILayout.TextField(PlayerPrefs.GetString("Player Name")));
GUILayout.Label("IP-Adresse:");										 // Den text IP-Adresse anzeigen
ip_Address = GUILayout.TextField(ip_Address); // Eingabefeld für die IP-Adresse
GUILayout.Label("Port:");													   // Den Text Port: anzeigen
Port = GUILayout.TextField(Port);							   // Eingabefeld für den Port
if (GUILayout.Button("Zu direkter IP verbinden")) // Button erstellen
{
// Status auf "Verbinde zu Server...." setzen
Status = "Verbinde zu Server...";
Debug.Log(Status);
// Wenn Button geklickt ist:
 // Netzwerkeinstellung Nat ausschalten
//  Network.useNat = false;
 // zu bestimmter IP und bestimmtem Port verbinden
 // [Port wird mit ParseInt nach int konvertiert]
Network.Connect(ip_Address, parseInt(Port));
}
if (GUILayout.Button("Server starten")) // Button erstellen
{
 // Status auf "Starte Server..." setzen
 Status = "Starte Server...";
 Debug.Log(Status);
 // Wenn Button geklickt ist:
 // Netzwerkeinstellung Nat ausschalten
//  Network.useNat = false;
 // Server aufmachen
 // der erste Parameter gibt die maximale Spielerzahl an
 // der zweite den Port für den server
 // (ich nehme hier einfach den normalen Port wie beim Client, kann man aber  auch anders machen)
 // [Port wird mit ParseInt nach int konvertiert]
//Network.InitializeServer(32, parseInt(Port));
 }
 else // Wir sind schon verbunden bzw. der Server läuft schon!
{
if(Status.length > 0) // Wenn der Status-text länger als 0 Zeichen ist...
			GUILayout.Label(Status); // Status anzeigen
if (GUILayout.Button ("Verbindung beenden"))
 {
	// Status auf "Trenne Verbindung(en)..." setzen
	Status = "Trenne Verbindung(en)...";
	Debug.Log(Status);
	Network.Disconnect(200); // Die Verbindung trennen (innerhalb von 200ms)
  }
 }
}
}

 

Ich bin für jede Hilfe dankbar ^^

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...

Hey Nexativez

ich bin auch neu hier, aber kann dir mit deinem Fehler weiterhelfen :)

 

Also, du hast bei:

 

if (Network.peerType == NetworkPeerType.Disconnected) // Wenn keine Verbindung besteht...
{									  
				    // tue etwas...
}
else // Wir sind schon verbunden bzw. der Server läuft schon!
{
													  // tue etwas (oder nichts)
}

 

 

Dort hast du dein script in den Bereich geschrieben, welcher erst ausgeführt werden soll, wenn der Client schon mit dem Server verbunden ist. Also kurz und knapp gesagt, du musst mit dem Server verbunden sein, um dich mit dem Server verbinden zu können :D

 

 

hier mein Code:

var ip_Address : String = "127.0.0.1"; // Die Variable die die ipAdresse beinhaltet (als Standard localhost)
var Port : String  = "25001";											  // Die Variable für den Port (standardmäßig 25001)
var Status : String = "Standby";											    // Ein Statuskommentar das wir in einem Label anzeigen, in etwa  "Verbinde zu Server...."

function OnGUI(){
// Fenster anzeigen [...]
GUI.Window(0,Rect(0,0,200,200),NetworkingWindow,"Verbindungsmanager");
}

/* Die Fensterfunktion vom Hauptmenuefenster */
function NetworkingWindow (id : int) {
if (Network.peerType == NetworkPeerType.Disconnected) // Wenn keine Verbindung besteht...
{									  
  if(Status.length > 0) // Wenn der Status-text länger als 0 Zeichen  ist... 

GUILayout.Label(Status); // Status anzeigen Wenn der Statuskommentar mehr als 0 Zeichen hat zeigen wir ihn mit einem  Label an
// Ein Eingabefeld für den Spielernamen erzeugen und den Text in der Registry speichern
GUILayout.Label("Name:");
PlayerPrefs.SetString("Player Name",GUILayout.TextField(PlayerPrefs.GetString("Player Name")));
// Ein Eingabefeld für den Spielernamen erzeugen und den Text in der  Registry speichern GUILayout.Label("Name:"); PlayerPrefs.SetString("Player  Name",GUILayout.TextField(PlayerPrefs.GetString("Player Name")));
GUILayout.Label("IP-Adresse:");							 // Den text IP-Adresse anzeigen
ip_Address = GUILayout.TextField(ip_Address);	 // Eingabefeld für die IP-Adresse
GUILayout.Label("Port:");								   // Den Text Port: anzeigen
Port = GUILayout.TextField(Port);						   // Eingabefeld für den Port

if (GUILayout.Button("Zu direkter IP verbinden")) // Button erstellen
{
// Status auf "Verbinde zu Server...." setzen
Status = "Verbinde zu Server...";
Debug.Log(Status);
// Wenn Button geklickt ist:
 // Netzwerkeinstellung Nat ausschalten
//  Network.useNat = false;
 // zu bestimmter IP und bestimmtem Port verbinden
 // [Port wird mit ParseInt nach int konvertiert]
Network.Connect(ip_Address, parseInt(Port));
}
if (GUILayout.Button("Server starten")) // Button erstellen
{
 // Status auf "Starte Server..." setzen
 Status = "Starte Server...";

 Debug.Log(Status);
 // Wenn Button geklickt ist:
 // Netzwerkeinstellung Nat ausschalten
//  Network.useNat = false;
 // Server aufmachen
 // der erste Parameter gibt die maximale Spielerzahl an
 // der zweite den Port für den server
 // (ich nehme hier einfach den normalen Port wie beim Client, kann man aber  auch anders machen)
 // [Port wird mit ParseInt nach int konvertiert]
//Network.InitializeServer(32, parseInt(Port));
 }


 else // Wir sind schon verbunden bzw. der Server läuft schon!
    {
if(Status.length > 0) // Wenn der Status-text länger als 0 Zeichen ist...
						    GUILayout.Label(Status); // Status anzeigen


if (GUILayout.Button ("Verbindung beenden"))
 {
		    // Status auf "Trenne Verbindung(en)..." setzen
		    Status = "Trenne Verbindung(en)...";
		    Debug.Log(Status);
		    Network.Disconnect(200); // Die Verbindung trennen (innerhalb von 200ms)
  }
 }
}
}

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 1 month later...

Kann mir jemand sagen was hier falsch ist:

 

var scrollPosition : Vector2; // Die Position des Skrollbalken
var chatEntrys = ArrayList(); // Ein Array mit dem Chatinhalt
var window = Rect(Screen.width/2-200,Screen.height/2-100,400,200); // Rechteck für das Chatwindow
var inputField : String = "";						   // Textfeldstring  var scrollPosition : Vector2;
function OnGUI(){
	window = GUI.Window (1, window, GlobalChatWindow, "Chat");
}

function GlobalChatWindow (id : int) {
// Skrollbalken erstellen
scrollPosition = GUILayout.BeginScrollView (scrollPosition);

for (var entry : String in chatEntrys) // jeden einzelnen durchgehen
{
	GUILayout.BeginHorizontal();
	GUILayout.Label(entry);				 // und für jeden ein textfeld erstellen
	GUILayout.EndHorizontal();
	GUI.DragWindow();  
 inputField = GUILayout.TextField(inputField);
}
// Skrollbalken Ende
GUILayout.EndScrollView ();
}
if (Event.current.type == EventType.keyDown && Event.current.character == "\n" && inputField.Length > 0)
// Wenn Enter gedrückt ist und mehr als 0 zeichen im Textfeld
{
var playerName  = PlayerPrefs.GetString("Player Name");  
// Den Spielernamen aus der Registry auslesen
if(playerName		  == "") // Wenn kein Name eingegeben oder Fehler...
 {
	playerName = "Benutzername"; //... den Namen zu Benutzername setzen
}
 // dann den Namen, einen Doppelpunkt und den Text per rundnachricht im Netzwerk versenden
 networkView.RPC("ChatText", RPCMode.AllBuffered, playerName+": "+inputField);
inputField = ""; // Textfeld zurücksetzen
}
@RPC
function ChatText(chatText : String){
chatEntrys.Add(chatText);
}  

 

 

weil bei mir das chatt system nicht funktioniert.

 

MfG Marv

Link zu diesem Kommentar
Auf anderen Seiten teilen

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Lädt...
×
×
  • Neu erstellen...