Jump to content
Unity Insider Forum

Anwendung friert bei Netzwerkaktivität kurz ein


Max89

Recommended Posts

Hallo.

 

Ich arbeite gerade an einem 2 Spieler Multiplayer Spiel (einfach nur zum Üben) und habe bereits

die wichtigsten Dinge fertig. Inkl. Remote-View (Partnerperspektive als kleines Fenster) und die

Synchronisation der Spielerposition, die sogar sehr flüssig übertragen und angezeigt wird.

 

Das Spiel läuft generell erstmal ohne Probleme - leider gibt es da aber eine nervige Ausnahme:

Sobald eine andere Anwendung etwas übers Netzwerk/Internet sendet oder empfängt, friert mein

Spiel für wenige Millisekunden komplett ein. Es wird dann also nichts mehr ausgeführt, kein Input,

keine neuen Frames, nichts. (aber eben nur für kurze Zeit!)

 

Ein Beispiel wäre der Steam Chat. Sobald ich eine Nachricht erhalte (oder jemand Online kommt),

hängt sich das Spiel kurz auf und läuft danach normal weiter, bis wieder etwas im Netzwerk passiert.

 

Das Problem tritt auch dann auf, wenn ich das Spiel 2x auf dem lokalen PC laufen lasse und

mich zu mir selbst verbinde.

 

 

Aufbau der Anwendung / Skripting:

Ich verwende ausschießlich RPCs und habe die Unity NetworkSync auf "Off" gestellt.

RPCs werden 30x pro Sekunde zwischen Client und Server gesendet um die aktuelle

Spielerposition / Geschwindigkeit zu übertragen.

Außerdem habe ich zwischenzeitlich bereits einen Buffer eingebaut, der mögliche Verzögerungen

auslgeichen soll, indem jeweils die aktuelle Position zwischengespeichert wird und die Spieler

zunächst an die (vorher) im Buffer gespeicherte Position synchronisiert.

 

 

Ich habe bereits versucht die RPCs auf 5 pro Sekunde zu senken, aber das Problem blieb

trotzdem bestehen (und zusätzlich gab es jede Menge (optisches) Lag, durch zu wenig Synchronisation).

 

 

Debug / Problemsuche:

Ich habe an unterschiedlichen Stellen Debug.Log()-Nachrichten eingebaut um zu sehen,

ob sich das Spiel an einer bestimmten Stelle aufhängt, aber es hängt (scheinbar) nur mit

der Netzwerkauslastung zusammen.

Die Debug Nachrichten zeigen also, dass mein Spiel zufällig i-wo hängen bleibt, bis im

Netzwerk wieder geringere Auslastung ist.

 

Soweit ich das mit den Debug-NAchrichten sehen konnte, werden die RPCs wirklich nur

für die beiden benötigten Objecte gesendet und es gibt keine unötigen RPCs.

 

 

PC Spezifikationen / Netzwerk / Unity:

- CPU: Core i7 @ 3,0 GHz (8 Kerne)

- GPU: GTX 580 mit 3 GB VRAM

- RAM: 16 GB DDR3 @ 1600 MHz

- Netzwerk: Kabel 100 MBit/s, Ping ist durchschnittlich unter 20ms

- Unity (free) 4.5.5f1

- Anwendung wird in Windows 64 bit (standalone) ausgeführt

 

 

Ich bin im Moment doch sehr ratlos wo ich noch suchen soll.

Das Problem lässt sich (bisher) nicht mit den einfachen Debug-Maßnahmen ausfindig machen.

 

 

Fragen:

- Was kann ich noch probieren?

- Wo könnte das Problem liegen?

- Habt Ihr ähnliche Probleme erlebt?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo nochmal und vielen Dank für die nette Aufnahme hier im Forum! :)

 

Dein Post sollte wirklich gepinned werden als Beispiel dafür, wie man an ein Problem rangeht, bevor man irgendwo nach weiterer Hilfe sucht.

Ich programmiere selbst seit etwas über 8 Jahren mit C++ / C# und dem Visual Studio,

daher kenn ich mich natürlich schon recht gut aus (auch wenn es nur ein Hobby ist).

Das hier ist also sozusagen nochmal der letzte Hoffnungsschimmer, nachdem ich mit meinem

bisherigen Wissen nicht zur Lösung des Problems gefunden habe.

Aber ich danke dir für dein Kommentar - schön, dass der Beitrag so erstmal gut ankommt. :)

 

