PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Speed


JSR
04.11.2013, 19:49
Hey! :)

Probiere grade mich in das scripting von Arma reinzufuchsen, weil es einiges leichter macht.
Jetzt probiere ich grade ein bestimmten Sound abzuspielen, wenn der Spieler in einem bestimmten Fahrzeug eine gewisse Geschwindigkeit erreicht hat.
Auf der BIS WIKI habe ich diesen Eintrag dazu gefunden:

http://community.bistudio.com/wiki/speed

Jedoch weiß ich nicht, was dass mit dem Fragezeichen aufsich hat.

"? (speed _truck1) >= 100 : hint (http://community.bistudio.com/wiki/hint) "You're going too fast!""

Frage mich sowieso, wieso die ein Fragezeichen in einem Beispiel setzen. Ist ja gar nicht verwirrend für Anfänger! :)


Wozu das Fragezeichen ist weiß ich jedenfalls nicht. Habe den Script jetzt mal in eine Testmission integriert und die Aussage "You're going to fast" kommt andauernd. Egal wie schnell ich bin.

Da ich den Script Command von einer offiziellen BIS WIKI Seite habe, frage ich mich wa sich als Anfänger falsch mache.

Habe auch schon ein wenig rumprobiert. Also das > verändert usw..

Buliwyf
04.11.2013, 20:38
? bedeutet if
: bedeutet then

:ugly:

JanIs
04.11.2013, 20:39
Das ist offensichtlich noch ein "altes" sqs Script.
Das "?" stand für das "wenn", ist also das Gleiche wie das "if" in einem sqf Script.

Sieh mal hier ... (http://community.bistudio.com/wiki/SQS_to_SQF_conversion)

JSR
04.11.2013, 20:43
Erstmal danke für die schnellen Antworten und danke für den Link! :daumen:

Okay verstehe! Also muss die Config so aussehen?

_vehicle=vehicle (_this select 0);

if (speed _vehicle) >= 100 then {hint "You're going too fast!"};


PS: Funktionieren tut es mit dieser Eingabe in die Script.sqf nämlich nicht.

Mir gehen die TrynError Versuche langsam aus, weil mir nichts mehr einfällt.

JanIs
04.11.2013, 20:54
Völlig korrekt ...

Du kannst aber auch die Abfrage etwa in einem Auslöser direkt durch Eingabe des Fahrzeugnahmes abfragen.
Also wenn dein Fahrzeug den Namen Truck1 hat dann einfach:

als Bedingung: (speed Truck1) >= 100
bei Akt: hint "You're going too fast!"

oder in einem Script, etwa einer Film-Zwischensequenz, Intro, Outro oder was auch immer:
if (speed Truck1) >= 100 then {hint "You're going too fast!"};

JSR
04.11.2013, 21:01
Mh, wieso funktioniert es nicht?

Vielleicht weil _Vehicle=Vehicle (ich probiere es im Little Bird aus) nicht präzise genug definiert ist für den Script?
Muss ich noch woanders irgendwas zuweisen?

PS: @JanIs,

Ich will es eigentlich weiter über SQF machen, weil ich später wenn ich mehr Erfahrung habe, den Script über eine Config aktivieren will.

JanIs
04.11.2013, 21:08
Erstmals siehe meine Antwort über deiner Frage.

Zweitens kommt es drauf an wie du das Script aufrufst.
Wenn du es aufrufst, dein Littlebird aber langsamer ist, dann kann sich ja auch nichts tun, da die Bedingung (schneller oder gleich 100 km/h) zu fliegen noch nicht zutrifft.
So gesehen müsstest du es entweder in eine Auslöser packen oder die Bedingung oder Abfrage im Script in einer Schleife laufen lassen damit die hint-Meldung ausgegeben kann, wenn dann tatsächlich die Geschwindigkeit erreicht oder überschritten wurde.

Ich hoffe das war verständlich genug.

Greetz
Jan

JSR
04.11.2013, 21:12
Ja aber ich erreiche ja die Geschwindigkeit über 100. Habe sie jetzt auf 50 verändert. Habe halt eine Testmission mit einem LittleBird erstellt.

Dein Post habe ich übrigens gesehen aber ich möchte das lieber doch gerne in einer SQF machen, weil ich dadrauf später angewiesen bin. Möchte nämlich über die Configs Scripte aktivieren. Wie in einem Addon. :)

