PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Array juchey


wolkenstuermer
08.08.2015, 17:10
Hallo!

Ich verzweifele langsam und sicher daran, dass ich nicht begreife, wie ich Einheiten, die ich gespawnt habe, wieder anspreche.

Sinn soll sein, dass man an einem Punkt beliebig oft Einheiten spawnen kann, vielleicht im eigenen Menü, vielleicht an einem Whiteboard, wie auch immer.

Die Einheiten sollen dann spawnen und ich will die Kontrolle darüber haben, sprich z.B. möchte ich auch alle gespawnten Einheiten wieder löschen können (aber eben nur diese).

Das Skript sieht bis jetzt so aus:

_grp1 = createGroup EAST;
_list1 = [];
{
_unit = [getMarkerPos "spawn", EAST, [_x],[],[],[],[],[],180] call BIS_fnc_spawnGroup;
[_unit] join _grp1;
_list1 = _list1 + [_unit];
} forEach ["O_Soldier_F"];

sleep 3;

{deleteVehicle _x;} forEach _list1;

Nur funktioniert mein "forEach _list1" kein bisschen. Und ich schnalle nicht warum.
Kann einer der Skriptbegabten einen Noob mal auf die richtige Spur bringen? Vermutlich ist es völlig einfach und ich renne nur mit dem Kopf immer gegen den Laternenpfahl ...

cheers!
Wolkenstuermer

Nokman
09.08.2015, 13:47
private ["_grp1","_list1","_unit"];
_grp1 = createGroup EAST;
_list1 = [];
{
_unit = [getMarkerPos "spawn", EAST, [_x],[],[],[],[],[],180] call BIS_fnc_spawnGroup;
_list1 = _list1 + units _unit;
[_unit] join _grp1;

} forEach ["O_Soldier_F"];

sleep 3;

{deleteVehicle _x;} forEach _list1;

So müsste es gehen das Problem was du hatest ist das _unit keine einheit ist sondern eine Gruppe. im Grunde ist der Aufbau von dir auch etwas sinlos so da du eine Gruppe erstelst und die in eine Gruppe Joinen läst. Deswegen konnte er zu list1 auch nix hinzufügen als der befehl ausgeführt wurde war die Gruppe nicht mehr da.

Schaue dir aber mal denn Befehl an
https://community.bistudio.com/wiki/createUnit_array der ist genau das was du brauchst

wolkenstuermer
10.08.2015, 12:59
Hi Nokman,

vielen Dank für die Erhellung :)
Muss noch viel lernen und manchmal sehe ich das Byte vor lauter Bit nicht mehr.

Das mit dem CreateUnitArray ist sehr interessant, damit werde ich wohl mal rumpfuschen.

Danke nochmal!
cheers!

wolkenstuermer
10.08.2015, 14:17
Zwei Fragen hätte ich noch:

Das mit den privates hast du eingefügt, damit die Werte beim erneuten Aufrufen nicht überschrieben werden, oder?

Und: Wenn ich nun in einem weiteren Skript die Liste löschen möchte, wie mache ich das? Die Variablen sind ja alle lokal. Muss ich mich da mit Strings und compile auseinandersetzen oder gibt es eine einfache Lösung?

Sinn wäre: In einem Skript Einheiten spawnen, im anderen Skript diese gespawnten Einheiten wieder löschen, indem ich sie direkt anspreche.

Drunken Officer
11.08.2015, 14:21
Sinn wäre: In einem Skript Einheiten spawnen, im anderen Skript diese gespawnten Einheiten wieder löschen, indem ich sie direkt anspreche.

globaleVariable nutzen.

z.b. der Aufruf in Script 1:
grp = ...... call BIS_fnc_spawngroup

Löschen im Script 2:
{_x setdammage 1 } forEach units grp



Nachtrag: Ansonsten kann ich mich Nokman anschließen, da dein Code "komisch" ist.

Entweder zu erstellst eine Gruppe und läßt die alle übertreten oder einen Soldaten.

1. Gruppe mit 3 Leuten

private ["_grp1","_list1"];
_list1 = [];
_grp1 = [getMarkerPos "spawn", EAST, ["O_Soldier_F", "O_Soldier_F","O_Soldier_F"],[],[],[],[],[],180] call BIS_fnc_spawnGroup;
{
_list1 = _list1 + [_x];
} forEach units _grp;


