21.05.2009, 16:01 | #1 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Befehlsübertragung in Multiplay mit Auslöser
Oft kommt es vor, dass im Editor positiv getestete Missionen im Multiplayermodus nicht korrekt laufen. Das liegt meist daran, weil bestimmte Befehle auf jedem Spieler-PC lokal ausgeführt werden müssen.
Für den Multiplayermodus gibt es ab ArmA V1.09 auch die Möglichkeit Befehle (Code) mit publicVariable zu übertragen. Das ermöglicht nun eine lokale Befehlsausführung an allen gewünschten PCs im Multiplayermodus über Auslöser. Ein ebenfalls neuer publicEventHandler hat den Nachteil, dass Befehle nicht auf dem PC des Absenders ausgeführt werden. Mit den "Auslöser-Befehlsempfängern" wird der Befehl auch beim Absender ausgeführt (falls er für ihn vorgesehen ist). Die Befehle brauchen einfach nur in die entsprechenden Variablen angeführt und mit publicVariabel übertragen werden. Folgende Variable sind für die Übertragung vorhanden: BefehlAnAlle (Befehle werden bei Server und Clients ausgeführt) BefehlAnWest (Befehle werden nur bei West-Spielern ausgeführt) BefehlAnEast (Befehle werden nur bei East-Spielern ausgeführt) BefehlAnServer (Befehle werden nur beim Server/Host ausgeführt) BefehlAnPlayer (Befehle werden nur bei den Spielern ausgeführt) Beispiel mit dem ein Spieler ein Skript beim Server/Host startet: BefehlAnServer = {[] exec "Skriptname.sqs"}; publicVariable "BefehlAnServer"; Beispiel um bei den Westspielern eine "hint"-Meldung anzuzeigen: BefehlAnWest = {hint "Hallo Westspieler!"}; publicVariable "BefehlAnWest"; Es können auch mehrere -durch ; getrennte- Befehle angegeben werden. Eine Befehlsübertragung mit den Variablen ist mehrfach möglich. Zwischen den Übertragungen mit der selbigen Variablen sollte aber mindestens 1 Sekunde Abstand liegen. Um die Befehls-Auslöser zu verwenden, brauchen nur die 5 Auslöser in die Mission kopiert werden (Kopieren: Strg+C und Einfügen: Strg+V). Es können auch nur die Auslöser kopiert werden, welche in der eigenen Mission Verwendung finden. In der Beispielmission ist ein Test der Übertragung möglich. Es sind Funkauslöser vorhanden, welche bei Markern die Farbe ändern. Es wird nur der lokale Markerbefehl genommen, aber durch die Befehlsübertragung läuft die Umfärbung an allen zutreffenden PCs. |
22.05.2009, 08:47 | #2 (permalink) |
Registriert seit: 03.01.2008
Alter: 84
Beiträge: 6.552
|
Das Ausführen eines Befehls auf der Sender Seite bei Nutzung von publicVariable Eventhandler ist kein Problem. Schick den Befehl an eine Funktion die je nach Parameter den Befehl auf der Senderseite ebenfalls noch ausführt bevor der Befehl über das Netz wandert. Beispiel: Code:
[{"West" setMarkerColorLocal "ColorRed"; player groupChat "Marker West auf rot!"}, 1] call SendToWest; Code:
SendToWest = { BefehlAnWest = _this select 0; if ((_this select 1) == 1) then {call (_this select 0)}; publicVariable "BefehlAnWest"; }; "BefehlAnWest" addPublicVariableEventhandler { call (_this select 1); }; Dein ganzes Beispiel lässt sich so komplett ohne einen einzigen Auslöser erstellen. Xeno
__________________
In arma everything is made of refined explodium, armored with wet paper towels. |
22.05.2009, 11:43 | #3 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Natürlich geht das auch über den EventHandler und ohne Auslöser (dazu wurde dieser neue EventHandler ja hinzugefügt).
Ich habe es aber absichtlich mit Auslöser gemacht, weil es so einfacher und ohne ein Skript verwendbar ist. In deinem Beispiel ist die Variable nach der Befehlsausführung noch zurückzustellen. Das selektierte Installieren der EventHandler verkompliziert die Sache nur. Auch ist es nicht ideal, dass bei jedem Aufruf erst festgelegt werden muss, ob der Absender auch den Befehl ausführen soll. Wenn ein Befehl für West ist, dann hat er automatisch für alle Westeinheiten zu gelten. Über Skript würde ich das so auslegen, dass nur eine Variable und somit nur ein Eventhandler notwendig ist. Hauptsächlich für den Server. Bei den Clients sind Überschneidungen nicht ausgeschlossen, das wäre nur mit einer eigenen Variablen für jeden Spieler abwendbar. Überhaupt sollte das Übertragen von Code nur sehr sparsam eingesetzt werden, weil die Fehler bei schlechter Internetverbindung noch umfangreicher werden. Ideal wäre die Übertragung von Zahlenkodes, welche dann bestimmte Befehle auslösen. |
22.05.2009, 12:00 | #4 (permalink) |
Registriert seit: 03.01.2008
Alter: 84
Beiträge: 6.552
|
Falsch, eben das braucht man nicht. Auch das lässt sich nach Bedarf ändern, dass was ich geposted habe war nur ein Beispiel. Komm mal etwas aus dem alten publicVariable Denken raus. Du kannst von 100 Rechnern aus eine pub Var an einen publicVariable Eventhandler schicken, alle werden ausgeführt, kein Zurücksetzen von Variablen notwendig. Das ist ebenfalls falsch. Ansonsten würde ein Mod wie z.B. A.C.E. nicht funtkionieren. Dort wird zig Code über ein und den selben Handler geschickt, es funktioniert trotzdem. Auch das ist machbar, setze ich so in der Domina ein, allerdings schicke ich größtenteils Strings. Xeno
__________________
In arma everything is made of refined explodium, armored with wet paper towels. |
22.05.2009, 13:14 | #5 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Verstehe ich das richtig, wenn ich mit publicVariable die Variable übers Netz sende, dann wird der EventHandler aktiviert, egal welchen Inhalt die Variable hat? Wenn das so ist, dann erübrigt sich natürlich das Rückstellen der Variablen (das wäre dann nur für die Bedingung bei Auslösern notwendig). Bis jetzt war ein Ereignis nur einleitbar, wenn sich der Inhalt der Variablen geändert hat. Ich habe kein Netzwerk, darum kann ich das nicht überprüfen.
Weiters, wenn zwei Spieler gleichzeitig mit publicVariable die gleiche Variable übers Netz senden, dann wird der EventHandler auf unbeteiligten PCs zweimal, bei den beteiligten nur der vom anderen Sender aktiviert (da könnte es Probleme bei der "Eigenaktivierung" geben)? Ob das System einen oder hundert EventHandler überprüfen muss, wird sich wohl schon auf die Rechnerleistung auswirken. Ebenso sind Übertragungs- und Koordinierungsfehler bei größeren Datenmengen (z.B. Code) wahrscheinlicher. Hauptsächlich wenn sie von Clients erfolgen, die oft sehr unterschiedliche Übertragungsgeschwindigkeiten haben. Dazu habe ich aber keine Ahnung, wie das in ArmA koordiniert wird. Bei OFP war es noch schrecklich. Jedenfalls danke ich dir für deine Ausführungen. Wenn ich vielleicht nochmal eine MP-Mission schreibe, werde ich sicher noch mehr Tipps von dir brauchen. |
23.05.2009, 01:27 | #6 (permalink) |
Registriert seit: 03.01.2008
Alter: 84
Beiträge: 6.552
|
Korrekt. Der publicVariable Eventhandler reagiert sobald die Variable von irgendwoher kommt. Das ist der entscheidene Vorteil. Du brauchst kein Netzwerk dafür, starte einfach einen dedicated Server (arma_server.exe) auf Deinem Rechner und connecte auf dem. Nö, gibts keine Probleme. Du darfst allerdings in dem addPublicVariableEventhandler nicht direkt die Variable abfragen, sondern _this select 1. _this select 1 beinhaltet den Variablenwert. Nein, gibt keine nennenswerten Probleme in diesem Bereich, absolut nicht. Leider, leider ist der MP Bereich bei ArmA einer der schwierigsten, gerade weil es so gut wie keine Informationen dazu gibt. Das meiste lernt man nur durch try and error. Mit ein paar Einheiten platzieren im Editor ist es im MP Bereich nicht getan. Die meisten die sich daran versucht haben, scheitern schon am Lokalitätsproblem geschweige denn haben je eine Chance solche netten Dinge wie die public Variable Eventhandler überhaupt zu verstehen. Xeno
__________________
In arma everything is made of refined explodium, armored with wet paper towels. |
23.05.2009, 12:09 | #8 (permalink) |
Registriert seit: 24.01.2009
Beiträge: 209
|
Ja der Tipp hatte mir auch ordentlich weiter geholfen, man kommt den Fehlern so einfach schnell auf die Schliche.
Aber irgendwie komm ich nicht so recht an die SQF Syntax ran, da bedarfs mal einer Idiotensicheren Erklärung, pö a pö! |
23.05.2009, 13:39 | #9 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
SQF syntax - Bohemia Interactive Community
Wenn du dabei auch die weiterführenden Links durchliest, bist du eigentlich gut bedient. |
31.05.2009, 11:02 | #10 (permalink) |
Registriert seit: 28.12.2008
Beiträge: 56
|
Jedes Byte in einer Variable die per publicVariable übertragen wird braucht Traffic !
Und zwar für JEDEN! Client, sowie natürlich den Server. Natürlich kann man nach dem Emfangen Abfragen machen, ob die Nachricht für sich selbst ist. Aber Traffic wird trotzdem verbraucht. Das ist der Grund, warum man keine (langen) Strings senden sollte. Also auch keinen CODE !! |
31.05.2009, 19:43 | #11 (permalink) |
Registriert seit: 03.01.2008
Alter: 84
Beiträge: 6.552
|
Hunter...
Ich habe da andere Erfahrungen gemacht. Ein paar Strings die gesendet werden machen den Bock nicht fett im Vergleich z.B. zu den dauernden setPos Übertragungen von allen Objekten die über das Netz laufen. Senden von Code macht da gar nichts, auch nicht von längeren Passagen. Xeno
__________________
In arma everything is made of refined explodium, armored with wet paper towels. |
30.05.2010, 13:01 | #12 (permalink) |
Registriert seit: 23.05.2008
Ort: Hamburg / Norderstedt
Alter: 46
Beiträge: 44
|
Moin,
tschuldigung das ich den "alten" Tread wieder rauskram, aber ich wollt dafür keinen neuen neuen aufmachen.. wenn ich einem Codeblock per publicVari - eh vom server zu den Clients sende funktioniert dies soweit, meine Frage ist kann ich lokale Variablenwerte, mitschicken? also ohne diese in ein array zupacken und in der Funktion nochmal direkt auszulesen.. init.sqf Code:
//server only if (isServer) then { //serverseitige Funktionen funcNvC = compile preprocessFile "BierAIG\server\funcNvC.sqf";//Function Nachricht vom Client funcFahrzeugRespawn = compile preprocessFile "BierAIG\server\funcFahrzeugRespawn.sqf";//Function Fahrzeug Respawn "NachrichtVomClient" addPublicVariableEventHandler { _nachricht = [_this] call funcNvC; };//end addPublicVari-EH };//end if-then //clients only if (!(isServer)) then { //clientseitige Funktionen funcNvS = compile preprocessFile "BierAIG\client\funcNvS.sqf";//Function Nachricht vom Server "NachrichtvomServer" addPublicVariableEventHandler { _nachricht = [_this] call funcNvS; };//end addPublicVari-EH };//end if-then //server & client funcFahrzeugAddKilledEH = compile preprocessFile "BierAIG\funcFahrzeugAddKilledEH.sqf";//Function Fahrzeug killed-EH geben funcFahrzeugKilled = compile preprocessFile "BierAIG\funcFahrzeugKilled.sqf";//Function Fahrzeug killed { _eh = [_x] call funcFahrzeugAddKilledEH; } foreach vehicles; Code:
_wert = _this select 0; _code = _wert select 1; call (_code select 0); Code:
//server _toter = _this select 0; _killer = _this select 1; //rauch und explosionen abwarten _typetoter = typeof _toter; _position = position _toter; _richtung = getdir _toter; _toter removealleventhandlers "killed"; deleteVehicle _toter; _neuesFahrzeug = _typetoter createVehicle _position; _neuesFahrzeug setpos _position; _neuesFahrzeug setDir _richtung; [_neuesFahrzeug] call funcFahrzeugAddKilledEH; NachrichtVomServer = {[_neuesFahrzeug] call funcFahrzeugAddKilledEH;}; publicVariable "NachrichtVomServer"; Code:
_wert = _this select 0; _code = _wert select 1; call (_code select 0); Code:
//server & client _fahrzeug = _this select 0; _fahrzeug addEventHandler ["killed", {_wert = [_this] call funcFahrzeugKilled;}]; Code:
//server & client _wert = _this select 0; _toter = _wert select 0; _killer = _wert select 1; if (!(isServer)) then { NachrichtVomClient = {[_toter,_killer] call funcFahrzeugRespawn;}; publicVariable "NachrichtVomClient"; };//end if-then if (isServer) then { [_toter,_killer] call funcFahrzeugRespawn; };//end if-then ist es überhaupt möglich, in dem Codeblock Variablen reinzupacken? Mfg Langer p.s. öhm funzt die Suchfunktion, hier im Forum nicht mehr?
__________________
hoch die Tassen, geschmollt wird später Geändert von Langer (30.05.2010 um 13:13 Uhr). |
30.05.2010, 14:02 | #13 (permalink) |
Registriert seit: 12.06.2006
Beiträge: 1.252
|
Es scheint ein Verständnisproblem bei dir vorzuliegen.
Code:
{[_toter,_killer] call funcFahrzeugRespawn;}; 2) Durch die Verwendung von call gibt die Funktion einen Wert zurück. Code:
NachrichtVomClient = {[_toter,_killer] call funcFahrzeugRespawn;}; und weißt es der GV NachrichtVomClient zu. Statt dessen langt es vollkommen die Referenz des Fahrzeugs der GV zu übergeben. 4) Die Referenz des Fahrzeuge sollte anschließend an alle Clients übertragen werden. Prüfe die Variableninhalt mit der Debug Console by Gaia und diag_log. Generelle Tipps: Community modding bible links N Beispiel: vehicleRespawn.sqf Code:
// add vehicle actions after respawn AAS_PublicAddActionsAndEH = _vehicle; publicVariable "AAS_PublicAddActionsAndEH"; Code:
"AAS_PublicAddActionsAndEH" addPublicVariableEventHandler { _vehicle = _this select 1; [_vehicle] spawn cmdEnhanceViewDistance; // clear vehicle cargo clearWeaponCargo _vehicle; clearMagazineCargo _vehicle; };
__________________
PvPscene |
30.05.2010, 16:11 | #14 (permalink) |
Registriert seit: 23.05.2008
Ort: Hamburg / Norderstedt
Alter: 46
Beiträge: 44
|
(arma2 schafft mein "taschenrechner" net und fürn neuen fehlt momentan das geld daher "fummel" ich noch in arma 1 rum...)
jo ich weiss^^ ich hab nur die "standart-version" der funcFahrzeugKilled.sqf gepostet.... selbst wenn ich ein string übergebe, fehlen anscheinend die objekte für die call-anweisung also im prinzip versuche ich, momentan, nen array zu übergeben. dieses array soll aus nem Codeschnipsel, sowie aus den objekten,welche im codeschnipsel "benutzt" werden sollen, bestehen. meine Frage ist, sofern möglich, wie müsste dieses array aussehen?? NachrichtVomClient = [{codeschnipzel},[wert1,wert2]]; in der funcNvC soll dann aus diesem übergebenem Array der codeschnipsel ausgeführt werden Code:
_komplett = _this select 0; _array = _komplett select 1; _code = _array select 0; call _code; Code:
{_array = NachrichtVomClient select 1; _werte = _array select 1; _wert1 = _werte select 0; _wert2 = _werte select 1; [_wert1,_wert2] call funcFahrzeugRespawn;} nämlich nur zwei (einen für den server, einen für den client) nicht für jede mögliche übergabe einen, wo nur nur die geforderten werte public werden, diese im EH ausgelesen und je nach zweck "verarbeitet" würden das würde funcNvC/funcNvS universell einsetzbar machen.. was mir fehlt ist die schreibweise, also codeschnipsel und die beiden werte in ein array zu packen, sowie im codeschnipsel die werte einlesen... wenn dies überhaupt möglich sein sollte ... grosses Fragezeichen sorry falls ich des ein wenig "komisch" erlären sollte.. Mfg Langer
__________________
hoch die Tassen, geschmollt wird später Geändert von Langer (30.05.2010 um 16:31 Uhr). |
30.05.2010, 17:27 | #15 (permalink) |
Registriert seit: 12.06.2006
Beiträge: 1.252
|
Aus Erfahrung (Xeno, Sickboy, mir) spielt die Anzahl der PVEH keine Rolle.
Das Wichtigste ist möglichst wenig Daten übers Netwerk zu verschicken. Insofern wenn du n generische PVEH unbedingt haben willst, dann schick einen Identifier mit. globalDefines.hpp Code:
#define AAS_VEHICLERESPAWN 1 Code:
#include "globalDefines.hpp" ... AAS_PVEH = [AAS_VEHICLERESPAWN,_vehicle]; publicVariable "AAS_PVEH"; Code:
#include "globalDefines.hpp" ... "AAS_PVEH" addPublicVariableEventHandler { _identifier = (_this select 1) select 0; switch (_identifier) do { case (AAS_VEHICLERESPAWN): { _vehicle = (_this select 1) select 1; [_vehicle] spawn cmdEnhanceViewDistance; // clear vehicle cargo clearWeaponCargo _vehicle; clearMagazineCargo _vehicle; }; }; };
__________________
PvPscene |
30.05.2010, 18:07 | #16 (permalink) |
Registriert seit: 23.05.2008
Ort: Hamburg / Norderstedt
Alter: 46
Beiträge: 44
|
oh man...
bin ich auf die einfache Lösung mal wieder net gekommen.. 1000 Dank.. mit dieser Methode sind die "codeschnipsel" in einer Function und nicht wild über viele verteilt.... Mfg Langer
__________________
hoch die Tassen, geschmollt wird später |
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
Themen-Optionen | |
Ansicht | |
|
|
Ähnliche Themen | ||||
Thema | Autor | Forum | Antworten | Letzter Beitrag |
Heli mit Wegpunkte durch Auslöser starten lassen | Althalus | Editing | 20 | 20.05.2009 10:15 |
Auslöser Alarm | DirtyHarryTPC | Editing | 4 | 12.12.2008 13:42 |
Auslöser Helikopter | lestatxtc | Editing | 2 | 08.02.2008 12:47 |
Auslöser | Omega | Editing | 3 | 22.12.2006 18:31 |
Fagen zu Auslöser | SvenPatrick | Editing | 4 | 16.12.2006 21:00 |