Und "If (speed _vehicle) >100 then {hint "Test"}; ist doch die Script Schleife, die du meinst, oder?

JanIs
04.11.2013, 21:22
Pass mal auf:

1. Erstelle das Script mit folgendem Inhalt:
_vehicle = vehicle (_this select 0);
while {speed _vehicle < 50} do {
sleep 1;
};
hint "You're going too fast!";

Dieses rufst du per Eingabe in die Initzeile des Littlebirds folgendermaßen auf:
gogo=[this] execVM "name_deines_scriptes.sqf"

Jetzt prüft er in einer Schleife von einer Sekunde ob die Geschwindigkeit von 50 km/h erreicht ist. Wenn ja springt das Script aus der Schleife und gibt die Hint-Meldung aus.

Alternativ ginge auch statt der Sekundenschleife ein
waitUntil {speed _vehicle > 50};

Dabei wird eigentlich statt der Abfrage alle Sekunden in einem Millisekundenabstand geprüft ob die Bedingung erfüllt ist.
In beiden Fällen pausiert das Script bis die Geschwindigkeit überschritten wurde ...


So wie in deiner Zeile KANN es nicht funktionieren, da in dem Moment, indem das Script die Abfrage erstellt, die Geschwindigkeit ja nicht erreicht sein kann und dementsprechend die Meldung wegen der nicht zutreffenden Abfrage nicht ausgegeben wird.
Außer du rufst das Script erst auf wenn du über 100 fliegst. Dazu benötigst du aber wiederum einen Auslöser ;-)

JSR
04.11.2013, 21:30
Okay cool, der erste Test hat funktioniert. War über 50 und dann hats funktioniert! Werde jetzt erstmal ein wenig rumprobieren damit, danke für die Bereitschaft zu helfen! Super. :daumen: :cool:

Muss mich da erstmal richtig reinfuchsen und die Logik und die Befehle verstehen. Das dauert natürlich ein wenig.

Was bedeutet denn eig. "(_this select 0)"?

JanIs
04.11.2013, 21:38
Ich hoffe ich verzapfe jetzt keinen Schmarrn, aber _this select 0 steht für das erste Argument, welches das Script ausführt.
Im vorliegenden Fall das [this] oder [Littlebird].
Begonnen wird nicht mit 1 sondern immer mit 0. Beeinhaltet das Script ein weiteres Argument, beispielsweise die Geschwindigkeit, wäre das dann _this select 1

_vehicle = vehicle (_this select 0);
_maxtempo = _this select 1;

while {speed _vehicle < _maxtempo} do {
sleep 1;
};
hint "You're going too fast!";

aufgerufen dann als gogo = [this,100] execVM "dein_script.sqf";


Das Ganze macht aber nur Sinn, wenn das Script für mehrere Fahrzeuge verwendet wird. Bei einmaliger Verwendung in einer Filmsequenz oder dergleichen genügt eigentlich wie oben schon angeführt die direkte Ansprache per
while {speed littlebird1 < 100} do {
sleep 1;
};
hint "You're going too fast!";


Ich denke aber, du hast jetzt das Prinzip der while-Schleife verstanden und auch, warum dein Script die Hint-Meldung nicht ausgegeben hatte.

JSR
04.11.2013, 21:42
Okay, also eine Art Inhaltsverzeichnes für Variabeln?


Ja, so zum Teil schon. Mir ist zwar klar was du meinst aber das If und Then Prinzip ist seitdem etwas unverständlich für mich.
Für mich hieß es

Falls _vehicle eine Geschwindigkeit über 50 KmH erreicht, so hint "Text";

Aber While und Do sind also allgemein für Schleifen verantwortlich, oder?

JanIs
04.11.2013, 21:51
Ja genau.

Du musst dir einfach folgende Situation vorstellen:

1. Du rufst dein Script am Beginn der Mission oder mittels Auslöser auf
2. Dein Script fragt nach ob eine Bedingung zutrifft
3. Wenn ja --> Hint, wenn nein passiert logischerweise gar nichts.