2. eine vordefinierte Gruppe:

private ["_grp1","_list1"];
_list1 = [];
_grp1 = [getMarkerPos "spawn", east, configfile >> "CfgGroups" >> "EAST" >> "caf_ag_me_t" >> "Infantry" >> "6_men_me_t")] call BIS_fnc_spawnGroup;
{
_list1 = _list1 + [_x];
} forEach units _grp;


3. Gruppe erstellen und 30 Leute rein:

private ["_grp","_list1","_unit"];
_list1 = [];
_grp = creategroup east;
for "_i" from 1 to 30 do

{
_unit = _grp createUnit ["O_Soldier_F", getMArkerPos "spawn", [], 0, "FORM"];
_list1 = _list1 + [_unit];
};

wolkenstuermer
11.08.2015, 17:20
Hallo Drunken,

danke für die Tipps!

Aber das ist ja das Problem, ich kriege es mit globalen Variablen nicht gebacken. Ich will das Skript ja mehrfach aufrufen können. In dem Fall würde er die globale Variable ja überschreiben.

Mein Script ist sicherlich komisch, ich versuche damit nur zu begreifen, wie ich Einheiten in einer Liste speichern und diese dann wieder entfernen kann. Das ist kein sinnvolles Skript für irgendwas, sondern soll meiner Matschbirne endlich ein Heureka entlocken ;)

(bin kein Programmierer und lerne das quasi von Adam und Eva an)

Wunsch: Ich habe in einer Mission z.B. eine Flagge. An dieser kann ich Einheiten spawnen lassen. Ich kann das Skript mehrmals aufrufen, dann werden eben n Einheiten gespawnt. Egal ob nun eine Einheit oder n Einheiten, ich möchte dann mit einem zweiten Skript ALLE Einheiten wieder entfernen können, die ich mit dem ersten in die Liste geschrieben/gespawnt habe.

Noch blicke ich nicht, was ich falsch mache. Global geht es nicht, da dann der zweite Soldat den ersten "überschreibt" (oder liege ich da falsch?) und lokal geht es auch nicht, da er meine Variable aus dem ersten Skript nicht wiederfindet.

Aber es muss doch irgendwie gehen, man muss doch irgendwie Listen in einem Skript an andere übergeben können, ohne sich übergeben zu müssen :ugly:

Bzw. wie wäre denn eine sinnvolle Lösung für meine Spawn/Despawn Kombi?

Drunken Officer
11.08.2015, 20:24
Dann baue einen globalen Array. Z.B. in der Init.sqf
Unitsarray = [];

Danach füllst du den Array. Bis jetzt wurde dafür _list1 genommen. _list1 ist aber eine lokale Varibable und wird nur in dem Script verwendet.
Mit unitsarray wird dieser immer weiter gefüllt.

Zum löschen der Einheiten wurde ja bereits geschrieben:
{_x setdammage 1} forEach unitsarray

BEISPIEL:
SEtze deinen Spieler
Setze einen Marker und benenne diesen "spawn"
setze eine Flagge in die Init der Flagge schreibst du:

unitarray = [];
this addaction ["SPAWN",
{
["spawn", 12] spawn
{
private ["_grp","_unit"];

_grp = creategroup east;
for "_i" from 1 to (_This select 1) do

{
_unit = _grp createUnit ["O_Soldier_F", getMArkerPos (_this select 0), [], 0, "FORM"];
unitarray = unitarray + [_unit];
};
};
}];


Setze einen Funktrigger mit mehrfacher Auslösung. In die Aktivierung schreibst du:
{_x setdammage 1} forEach unitarray

--> Lasse Einheiten spawnen. Mit dem Funktrigger kannst du sie alle auf einmal töten

Nokman
12.08.2015, 11:55
Zwei Fragen hätte ich noch:

Das mit den privates hast du eingefügt, damit die Werte beim erneuten Aufrufen nicht überschrieben werden, oder?

um es einfach zu sagen, Ich habe die Definiert das es die gibt weil er sonst ausserhalb der foreach nicht weis das die einen Wert hat.
Foreach ist ein anderer Raum(bereiche im Script) in der Wohnung(gesamte Script). Ohne das Ich dir jetzt sage(private [""]) das jemand im nebenraum ist weist du es nicht ausser du schaust nach.

Wie Drunken Officer schon als beispiel sagte gibt es neben denn noch 100 weitere möglichkeiten.