Ich tippe auf die Übertragungszyklen. 30 Mal pro Sekunde ist sau viel. Geh mal mit dem Zyklus runter und schau was dann passiert.

Du hast meinen Beitrag wohl nur überflogen? :P

Ich habe bereits versucht 5x pro Sekunde die RPCs zu senden - ohne Erfolg! (Es gab nur zusätzlich noch optisches Lag)

 

Tritt das problem so auch bei anderen Systemen auf, hast du bisher nur im Editor getestet oder Standalone?

Getestet habe ich folgendes:

- Editor + Standalone (lokal)

- Editor + Standalone (über Internet mit einem Freund)

- Standalone + Standalone (beide lokal)

- Standalone (lokal) + Standalone (über Internet mit einem Freund)

- Standalone (mein PC) + Standlone (mein Laptop)

 

Damit dürfte also geklärt sein, dass es unabhängig vom System passiert.

Das Einfrieren tritt auf jedem PC auf und immer nur bei Netzwerkaktivät anderer Programme.

Daher denke ich schon, dass es i-was mit dem Netzwerk-Quellcode vom Programm zu tun haben sollte.

Das Spiel läuft ja auf allen genannten Systemen flüssig, bis zu dem Moment wo eine andere Anwendung das Netzwerk (mit-)nutzt.

 

Schonmal probiert die einstellung Run in Background zu aktivieren vielleicht liegts nicht wirklich am netzwerk sondern das das Programm kurz pausiert wird

'Run in Background' ist bereits seit dem Project-Start aktiviert, damit ich auch lokal testen kann.

Diese Option würde ja auch nur ein Problem darstellen, wenn mein Spiel den Fokus verliert.

 

Nur um das zu erwähnen:

Wenn ich selbst den Fokus vom Spiel nehme und eine Nachricht über Steam verschicke, dann

tritt der Fehler ebenfalls auf. Wenn ich aber nur den Fokus wegnehme, läuft es flüssig weiter.

 

 

Hier ist noch ein (gekürzter) Auszug aus dem Quellcode:

(Dieses Skript befindet sich auf beiden Player-GameObjects)

void Update()
{
	if (Time.time - timeStamp >= timeLimit)
	{
		timeStamp = Time.time;

           networkView.RPC(    "UpdateMovement",               // Name der Remote-Funktion
                               RPCMode.Others,                 // RPC-Mode (andere Spieler)
                               myTransform.position,           // Position
                               myTransform.rotation,           // Rotation
                               myRigidbody.velocity,           // Geschwindigkeit
                               myRigidbody.angularVelocity     // Winkelgeschwindigkeit
                           );
	}
}

[RPC]
void UpdateMovement(Vector3 newPosition, Quaternion newRotation, Vector3 newVelocity, Vector3 newAngVelocity)
{
	// aktuelle Position = Position im Buffer
	transform.position = lastPosition;
	transform.rotation = lastRotation;

       rigidbody.velocity        = lastVelocity;
       rigidbody.angularVelocity = lastAngVelocity;

	// Position im Buffer = neue Position aus dem RPC
       lastPosition = newPosition;
       lastRotation = newRotation;

       lastVelocity    = newVelocity;
       lastAngVelocity = newAngVelocity;
}

Das ist dann auch schon alles was im Moment übertragen wird.

Ich habe bereits mit Debug.Log()-Nachrichten überprüft, ob das Skript wirklich nur die gewünschten RPCs sendet.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Schwieriges wenn auch interessantes Problem.

 

Wirklich helfen kann ich dir dabei leider nicht. Was du aber versuchen könntest um ein Problem der RPCs auszuschließen: Du könntest versuchen Nachrichten ohne RPC zu versenden um zu sehen ob sich das anders verhält: OnSerializeNetworkView und Co

 

Auch kannst du mal versuchen was passiert wenn du die anderen Einstellungen des NetworkViews veränderst.

 

Ein separates TestProjekt hast du sicher auch schon gehabt was möglichst simpel ist. Da war das Problem ebenfalls?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Willkommen Max89!

 

#1 Mal eine ganz "blöde" Frage von mir... auf welchen Ports laufen die Sockets? => 8080? ^_^ Nicht böse nehmen. Manchmal helfen solche Fragen.

 

#2 Hast du eine Möglichkeit an eine Pro Version zu kommen? => Unity Profiler anmachen und schauen wer wo die Probleme macht.

 