Da du keine Schlaufe hattest, die Geschwindigkeit beim Start des Scripts jedoch niedriger war, konnte auch keine Meldung kommen.
Aus dem Grunde die Schlaufe damit das Script so lange läuft und warten kann, bis das Argument eintritt.

Praktisch wie ein Auslöser der die Hint-Meldung ja auch erst ausgeben wird, wenn die Geschwindigkeit tatsächlich erreicht wurde. Die Prüfung der Bedingung im Auslöser läuft ja auch ständig im Hintergrund ...

JSR
04.11.2013, 21:55
Okay ich verstehe! :)
Nochmal Danke für deine Mühe.

Mein Ziel ist eigentlich über einen Script einen bestimmten Sound im Cockpit des LBs abzuspielen, sobald eine bestimmte Geschwindigkeit in einer gewissen Höhe erreicht ist. Bin seit über einem Jahr beschäftigt eine Sound Mod herzustellen und alleine und ohne Scripterfahrung ist das ganz schön mühsam, wenn man sich so manche Ziele gesetzt hat.
Deswegen finde ich es immer gut wenn mir hier geholfen wird.

JanIs
04.11.2013, 21:58
Na Bumm, da hast du dir ja was vorgenommen ...
Gleich einen Mod zu basteln finde ich schon als recht hochgestecktes Ziel.

Wünsche dir viel Glück und gutes Gelingen.
Viel Zeit und Geduld hast du ja offensichtlich, nachdem du schon so lange daran herumwerkelst. :daumen:

Greetz
Jan

JSR
04.11.2013, 22:01
Ja und leider nie was rausgebracht.
Hab bestimmte Ziele und bin aufgrund der fehlenden Kenntnisse manchmal demotiviert oder weiß einfach nicht weiter.
Habe halt manchmal die Nase voll gehabt und dann aber doch immer wieder angefangen. Deswegen ist es mir manchmal schon peinlich hier nach Hilfe zu fragen. :zahn:

PS: Danke! :)

JeeperCreeper
04.11.2013, 23:21
Erstmal danke für die schnellen Antworten und danke für den Link! :daumen:

Okay verstehe! Also muss die Config so aussehen?
_vehicle=vehicle (_this select 0);

if (speed _vehicle) >= 100 then {hint "You're going too fast!"};


PS: Funktionieren tut es mit dieser Eingabe in die Script.sqf nämlich nicht.

Mir gehen die TrynError Versuche langsam aus, weil mir nichts mehr einfällt.

Hallo erstmal, da ich auch erst ungefähr vor einem Monat angefangen habe mit dem Scripten, würde ich Dir gerne einen Tipp geben der das Scripten um einiges leichter macht, falls Du ihn nicht schon kennst.
Wenn du deine Arma.exe mit dem angehängten Parameter "-showScriptErrors" startest, dann werden Dir sofort alle deine Scriptfehler die du im Script hast mit Angabe der Line angezeigt. Somit weisst du sofort wo der Fehler steckt und manchmal steht dort sogar was falsch ist.

Nun zu der if-Bedingung (http://community.bistudio.com/wiki/if). Eine if-Bedingung erwartet zwingend ein Boolean (http://community.bistudio.com/wiki/Boolean) Wert in den runden Klammern. Das heißt, entweder ein "true" oder ein "false".
Du hast jetzt hingeschrieben, wenn (geschwindigkeit _auto) >= 100 dann.....
Wie gesagt braucht die if-Bedingung einen Wahrheitswert in den Klammern. Und bei (geschwindigkeit _auto) kann ja kein Wahrheitswert rauskommen. Also müsstest du auch noch die Zahl mit rein nehmen in die Klammer und richtig wäre dann.
Wenn (geschwindigkeit _auto >= 100) dann....
So kriegst du ja ein "true" oder "false" raus.

Am besten du guckst mal hier (http://hx3.de/editing-scripting-167/sqf-handbuch-22579/) rein. Da steht alles super genau beschrieben. Damit hab ich schon jede Menge gelernt, obwohl ich nix mit Programmieren am Hut hatte vorher. Da wird auch erklärt wie man sich auf der Wiki-Seite (http://community.bistudio.com/wiki/Category:Scripting_Commands_Arma_3) zurecht findet, wo die ganzen Befehle erklärt sind.
Ja dann mal Viel Erfolg noch:daumen:

JSR
04.11.2013, 23:28
Danke für die Tipps und sehr vielen Dank für das Tutorial! :) Werde ein wenig rumprobieren und dann wieder Feedback hier geben! Thx! :daumen:

JSR
05.11.2013, 21:11
Okay, soweit so gut! :)