du kanst eine globale variable verwenden

MeineSoldaten = [];
{
hier werden die einheiten erstellt und in _list1 geschrieben
}
MeineSoldaten pushback _list1;

Somit würden die soldaten aus _list1 (lokal) in die MeineSoldaten(global) reingeschoben werden ans ende.

Dann kanst du zb da alle löschen lassen mit

{deleteVehicle _x;} forEach forEach MeineSoldaten; // da sind alle weg

Du kanst es auch in bereiche nach erstellung sortieren

Jetzt wird jedes mal wenn du den Script aufrufst ne neuer bereich in der Globalen erstellt.
MeineSoldaten pushback [_list1];
dann heist der löschbefehl
{deleteVehicle _x;} forEach (MeineSoldaten select ZAHL);

Wichtig ist zu denn was ich dir hier sage Schaue dir https://community.bistudio.com/wiki/Category:Scripting_Commands_Arma_3 an darin stehen die ganzen befehle und was die machen wie select foreach etc. einfach suchfunktion des browser (strg +f) verwenden.

private ["_grp1","_list1","_unit","_ki"];
if (isnil "MeineSoldaten") then { //isnil MeinSoldat sobald der einmal ausgeführt wurde überspringt er denn bereich.
MeineSoldaten = [];
kiloeschen = { //ist die Funktion (ist in einer {} )die in Addaction ausgeführt werden soll
private ["_c","_del"];
_del = [];
if (count MeineSoldaten isequalto 0) exitwith {Hint 'Keine Einheiten erstellt'}; //soll aus den Script wieder Springen wenn es keine Ki zum löschen gibt
for "_c" from 1 to (count MeineSoldaten) do { //eine For Schleife
if ([format['Es gibt %1 Ki Gruppen möchtest Du Gruppe %2 Löschen mit %3 KI´s?',count MeineSoldaten,_c,count (MeineSoldaten select (_c -1))],'Ki Löschen','Ja','Nein']call bis_fnc_guimessage) then { // funktion GUI Message
{deleteVehicle _x;} foreach (MeineSoldaten select (_c-1));
_del = _del + [(_c -1)]; //speichert sich lokal die Bereiche welche gelöscht wurden in MeinSoldat
};
};
reverse _del; //Dreht die speicherung um damit wir von hinten her die Meinsoldat aufräumen können
{MeineSoldaten deleteAt _x} foreach _del; //räumt auf
};
player addAction ["Ki Löschen",kiloeschen]; //Fügt hinzu die Addaction
};
// jetzt das wird immer ausgeführt. Es werden Zwischen 0(da er aufrunden soll ceil ist es immer 1) und 20 KI´s Erstelt
_grp1 = createGroup EAST;
_list1 = [];
_ki = [];
for "_i" from 1 to (ceil(random 20)) do {
_ki = _ki + ["O_Soldier_F"]; (Hier baut er die Anzahl der soldaten zusammen)
};
_unit = [getMarkerPos "spawn", EAST, _ki,[],[],[],[],[],random 360] call BIS_fnc_spawnGroup;
_list1 = _list1 + units _unit;
[_unit] join _grp1;

Meinesoldaten = MeineSoldaten + [_list1];// hinzufügen zu MeineSoldaten


Hier ein Script der das machen sollte was du möchtest bassiert auf deinen was du bereits kantest und soll dir helfen damit zurechtzukommen. Ich habe die Soweit wichtigsten befehle darin genutzt die man so braucht.

Es ist nicht der Beste Script.

ps: Arma mit -showScriptErrors starten als paramater

wolkenstuermer
12.08.2015, 15:32
Hmm ... vielen Dank erstmal ihr beiden - jetzt raucht zwar der Kopf, aber ich werde mir das alles mal versuchen zu begreifen. :bahnhof:

Finde ich super, dass es hier so kompetente Hilfe gibt! :danke:

Ich glaube das Schlimme für Skriptanfänger ist gerade, dass es soviele Wege gibt ;) Ich bin gestern z.B. schon daran gescheitert, das Beispiel von Drunken einfach für ein Skript umzusetzen (anstatt als AddAction im Fahnenmast). Schätze, da fehlen noch ordentlich Grundlagen (an denen ich immer wieder verzweifele).

Ich schaue die Befehle auch immer im Wiki nach, nur ist das für Anfänger trotzdem sehr schwer, zu begreifen, wann man was wie mit wem verwendet.

