05.11.2012, 17:40 | #1 (permalink) |
Registriert seit: 16.10.2012
Beiträge: 63
|
Einheiten spawnen/ löschen script
wie man sehen kann hab ich ein gewaltiges Problem
http://s1.directupload.net/file/d/3065/dvuzvcph_jpg.htm All die Einheiten sollen Leichen darstellen, das kostet natürlich einiges an Performance. Ich suche grad nach ner Möglichkeit, die Einheiten erst spawnen zu lassen wenn sich der Spieler in der Nähe befindet, wenn er dann wieder das Gebiet verlässt, dann sollen die Leichen wieder verschwinden. DAC und andere Spawnscript, die ich bisher gefunden habe, sind dafür ja ungeeignet. Wichtig wäre halt, dass man der gespawnten Einheit noch einige Befehle geben kann(zB. removeAllWeapons). habt ihr ne Idee? PS: ich weiß das die Engine nicht unbedingt auf sowas ausgelegt ist Geändert von sandmanGER (05.11.2012 um 17:43 Uhr). |
05.11.2012, 21:23 | #2 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Es werden z.B. in einer Stadt zufällig verteilt Soldaten in zufälliger Richtung erstellt und gleich wieder gelöscht.
Dabei speichert man die Position der Soldaten und deren Richtung in einem Array (Stadt1). Bei Bedarf werden an den gespeicherten Positionen wieder Soldaten erstellt, getötet und entwaffnet. Es werden die IDs der Soldaten in einem Array gespeichert (Soldaten1), um sie wieder löschen zu können. Erlischt der Bedarf, dann werden mit dem Array der Soldaten-IDs die toten Soldaten gelöscht. Die Toten Erstellen und Löschen kann so beliebig wiederholt werden. Wobei sie immer an gleicher Position und mit gleicher Stellung liegen werden. Im Folgenden kann ein Beispiel mittels 3 Auslösern durchgeführt werden: 1. Auslöser erstellt erstmals die Soldaten und löscht sie gleich wieder. Drei Soldaten werden in diesem Beispiel um den Spieler erstellt. Code:
Stadt1 = []; for "_i" from 1 to 3 do { _unit = group player createUnit ["USMC_Soldier", position player, [], 0, "FORM"]; _unit setDir floor(random 360); Stadt1 = Stadt1 + [[position _unit select 0,position _unit select 1,getDir _unit]]; deleteVehicle _unit }; player groupChat format ["Stadt1 = %1",Stadt1]; 2. Auslöser erstellt tote Soldaten. Code:
Soldaten1 = []; { _unit = group player createUnit ["USMC_Soldier", [_x select 0, _x select 1], [], 0, "FORM"]; _unit setDir (_x select 2); Soldaten1 = Soldaten1 + [_unit]; _unit setDamage 1; removeAllWeapons _unit; } forEach Stadt1; player groupChat format ["Soldaten1 = %1",Soldaten1]; Code:
{deleteVehicle _x} forEach Soldaten1; Die Anzeige der Array-Inhalte dient nur Testzwecken. |
06.11.2012, 15:17 | #3 (permalink) |
Registriert seit: 16.10.2012
Beiträge: 63
|
Damit lässt sich was anfangen vielen Dank!
Auf diese Weise kann man ja auch Objekte erscheinen lassen. Aber kann man schon platzierten Objekten einen Befehl oder Namen geben, damit sie halt genauso erscheinen wie die Soldaten? zb. Zäune, leere Fahrzeuge.. Geändert von sandmanGER (06.11.2012 um 15:34 Uhr). |
06.11.2012, 20:07 | #4 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Im Editor gibst du den von dir aufgestellten Objekten einen Namen. Hier im Beispiel Name1,Name2,Name3. Diese musst du dann im 1. Auslöser ins Array ObjektNamen1 eintragen.
Test mit drei Auslösern: 1. Auslöser speichert die Position, Richtung und die Type der Objekte und löscht sie. Code:
ObjektNamen1 = [Name1,Name2,Name3]; ObjektDaten1 = []; { ObjektDaten1 = ObjektDaten1 + [[position _x select 0,position _x select 1,getDir _x,typeOf _x]]; deleteVehicle _x } forEach ObjektNamen1; Code:
ObjektNamen1 = []; { _objekt = (_x select 3) createVehicle [0,0]; _objekt setPos [_x select 0, _x select 1]; _objekt setDir (_x select 2); ObjektNamen1 = ObjektNamen1 + [_objekt]; } forEach ObjektDaten1; Code:
{deleteVehicle _x} forEach ObjektNamen1; Auslöser 1 einmaliger Aufruf. Auslöser 2 und 3 mehrfach. Diese können beliebig wiederholt werden (immer nacheinander). |
08.11.2012, 19:52 | #6 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
ObjektNamen1 = nearestObjects [Objekt oder Position, ["Car","Tank",usw.], Radius];
http://community.bistudio.com/wiki/nearestObjects Das geht auch für tote Soldaten, falls du die händisch plazieren willst. Die brauchst du nicht zu töten, sondern nur aufzustellen und dann den weiteren Code für die toten Soldaten verwenden. |
11.11.2012, 13:19 | #7 (permalink) |
Registriert seit: 16.10.2012
Beiträge: 63
|
ich möchte weitere Daten abfragen:
Damage, Fuel hab dafür beim 1. getDammage _x; und bei 2.: setDamage _objekt = (_x select 4) createVehicle [0,0]; ... _object setDamage (_x select 3); Funktioniert nicht. Und für den Fuelstatus hab ich nichts gefunden. |
11.11.2012, 15:08 | #8 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Für eine bessere Übersicht sind die Daten im Array-Feld jetzt anders angeordnet.
Das vereinfachte Löschen mit {deleteVehicle _x} forEach ObjektNamen1; ist jetzt nicht mehr möglich, weil auch Schaden und Tankfüllung gesichert werden. Also immer den ersten Code verwenden! Zeilen fürs Speichern und entfernen (Vor dem ersten Aufruf müssen die ObjektNamen1 geladen sein!): Code:
ObjektDaten1 = []; { ObjektDaten1 = ObjektDaten1 + [[ typeOf _x, position _x select 0, position _x select 1, getDir _x, getDammage _x, fuel _x ]]; deleteVehicle _x }forEach ObjektNamen1; Code:
ObjektNamen1 = []; { _objekt = (_x select 0) createVehicle [0,0]; _objekt setPos [_x select 1, _x select 2]; _objekt setDir (_x select 3); _objekt setDammage (_x select 4); _objekt setFuel (_x select 5); ObjektNamen1 = ObjektNamen1 + [_objekt] } forEach ObjektDaten1; |
11.11.2012, 18:53 | #9 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Es wird einigen Kopfzerbrechen bereiten, wie hier die Daten in den Arrays gespeichert sind?
Zur Sicherheit eine kurze Anschauung: ObjektNamen1 ist ein Array welches die IDs der Objekte enthält: [ ObjektID#1 , ObjektID#2 , ObjektID#3 , usw. ] ObjektDaten1 ist hingegen ein Array welches Arrays enthält, die jeweils die Daten für ein Objekt enthalten: [ [ObjType,PosX,PosY,Dir,Damage,Fuel] , [ObjType,PosX,PosY,Dir,Damage,Fuel] , usw. ] |
17.11.2012, 13:48 | #10 (permalink) |
Registriert seit: 16.10.2012
Beiträge: 63
|
Wie kann man den Munitonsstatus übergeben?
Hintergrund: Wenn ein Fahrzeug gespawn wird, welches zuvor für Damage, Fuel und Munition den Wert 0 erhielt, hat es den Munitionswert 1 und brennt natürlich. ------------------------------------ #2 Und wie kann man den Platzierungsradius einfügen? Das würde für mehr Abwechslung sorgen. _unit set... Geändert von sandmanGER (17.11.2012 um 14:49 Uhr). |
30.12.2012, 13:57 | #12 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Für Objekte zum Entfernen und Wiederherstellen habe ich einmal ein Beispiel erstellt. Dabei werden die Objekte nicht versetzt, sonder gänzlich gelöscht.
Aufgerufen wird das z.B. über einen Auslöser mit Namen Trigger1 der einen bestimmten Radius aufweist in welchen die Objekte aufgestellt sind. Das sieht dann so aus: Code:
temp =["Objekte1",["Car","Tank"],triggerArea Trigger1 select 0,position Trigger1] execVM "Objekte_entfernen_herstellen.sqf"; Durch wiederholten Aufruf des Skripts werden die Objekte gelöscht und wieder hergestellt. Von den Objekten wird die Position, die Richtung, Beschädigung und Tankfüllung beibehalten. Durch unterschiedliche Objekte-Namen (1. Parameter) ist das Skript für beliebig viele Bereiche anwendbar. Skript Objekte_entfernen_herstellen.sqf Code:
/* Objektgruppen entfernen und wiederherstellen [Vienna 30.12.2012] Das Skript ist für beliebig viele Objekt-Gruppen verwendbar. Die Objekt-Gruppen unterscheiden sich durch den Namen im 1. Parameter. Die Objekte werden anhand der Klassen-Namen im Radiusbereich ermittelt. Parameter: (der 1. Parameter bezeichnet den Namen der Gruppe und darf nicht doppelt vorkommen) "NameObjektGruppe", [Array mit ClassNamen], Radius für den Bereich der Objekte, Position Mittelpunkt des Radius Aufrufbeispiel über Auslöser: temp =["Objekte1",["Car","Tank"],triggerArea Trigger1 select 0,position Trigger1] execVM "Objekte_entfernen_herstellen.sqf"; Erster Aufruf des Skripts: die durch die Parameter bestimmten Objekte werden gelöscht. Zweiter Aufruf des Skripts: die gelöschten Objekte werden im vorherigen Zustand wiedererstellt. Dritter Aufruf des Skripts: gleich erster Aufruf. usw. Nach dem ersten Aufruf ist nur noch der erste Parameter von Bedeutung, der die jeweilige Gruppe bezeichnet. */ private ["_globaleVariable_IDs","_globaleVariable_Daten","_globaleVariable_Schalter","_Klassen","_radius","_position","_code","_IDs","_daten","_entfernen"]; _globaleVariable_IDs = (_this select 0)+"_IDs"; _globaleVariable_Daten = (_this select 0)+"_Daten"; _globaleVariable_Schalter = (_this select 0)+"_Schalter"; //eigene globale Variabel für jede Gruppe nach dem Namen im 1. Parameter erstellen if (isNil _globaleVariable_Schalter) then { _Klassen = _this select 1; _radius = _this select 2; _position = _this select 3; //Initialisieren der globalen Variablen gemäß _globaleVariable_IDs _code = format ["%1 = []",_globaleVariable_IDs]; call compile _code; //Initialisieren der globalen Variablen gemäß _globaleVariable_Daten _code = format ["%1 = []",_globaleVariable_Daten]; call compile _code; //Initialisieren der globalen Variablen gemäß _globaleVariable_Schalter _code = format ["%1 = true",_globaleVariable_Schalter]; call compile _code; //1. sichern der Objekt-IDs (entspricht den Namen) _IDs = nearestObjects [_position,_Klassen,_radius]; //Übertragen der Daten in die globale Variable gemäß _globaleVariable_IDs _code = format ["%1 = _IDs",_globaleVariable_IDs]; call compile _code }; //Auslesen der "Schalterstellung" in Variable _entfernen _code = format ["_entfernen = %1",_globaleVariable_Schalter]; call compile _code; //Entfernen oder Wiederherstellen je nach Schalterstellung (true/false) if (_entfernen) then // Sichern und Entfernen der Gruppe { //IDs aus globaler Variabler gemäß _globaleVariable_IDs übernehmen _code = format ["_IDs = %1",_globaleVariable_IDs]; call compile _code; //Daten der Objekte sichern und Objekte löschen _daten = []; { _daten = _daten + [[ typeOf _x, position _x select 0, position _x select 1, position _x select 2, getDir _x, getDammage _x, fuel _x ]]; deleteVehicle _x }forEach _IDs; //Daten aus _daten in globale Variable gemäß _globaleVariable_Daten übertragen _code = format ["%1 = _daten",_globaleVariable_Daten]; call compile _code; //globale Variable gemäß _globaleVariable_Schalter auf false stellen _code = format ["%1 = false",_globaleVariable_Schalter]; call compile _code } else //Wiederherstellen der Gruppe { //Daten aus globaler Variabler gemäß _globaleVariable_Daten übernehmen _code = format ["_daten = %1",_globaleVariable_Daten]; call compile _code; //Objekte der Gruppe aufstellen und Namen(IDs)der Objekte sichern _IDs = []; { _objekt = (_x select 0) createVehicle [0,0]; _objekt setPos [_x select 1, _x select 2, _x select 3]; _objekt setDir (_x select 4); _objekt setDammage (_x select 5); _objekt setFuel (_x select 6); _IDs = _IDs + [_objekt] } forEach _daten; //Daten aus _IDs in globale Variable gemäß _globaleVariable_IDs übertragen _code = format ["%1 = _IDs",_globaleVariable_IDs]; call compile _code; //globale Variable gemäß _globaleVariable_Schalter auf true stellen _code = format ["%1 = true",_globaleVariable_Schalter]; call compile _code } |
31.12.2012, 12:51 | #13 (permalink) |
Registriert seit: 16.10.2012
Beiträge: 63
|
Mir ist aufgefallen, dass die Objekte nur ein einziges mal bestimmt werden, anschließend werden sie halt immer gelöscht und wieder neu platziert.
Wenn man also im Nachhinein in dem Bereich Fahrzeuge abstellt, werden diese in dem Script nicht miteinbezogen. Es werden halt nur die Objekte verarbeitet, die sich zuanfang innerhalb des Radius befanden. Desweiteren werden die Fahrzeuge, die schonmal gelöscht und neu platziert wurden und sich nun außerhalb des Radius befinden (weil man sie einfach weggefahren hat) weiterhin gelöscht und platziert. Wenn man diese drei Schritte immer von vorne beginnen würde, könnte man diese "Bugs" vermeiden. Wie man das allerdings scriptet weiß ich nicht |
01.01.2013, 10:53 | #14 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Dem wird in der folgenden Version entsprochen.
Über einen neu hinzugekommenen Parameter (auf Platz 2) ist einzustellen, ob die Objekte vor dem Löschen gem. den Parametern 3-5 neu eingelesen werden. Siehe auch Beispiel im Anhang. Code:
/* Objektgruppen entfernen und wiederherstellen [Version 2 Vienna 01.01.2013] Das Skript ist für beliebig viele Objekt-Gruppen verwendbar. Die Objekt-Gruppen unterscheiden sich durch den Namen im 1. Parameter. Die Objekte werden anhand der Klassen-Namen im Radiusbereich ermittelt. Ist der 2. Parameter auf true, dann werden bei jedem Löschen die Objekte im Radiusbereich neu eingelesen. Dabei können auch Parameter 3-5 geändert werden. Parameter: "NameObjektGruppe", (der 1. Parameter bezeichnet den Namen der Gruppe und darf nicht doppelt vorkommen) true/false, (true = neues Einlesen der Objekte gemäß der folgenden Parameter. [Array mit ClassNamen], Radius für den Bereich der Objekte, Position Mittelpunkt des Radius Aufrufbeispiel über Auslöser: temp =["Objekte1",true,["Car","Tank"],triggerArea Trigger1 select 0,position Trigger1] execVM "Objekte_entfernen_herstellen2.sqf"; Erster Aufruf des Skripts: die durch die Parameter bestimmten Objekte werden gelöscht. Zweiter Aufruf des Skripts: die gelöschten Objekte werden im vorherigen Zustand wiedererstellt. Dritter Aufruf des Skripts: gleich erster Aufruf. usw. */ private ["_globaleVariable_IDs","_globaleVariable_Daten","_globaleVariable_Schalter","_neueObjekte","_Klassen","_radius","_position","_code","_IDs","_daten","_entfernen"]; _globaleVariable_IDs = (_this select 0)+"_IDs"; _globaleVariable_Daten = (_this select 0)+"_Daten"; _globaleVariable_Schalter = (_this select 0)+"_Schalter"; _neueObjekte = _this select 1; //eigene globale Variabel für jede Gruppe nach dem Namen im 1. Parameter erstellen if (isNil _globaleVariable_Schalter) then { //Initialisieren der globalen Variablen gemäß _globaleVariable_IDs _code = format ["%1 = []",_globaleVariable_IDs]; call compile _code; //Initialisieren der globalen Variablen gemäß _globaleVariable_Daten _code = format ["%1 = []",_globaleVariable_Daten]; call compile _code; //Initialisieren der globalen Variablen gemäß _globaleVariable_Schalter _code = format ["%1 = true",_globaleVariable_Schalter]; call compile _code; //für 1. Sichern der Objekte-Namen(IDs) jedenfalls auf true stellen _neueObjekte = true }; //Auslesen der "Schalterstellung" in Variable _entfernen _code = format ["_entfernen = %1",_globaleVariable_Schalter]; call compile _code; //Auslesen der Objekte-Namen(IDs) gemäß der Klassen im Radiusbereich if (_entfernen and _neueObjekte) then //1. Sichern sowie weiteres sichern wenn 2. Parameter = true { _Klassen = _this select 2; _radius = _this select 3; _position = _this select 4; //sichern der Objekt-IDs (entspricht den Namen) _IDs = nearestObjects [_position,_Klassen,_radius]; //Übertragen der Daten in die globale Variable gemäß _globaleVariable_IDs _code = format ["%1 = _IDs",_globaleVariable_IDs]; call compile _code } else //Laden der Objekte-Namen(IDs) gemäß der 1. Sicherung wenn 2. Parameter = false { //Namen(IDs) aus globaler Variabler gemäß _globaleVariable_Ids übernehmen _code = format ["_IDs = %1",_globaleVariable_IDs]; call compile _code; }; //Entfernen oder Wiederherstellen je nach Schalterstellung (true/false) if (_entfernen) then // Sichern und Entfernen der Gruppe { //IDs aus globaler Variabler gemäß _globaleVariable_IDs übernehmen _code = format ["_IDs = %1",_globaleVariable_IDs]; call compile _code; //Daten der Objekte sichern und Objekte löschen _daten = []; { _daten = _daten + [[ typeOf _x, position _x select 0, position _x select 1, position _x select 2, getDir _x, getDammage _x, fuel _x ]]; deleteVehicle _x }forEach _IDs; //Daten aus _daten in globale Variable gemäß _globaleVariable_Daten übertragen _code = format ["%1 = _daten",_globaleVariable_Daten]; call compile _code; //globale Variable gemäß _globaleVariable_Schalter auf false stellen _code = format ["%1 = false",_globaleVariable_Schalter]; call compile _code } else //Wiederherstellen der Gruppe { //Daten aus globaler Variabler gemäß _globaleVariable_Daten übernehmen _code = format ["_daten = %1",_globaleVariable_Daten]; call compile _code; //Objekte der Gruppe aufstellen und Namen(IDs)der Objekte sichern _IDs = []; { _objekt = (_x select 0) createVehicle [0,0]; _objekt setPos [_x select 1, _x select 2, _x select 3]; _objekt setDir (_x select 4); _objekt setDammage (_x select 5); _objekt setFuel (_x select 6); _IDs = _IDs + [_objekt] } forEach _daten; /*Daten aus _IDs in globale Variable gemäß _globaleVariable_IDs übertragen wenn nur die erstmaligen Objekte gesichert werden*/ if (not _neueObjekte) then { _code = format ["%1 = _IDs",_globaleVariable_IDs]; call compile _code }; //globale Variable gemäß _globaleVariable_Schalter auf true stellen _code = format ["%1 = true",_globaleVariable_Schalter]; call compile _code } |
01.01.2013, 14:14 | #15 (permalink) |
Registriert seit: 16.10.2012
Beiträge: 63
|
Es wäre, glaube ich, noch einfacher wenn man nur 2. Auslöser verwendet, anstatt mehrere zu platzieren, um ein größeres Gebiet abzudecken. Immerhin soll damit ja Perfomance gewonnen werden.
Man bräuchte einen großen Auslöser (zb. 1500m Radius). Dieser begrenzt das entsprechende Gebiet. In ihm werden zuanfang alle Objekte gespeichert und gelöscht. Ein 2. Auslöser (zb. 200m) müsste dann am Spieler haften. Er bewegt sich somit. In ihm werden alle Objekte geladen und wieder platziert. Sodass sich um den Spieler immer genügend Objekte befinden. Das Script sollte dann immer alle 5 Sekunden ausgeführt werden, damit es sich nicht aufhängt. Natürlich funktioniert das ganze nicht, wenn man mit nem Jet durchs Gebiet fliegt, aber das kommt in meiner Mission eh nicht vor. Wär cool wenn du das auch noch hinkriegst |
01.01.2013, 18:27 | #16 (permalink) |
Registriert seit: 12.07.2004
Ort: Wien
Beiträge: 1.917
|
Das wäre nicht einfach zu bewerkstelligen, besonders im Mehrspielermodus. Es muss der Abstand zur Position jedes gelöschten Objektes abgefragt werden.
Mit obigem Skript musst du so vorgehen, dass die Auslöserkreise jeweils die größten Mengen an Objekten abdecken. Die Kreise dürfen sich nicht überscheiden. In den freibleibenden Bereichen werden die Objekte nicht gelöscht. Hast du dir schon Gedanken gemacht wie du nach dem ersten Löschen die Objekte ein- und ausschaltest? Als Einzelspieler ist das recht einfach mit Distance des Spielers zu den einzelnen Auslösern möglich. Im Mehrspielermodus muss das der Server/Host steuern und bei den Schaltvorgängen alle Spieler berücksichtigen. |
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
|
|
Ähnliche Themen | ||||
Thema | Autor | Forum | Antworten | Letzter Beitrag |
Beta-Patch für OpA erschienen | det99 | Community | 1429 | 18.07.2014 16:51 |
zufälliges Spawnen von Einheiten | sandmanGER | Editing & Scripting | 7 | 17.10.2012 21:56 |
Einheiten in Gruppe löschen | Brubaker | Editing | 6 | 26.05.2011 17:44 |
Heal/Repair Script / Einheiten in einem Radius zufällig generieren lassen | Noobfire | Editing & Scripting | 8 | 06.08.2010 15:22 |
Script-Problem: Einheiten löschen | Kampfmöhre | Editing & Scripting | 5 | 31.05.2010 12:37 |