Wenn ich das ganze wiederholen will... Sprich, der Spieler erreicht im LB die Geschwindigkeit 50, der Ton wird abgespielt, er geht mit der Geschwindigkeit runter auf 40 und dann wieder auf 50 und der Ton wird wieder abgespielt, muss ich dann die _i commands verwenden?

Mit while und do klappt zwar alles, der script bleibt aber einmalig. Bei nochmaligen überschreiten des Tempos passiert nichts mehr.

JeeperCreeper
05.11.2013, 23:41
Ich weiss jetzt nicht wie du das mit dem Ton machst, aber hier mal ein Beispiel wie es ohne geht, gerade getestet klappt wunderbar mehrmals.

In die Init des Vehicles kommt das rein:
temp = [this] execVM "tempo.sqf";

Das Script heißt "tempo.sqf" und da rein kommt folgendes:
if (!isServer) exitWith {};

private ["_veh"];

_veh = _this select 0;

while {true} do
{
if (speed _veh >= 50) then {hint "Du fährst zu schnell!"; sleep 5; hint ""}
};

Sobalt man jetzt mit dem Vehicle über 50 km/h kommt, kriegst du die Meldung für 5 Sek. eingeblendet. Über sleep kannst du die Meldung natürlich auch länger einblenden lassen.
Wenn du jetzt wieder unter die 50km kommst und nochmal drüber, kriegst du die Meldung wieder angezeigt.

JSR
05.11.2013, 23:47
Super, danke für die Hilfe!

Übrigens, statt Hint "Text" füge ich Playsound "Name der Sounddatei" ein und fertig. :)

Kannst du mir vllt. erklären, wo bzw. wie genau du die "unendliche" Wiederholung gescriptet hast? :angel:

PS: While {true} - also während "aktiv" oder "wahr" ist also ein großer Unterschied zu "While {speed _vehicle <50};" ?

JeeperCreeper
05.11.2013, 23:58
Ah cool, jetzt hab ich auch wieder nen neuen Befehl gelernt thx:naughty:

Die wiederholung erzeugst du mit der while-Schleife. Alles an Code was du in der Scheife reinschreibst, wiederholt sich halt. Hmm... wie soll man das erklären, ist eigentlich selbsterklärend:confused:

Ein Beispiel mal mit nem anderen Code:

if (!isServer) exitWith {};

private ["_auto"];

_auto = _this select 0;

while {true} do
{
player moveInCargo _auto
};
Hiermit ist es jetzt dem Spieler nicht mehr möglich aus dem Auto auszusteigen. Weil er halt immer wieder durch das Script reingesetzt wird.
Wenn du da jetzt noch z.B. nen sleep Befehl reinsetzt von ein paar Sek. dann hast du die Zeit kurz auszusteigen und wirst nachdem sleep wieder reingesetzt.
if (!isServer) exitWith {};

private ["_auto"];

_auto = _this select 0;

while {true} do
{
player moveInCargo _auto; sleep 20
};

Damit hast du 20 Sek. Zeit irgendwas zu machen bis du wieder reingesetzt wirst.:stupid:

Also immer wenn die Bedingung (While {condition}) true ist, dann wird die Schleife fortgesetzt. Sobalt false kommt dann nicht mehr. Man kann halt anstatt dem "true" irgendeine Bedingung reinschreiben und solange die "true" wiedergibt, läuft die Schleife.
Und {speed _vehicle <50} gibt ja nur "true" zurück, wenn man unter 50 ist. Sobalt man einmal über 50 kommt, wird die Schleife verlassen. Eine einfache Schleife erzeugst du halt immer, wenn du "true" reinschreibst und nach dem "do" dein Code der wiederholt werden soll. Weil dann ist ja immer "true".