#3 Hast du die Empfangsroutine selbst geschrieben bzw. kommst du da ran? Oder ist das was aus Unity (ich kenne die Netzwerkprogrammierung von Unity/C# nicht, hab selbst 3rdParty zugekauft)? Ich will darauf hinsaus, ob du Timer und Empfangsbuffergröße ausgeben kannst. Nicht, dass jemand dein RecvSocket zumüllt und dein Empfänger das ohne Warning verwirft = freeze

 

#4 ich würde ALLES was empfangen wird ins Log schreiben (Timestamp + recv buffer size) und dann mal schauen was da ankommt wenn der Steam Chat läuft

 

MfG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du könntest versuchen Nachrichten ohne RPC zu versenden um zu sehen ob sich das anders verhält: OnSerializeNetworkView und Co

Werde ich machen!

Bis jetzt hab nur mit Debugging und geringerer Senderate versucht, ob ich das Problem so lösen kann.

 

Ein separates TestProjekt hast du sicher auch schon gehabt was möglichst simpel ist. Da war das Problem ebenfalls?

Ich sitze gerade in diesem Moment daran ein richtig simples Project zu erstellen, wo ich das nochmal

alles ganz in Ruhe testen werde. Nachdem die bisherigen Versuche im aktuellen Projekt ja nichts

gebracht haben, scheint es unumgänglich zu sein. Ich will jetzt einfach wissen ob es an mir liegt,

oder ob da die Ursache noch wo anders zu suchen ist. :P

 

Ich schau mir grad nebenbei nochmal ein paar Tutorials an und werde mit NetworkView-Synchronisation beginnen.

Wenn das klappen sollte, geh ich dann auf RPCs und dann mal schauen ob der Fehler wieder auftritt.

 

#1 Mal eine ganz "blöde" Frage von mir... auf welchen Ports laufen die Sockets? => 8080? ^_^ Nicht böse nehmen. Manchmal helfen solche Fragen.

Port: 51382 << dieser sollte ja nicht belegt sein (Laut meinem Router wird der nur von meiner Anwendung genutzt)

Ich hab schon drauf geachtet, dass ich nicht Port 80 und andere wichtige (standarisierte) Ports nutze. :)

 

#2 Hast du eine Möglichkeit an eine Pro Version zu kommen? => Unity Profiler anmachen und schauen wer wo die Probleme macht.

Ich besitze nur Unity Free und da ess eher ein Hobby ist und nur zu Übungszwecken dient,

möchte ich da ungern Unity Pro käuflich erwerben (das Problem hat ja hoffentlich nichts damit zu tun :P ).

 

#3 Hast du die Empfangsroutine selbst geschrieben bzw. kommst du da ran? Oder ist das was aus Unity? Ich will darauf hinsaus, ob du Timer und Empfangsbuffergröße ausgeben kannst. Nicht, dass jemand dein RecvSocket zumüllt und dein Empfänger das ohne Warning verwirft = freeze

Was ich selbst geschrieben habe, ist im letzten Beitrag von mir zu sehen.

Aber Unity übernimmt dabei die Sende- und Empfangsrolle selbst im Hintergrund.

Da ich selbst erst 1 Woche damit arbeite, kann ich da auch nicht genau sagen wie Unity das erledigt.

In meinem Quellcode kümmere ich mich nur um den Aufruf vom RPC und was innerhalb vom RPC

dann mit den Parametern geschiet. Aber das Senden und Empfangen habe ich selbst nicht programmieren müssen.

 

#4 ich würde ALLES was empfangen wird ins Log schreiben (Timestamp + recv buffer size) und dann mal schauen was da ankommt wenn der Steam Chat läuft

Gute Idee - ich hoffe das kann ich mit Unity Free umsetzen.

Ich schau mal nach ob man da Zugriff auf diese Parameter bekommen kann.

(Ich rufe ja - wie erwähnt - nur den RPC auf, aber das Senden übernimmt Unity!)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe viel darüber gelesen, dass die Netzwerkimplementierung von Unity nicht gut sein soll. In den Unity Blogs schreiben sie auch über eine neue API und besserer Unterstützung. Da ich mit C++ x-mal mit verschiedenen Libs (qt, boost, std socket) die Schiene selbst implementiert habe, hatte als C# Quereinsteiger keine lust drauf es nochmal in einer Sprache zu machen, die ich kaum beherrsche => daher habe ich mir das Bolt-Asset gekauft (UnityForumLink).

 