Nochmal danke Jungs.

Nokman
12.08.2015, 15:52
Natürlich kein problem,

Jeder muss mal fragen und jeder hat mal angefangen, slange man sich aber bemüht und nicht einfach ankommt mit der Frage "Hier ich will ne Super geiles Teil haben macht mal schnell" dann hilft man auch.

Vieles kommt auch nur duch Probieren.

Du kanst den Script von mir zb auch einfach in die Konsole eingeben dazu musst du aber alle //TEXT entfernen sonst gibt es einen fehler. Danach ausführen. und wenn du die Scripterrors anhast wirste auch ganz schnell sehen was nicht geht wenn was nicht geht.

Als Idee kanste auch gerne den Script von mir so umbauen das Du nach dem ersten ausführen eine addaction bekommst zum erstellen der KI. Dazu den Befehlsblock wie die kiloesch script bearbeiten.

Das wird schon.

wolkenstuermer
13.08.2015, 12:03
Danke Nokman.

Das mit dem Probieren ist so eine Sache :oh:
Manchmal probiere ich sehr lange rum und bin frustriert, weil gar nix geht. Ist aber vermutlich das Los des Anfängers :haw:

Die schwierigsten Sachen sind am Anfang (zumindest für mich) die Lokalitäten, dass alles dann auch noch im MP läuft, Unterschiede zwischen lokal und global und wann man was nimmt, dann entdeckt man im Wiki auch noch, dass die Befehle teils lokal, teils global anwendbar sind und teils eben auch nicht :ugly:

Aber gut. Dennoch macht es Spaß, zu sehen, wenn was läuft. Kommt am Anfang eben leider nicht allzu oft vor ;)

Drunken Officer
13.08.2015, 13:57
Bei den Befehlen immer links oben in die Ecke schauen!

wolkenstuermer
14.08.2015, 19:00
Brrr ... ich verstehe es leider immer noch nicht.

Ich habe nun ein kleines Schnipsel namens spawn.sqf:

soldierArray = [];
[] spawn {
private ["_grp","_unit"];
_grp = creategroup east;
for "i" from 1 to 1 do {
_unit = _grp createUnit ["O_Soldier_F", getMarkerPos "spawn", [], 0, "FORM"];
soldierArray = soldierArray + [_unit];
};
};

und eines namens delete.sqf

{deleteVehicle _x;} forEach soldierArray;

Das ist doch exakt das, was ihr geschrieben habt, ich teile - wem auch immer - mit, dass es die Variablen gibt, ich erzeuge eine (in meinem Fall einmalige) Einheit, ich sage "schmeisse die Einheit in Gruppe _grp und sag dann dem Array, du bist um _unit reicher. Da das Array global ist, sollte ich es im anderen Skript dann wieder entleeren können.

Jedoch: Es wird die letzte Einheit gelöscht. Alle anderen bleiben stehen, in etwa so ratlos wie ich :zahn:

Wo ist mein Fehler? Oder kann ich Einheiten nur über AddAction so erzeugen und in ein Array schreiben, dass das Array auch befüllt wird (denn es klappt ja, wenn ich exakt das Gleiche schreibe, es nur über ein spawn in ein AddAction einbette und von einem Objekt aus aufrufe ...)

Ist es entscheidend, "wer" das Skript aufruft?

Drunken Officer
16.08.2015, 19:55
Führst du soldierarray = []; jedesmal mit neu aus? Denn das darfst du nicht.
Ich denke genau das machst du aber.

Übersetzt heißet es:
Erstelle leeren Array
Erstelle Gruppe
Erstelle Einheit und schmeiße diese in den Array.
..
Erneute Ausführung
Erstelle bzw. leere den Array !!!
bla
bla bla

Somit hat dein Array nur eine Einheit gespeichert, nämlich die letzte erzeugte Einheit.

Die Vordefinition darf nur einmal ausgeführt werden. Der Rest vom Spawn-Script stimmt, auch wenn eigentilich for "_i" from... richtiger wäre.

wolkenstuermer
17.08.2015, 00:35
Argh. Ich bin ... :stupid:
Danke Drunken. Das war irgendwie logisch. Aber ich hab's trotzdem nicht gesehen.

Also ab damit in die init.sqf und dann (weil global) sollten das auch meine beiden Schnipsel hinkriegen.

Danke!