JSR
06.11.2013, 00:10
Okay. Also greife ich mit While {true} auf den unten Block, der mit einer IF und THEN bestückt ist zu und gebe mit "true" an, dass er immer wenn der Wert im IF und THEN Block zutrifft auch genau das erfüllt. So habe ich es jetzt verstanden. :shy:

JeeperCreeper
06.11.2013, 00:20
Nein nicht ganz hehe, ich sag ja ich kann nix erklären. Der untere Block hat mit dem {true} nix am hut. Der untere Block (egal welcher muss nicht if then else sein) wird halt nur dann immer wieder ausgeführt, solange die Bedingung nach dem While, also in den {Klammern} true wiedergibt. Wenn du da jetzt selber einfach nur {true} reinschreibst, dann ist die Bedingung halt schon true und somit läuft die Schleife ewig, weil ja nicht mehr {false} kommen kann.
Würde man jetzt als Beispiel in die While Bedingung folgendes reinschreiben:
While {1>2} do {irgendwas}
Dann würde irgendwas nie passieren, weil 1 nie größer werden kann wie 2. Ich hoffe jetzt war es klar genug :zahn:

JSR
06.11.2013, 00:34
Nein nicht ganz hehe, ich sag ja ich kann nix erklären. Der untere Block hat mit dem {true} nix am hut. Der untere Block (egal welcher muss nicht if then else sein) wird halt nur dann immer wieder ausgeführt, solange die Bedingung nach dem While, also in den {Klammern} true wiedergibt. Wenn du da jetzt selber einfach nur {true} reinschreibst, dann ist die Bedingung halt schon true und somit läuft die Schleife ewig, weil ja nicht mehr {false} kommen kann.
Würde man jetzt als Beispiel in die While Bedingung folgendes reinschreiben:
While {1>2} do {irgendwas}Dann würde irgendwas nie passieren, weil 1 nie größer werden kann wie 2. Ich hoffe jetzt war es klar genug :zahn:

Ich glaub das liegt mehr an mir als an dir. :ugly:

Stelle mich bei sowas irgendwie immer sehr blöd an, brauche dafür immer ein wenig. :zahn:

Was ich halt nicht so ganz verstanden habe ist, warum der vorherige Eintrag, den wir gestern behandelt haben sich dann nicht auch wiederholt.
Weil
"
While {speed _vehicle > 50} Do {playsound "Sound"};

Bedeutet ja, dass während man im _vehicle die Geschwindigkeit 50Kmh überschritten hat, der sound "Sound" abgespielt wird.

Und das andere mit While {true} do und dann der IF Block aus deinem Tempo script sagt ja im Endeffekt das gleiche aus, nur das {speed _vehicle > 50} halt nicht bei While sondern im unteren Block stehen.

Deswegen habe ich es jetzt so verstanden wie ich es schon beschrieben habe, was aber wahrscheinlich falsch ist, wie du es grad sagst. Deswegen werde ich mir jetzt noch 200 mal deinen Beitrag durchlesen, bis ich es verstanden habe. :zahn::ugly:

Mache für heute jetzt erstmal eine Pause und fang morgen wieder frisch an. Bin heute zu kaputt um noch weiter dadran zu lernen. Werde so nichts kapieren. :shy:

Aber wie gesagt, liegt definitiv NICHT an dir! ;) Du erklärst das ganz gut! :)

JeeperCreeper
06.11.2013, 09:04
Du denkst da schon in die richtige Richtung. Das mit der Bedingung hast du jetzt verstanden. Aber bei
While {speed _vehicle > 50} Do {playsound "Sound"};
wird der Sound deshalb nicht abgespielt, weil du ja nicht über 50km/h startest. Und sobalt du ja unter 50km/h kommst, in dem Fall bist du ja schon am Anfang unter 50, dann wird die Schleife ja verlassen.

JanIs
06.11.2013, 11:01
While {true} bedeutet ja nichts anderes als "Solange es wahr ist".
Und da es sozusagen ohne Bedingung immer "wahr", also "true" ist läuft das Ganze während der ganzen Mission über ...