Bolt selbst ist eine Netzwerk-Lib, die die Handhabungen vom Senden/Empfangen Master/Client vereinfacht. Für die Übertragung nutzt Bolt eine andere Lib, die freie UdpKit Lib. Beide Libs sind vom selben Entwickler -> Bold ist quasi die Kostenpflichtige easy to use Version mit mehr Funktionen.

 

Wenn du deine Implementierung weiter benutzen möchtest, würde ich versuchen den Fehler in nem MiniProjekt zu reproduzieren, wie du es ja atm machst, aber damit auch in das Unity Forum gehen, weil da in dem Netzwerk Bereich Leute sind, die bestimmt sowas schon gehabt haben.

Notfalls kannst du den Unity Profiler per 30 Tage Testversion aktivieren.

 

Ansonsten würde ich dir die UdpKit lib empfehlen. UdpKit und Bolt funktionieren beide mit der Free Version.

 

MfG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich weiß gerade nicht ob ich mich freuen soll, oder ob ich ganz doll weinen soll. :huh:

 

Ich habe mein Test-Projekt fertig und auch da gibt es das gleiche Problem.

ABER:

Das Spiel friert auch kurz ein, wenn das Unity-Networking komplett deaktiviert ist.

- Es ist also kein Network-View aktiv

- Es werden keine RPCs gesendet

- Ich hab sogar mal nur ein leeres Projekt mit dem Sphere + PlayerController erstellt (ohne NetworkView)

=> das Spiel hängt sich (kurz) auf, wenn eine andere Anwendung i-was anzeigen will. :blink:

 

Da kann ich natürlich lange im Netzwerk-Skript suchen, wenn es schon bei sowas scheitert.

Jetzt bin ich hier natürlich im falschen Forum... denn mit Netzwerk hat das nix mehr zu tun.

 

Bevor ich hier aber schließe, such erstmal weiter nach einer Lösung...

Jetzt weiß ich ja zumindest, dass ich nicht nach Netzwerkproblemen suchen muss. :P

 

Ich werde evtl. noch ein anderes Thema eröffnen (wenn ich selbst keine Lösung finden sollte)

und dann hier noch den Link zur Lösung hinzufügen.

 

Bis dahin erstmal vielen Dank an euch.

Mal sehen ob ich den Fehler noch finde. :(

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ups! Das mit den 5x hatte ich überlesen.

Aber du hast ja heraus bekommen, dass es etwas anderes sein muss.

Da es von dem Rechner zu kommen scheint, wirds jetzt natürlich fieß.

Kann die Grafikkarte, bzw. der Treiber, sein. Kann der Vierenscanner sein, kann ein anderer Prozess im Hintergrund sein oder aber etwas im Speichermanagement.

Ich kenne solche Hänger nur vom OpenGL. Speziell war sowas bei Cinema4D der Fall.

Aber Unity hat sowas bei mir noch nie verursacht....

Tut mir leid, aber da ist ein Helfen schwer. :(

Link zu diesem Kommentar
Auf anderen Seiten teilen

Tut mir leid, aber da ist ein Helfen schwer. :(

Dafür muss man sich doch in diesem Fall nicht entschuldigen!

Da kann doch nun niemand was dafür, dass es so ein seltsames Problem ist und es keine "spontane" Lösung gibt. :P

 

---

 

Ich habe nun übrigens nach weiteren Stunden der Suche - ohne Erfolg - ein neues Thema erstellt:

http://forum.unity-c...riert-kurz-ein/

Dieses Thema hier kann also geschlossen werden (da es Offtopic wäre).

 

Etwas weiter bn ich zwar - das Problem scheint mit Tooltips/Taskleiste zusammenzuhängen - aber Lösung = Fehlanzeige! :(

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe bereits versucht die RPCs auf 5 pro Sekunde zu senken, aber das Problem blieb

trotzdem bestehen (und zusätzlich gab es jede Menge (optisches) Lag, durch zu wenig Synchronisation).

 

30 RPCs pro Sekunde sind echt viel, vor allem wenn man bedenkt, dass beide Spieler diese dann wohl senden.

 

Eines der Highlevel Networking Elemente ist Interpolation. Vor allem bei Positionen werden nur wenige Male pro Sekunde die Vektoren synchronisiert und von da an interpoliert um den Jitter (deinen Lag) zu beseitigen. Zusätzlich kann man noch in Betracht ziehen die Floats vom Vektor zu komprimieren.

 

 

Du kannst ja mal einen Build posten von deinem simplen Projekt, dann kann man das auch auf einer anderen Maschine testen.

 

 

@TS42 Bolt ist schon was richtig feines :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...