"true" findest du beispielsweise ja auch standardmäßig als Wegpunktbedingung. Solange statt "true" nicht eine Bedingung rein kommt, laufen diese auch einfach durch.

Wie JeeperCreeper schon erklärt hatte läuft bei "while {true} ..." das Script sozusagen ewig in der Schleife, weil die alleinige Bedingung "true" immer zutrifft. Es wird die Schleife nie verlassen. Aus dem Grunde kommt die Meldung mehrmals, auch wenn zwischendurch die Geschwindigkeit unterschritten wurde.
Es handelt sich in dem Script ja auch praktisch um zwei Bedingungen. Die 2. mit der Geschwindigkeit gibt die Meldung aus und wird aufgrund der ersten Bedingung, die immer zutrifft immer wieder gestartet.
Es ist sozusagen eine doppelt verschachtelte Bedingung, die nie beendet werden kann weil das "while {true} ..." immer zutrifft.

Bei der gestrigen Version läuft die Schleife so lange, bis die Geschwindigkeit höher ist. Dann kommt die Hint-Meldung. Danach ist für das Script sozusagen die Arbeit getan und es wird beendet weil die Bedingung ja erfüllt worden ist.

Vielleicht ist dir der Knopf ja jetzt aufgegangen ...

Greetz
Jan

JSR
06.11.2013, 19:03
Okay, ich habs nun endlich verstanden.
Danke für die Geduld ihr beiden! :daumen:

Ich habe gestern (oder vorgestern?) angefangen das Tutorial zu lesen, bin aber noch nicht an der Stelle gewesen, wo beschrieben wird, wo der Unterschied mit "Null []" und "Gogo []" ist oder was zum Beispiel Private bedeutet oder
was es mit "if (!isServer) exitWith {};" aufsich hat.

Drunken Officer
07.11.2013, 19:07
Ist die bedingungen in einer schleife nicht gegeben, wird diese übergangen
Arbeite mit Waituntil
Warnung = [this, 60] execvm "....sqf"

Private ["_rd", "_ge"];
_rd = _this select 0;
While {alive _rd} do
{
_rd = _this select 0;
_ge = _this select 1;
Waituntil {speed _rd > _ge};
Hint "you are to fast";
Sleep 3;
};


Gogo oder was auch immer ist eine variable, welche als Wert die ausführung des scriptes beinhaltet

JSR
07.11.2013, 19:26
Danke! Soweit komme ich aber mit der Version von Jeeper gut zurecht! ;)
Sie erfüllt soweit Sinn und Zweck.


Zur Zeit habe ich ein anderes Problem. Sobald ich das Script über die Config starte, was soweit funktioniert, kommt eine Fehlermeldung, sobald ich über die angegebene Geschwindigkeit komme.

"Radio Message "TSound" not found".

In der config.cpp bzw. .bin ist der Sound per

class CfgRadio {

class TSound {
name = "";
sound[] = {"Ah6\T_Low", 1, 1};
title = "";
};
};
angegeben. Ist halt nur der Ausschnitt CfgRadio aus der cpp.

Wie genau gebe ich den Pfad in der .cpp denn sonst durch? Habe es schon mit CfgSounds probiert, klappt aber soweit auch nicht.

Oder muss ich das mit den Veerbungen der classen beachten?
Falls ja, ich habe keine CfgRadio gefunden... was ja auch eigentlich dafür spricht, dass das anders funktioniert. Habe als Abguckbeispiel eine andere Config genommen, wo diese Sounds per CfgRadio definiert wurden... jedoch aus Arma 2.

In der Testmission, wo alles ohne config abgerufen wurde, habe ich den VehicleRadioSound Pfad in der description.ext mit CfgRadio angegeben und es hat funktioniert.


EDIT:

Fehler gefunden!

Für alle die, die das vllt interessiert:
Ich habe CfgRadio unter dem CfgVehicle Block definiert. Denke mal ein typischer Anfängerfehler. :P

CfgVehicle muss natürlich per }; geschlossen werden und dann kommt CfgRadio dran. ;) Funktioniert jetzt alles erstmal super. Danke für die Hilfe, die mir die Basis für meine Ideen gegeben hat!