Sascha Geschrieben 9. Juni 2010 Melden Share Geschrieben 9. Juni 2010 Unity wirkt ja mit großer Anziehungskraft auf Designer, während die Benutzerfreundlichkeit einen Programmierer erst einmal abschreckt, ist diese doch meist mit Einschränkungen oder sonstigen Ärgernissen verbunden. Wer sich gerne Spiele ausdenkt oder designed, muss sich auch in Unity ersteinmal mit Programmierung auseinander setzen, und dafür dieses Tutorial. Bis auf den letzten Teil (3.2) nicht unbedingt für Leute, die schon gut mit JavaScript programmieren können. Dieses Tutorial beschäftigt sich ausschließlich mit Javascript, da es noch einen Satz einfacher ist als c#. Scripten in Unity für Einsteiger Teil 1 - Scripts benutzen / Unity-Grundlagen Wer sich Unity schon einmal angesehen hat, sieht: Unity läuft grundlegend über dieses Prinzip: Ein Spiel besteht aus mehreren Szenen (Scenes) Eine Szene besteht aus mehreren GameObjects Ein GameObject besitzt mehrere Komponenten (Component) Ein GameObject ansich ist nichts weiter als eine Instanz. Es ist kein Licht, hat keine Form, keine Physik und ist in keiner Weise sichtbar. Erst die Komponenten des GameObjects definieren, was es ist. Fügt man z.B. ein Licht hinzu, so ist das kein Licht-GameObject, sondern ein GameObject mit einer Licht-Komponente. Sichtbare Objekte haben eine Komponente, die von der Renderer-Klasse abgeleitet ist (was das genau heißt, muss man erstmal nicht wissen), ohne diese wären sie unsichtbar. Sogar "Transform" ist eine Komponente, die sich nur nicht löschen lässt, und pro GameObject einmalig ist, trotzdem ist es nur eine Komponente. Eine Komponentenart hebt sich stark von den anderen ab: Script (MonoBehaviour). Ein Script ist eine weitere Komponente, die einem GameObject hinzugefügt werden kann. Warum es gut ist, dass man pro GameObject Scripts hat, und nicht ein großes Programm, das alles steuert, wie es sonst üblich ist, sei später erwähnt. Was hier zu merken ist: Scripts lassen sich in der Bibliothek per Rechtsklick=>Create=>JavaScript (oder welche Scriptart auch immer) erstellen.Anschließend benennt man ihn und öffnet ihn per Doppelklick. Man zeiht das Script auf ein GameObject oder in die Komponentenliste des geöffneten GameObjects, um es zuzuweisen. Bei JavaScript und c# muss man auf Groß- und Kleinschreibung achten! Wir wollen jetzt ein Script erstellen, das einen Würfel dreht. Erstelle eine neue Szene. Erstelle einen Würfel und platziere ihn im Weltzentrum (0,0,0). Erstelle jetzt einen neuen Javascript und nenne ihn RotateMe. Weise den Skript dem Würfel zu. >>> Noch passiert nichts, der Skript ist ja noch leer! Teil 2 - Variablen Variablen erfüllen viele Zwecke. Sie haben einen Datentyp und einen Wert. Der Datentyp gibt an, was die Variable beinhaltet; das kann ein Wort sein, eine Zahl, ein Vektor oder sogar ein GameObject. Die Zahl der Datentypen ist unbegrenzt, allein schon, weil man sich selber welche erstellen kann. Die wichtigsten Datentypen sind die so genannten primitiven Datentypen: boolean - Wahreheitswert (true [ja] oder false [nein])int - Ganzzahl [integer] (z.B. -3 | 0 | 110) String - Zeichenkette (z.B. "Hallo Welt" [mit Anführungsstrichen!]) float - Gleitkommazahl (z.B. -4.3 | 12 | 12.5 [mit Punkt statt Komma!]) double - Gleitkommazahl mit doppelter Genauigkeit, braucht man in Unity selten (Kleiner Nachtrag hier: String ist nicht wirklich ein primitiver Datentyp im eigentlichen Sinne, verhält sich aber ungefähr so.) Eine Variable definiert man in Javascript (!) wie folgt: var name; Das Schlüsselwort "var" wird vom Editor gesondert markiert und bedeutet: Im folgenden wird eine Variable definiert. Das Wort "name" ist der Name der Variable und kann beliebig heißen, aber: - nur Buchstaben und Zahlen, Tiefstriche gehen auch ( _ ) - das erste Zeichen muss ein Buchstabe sein - keine Sonderzeichen (auch keine Umlaute) und erst recht keine Leerzeichen - die Konvention liegt bei CamelCase-groß-und-klein-schreibung, d.h.: erster Buchstabe klein und dann Kapitälchen, z.B. nameDerVariable Das Semikolon ( ; ) am Ende beendet die Anweisung, das gilt für alle Anweisungen. RICHTIG: var health;var livesLeft; FALSCH Var health; //var muss kleinvar health //kein Semikolon var 23t; //Variablenname darf nicht mit Zahl anfangen var häckchen; //Keine Umlaute erlaubt öffne das Script RotateMe und lösche den gesamten Inhalt Erstelle eine Variable "rotateSpeed" >>> Das Ergebnis müsste nun so aussehen: var rotateSpeed; Teil 2.1 - Variablen initialisieren Variablen erstellen, schön und gut, sie müssen auch Werte haben. Eine Wertzuweisung funktioniert ganz simpel per Gleichzeichen ( = ): health = 100; Dies ist eine Anweisung. Anweisungen lassen sich nicht einfach so in das Script schreiben, einzige Ausnahme sind Variablen, die erstellt werden (siehe vorheriger Abschnitt). Wie man diese Zuweisung anwendet, sei später erklärt. Eine Wertzuweisung lässt sich mit einer Variablendeklaration kombinieren, das nennt man dann Initialisierung: var health = 100; Hierbei gibt es eine Besonderheit in Javascript. Die meisten Programmiersprachen verlagen danach, dass eine Variable bei der Deklaration einen Typ angegeben bekomen. JavaScript tut dies nicht; weist man z.B. health den Wert 100 bei der Initialisierung zu, wird health bis auf weiteres als int behandelt, was es ja auch ist. Die Initialisierung einer Variable ist also eine Art vorläufiger Festsetzung des Datentyps. Man kann den Datentyp aber auch endgültig angeben... Teil 2.2 - Variablen-Typ angeben ...das funktioniert durch einen Dopelpunkt ( : ). Beispiel: var health : int; Health ist nun eine int-Variable. Die Performance des Scripts steigt, wenn man immer fleißig die Datentypen angibt, weil das Programm dann nicht immer selbst herausfinden muss, was für einen Datentyp eine Variable hat. Insbesondere, weil Variablen ohne angegebenen Typ ihren Typ später wechseln können. Initialisieren wir jetzt unsere Variable, sieht sie so aus: var health : int = 100; ändere jetzt die Variable rotateSpeed so ab, dass sie ein float ist und den Wert 10 hat. >>> Das Ergebnis müsste jetzt so aussehen: var rotateSpeed : float = 10; Teil 2.3 - Variablen im Unity-Editor Jetzt haben wir ein Script an unserem Würfel, der eine Variable hat: rotateSpeed. Diese Variable soll natürlich die Geschwindigkeit angeben, mit der gedreht wird. Eine normale Variable, die einen Datentyp hat (und sei er auch nur durch die Initialisierung angegeben), ist in Unity im Editor einstellbar. Speichere und schließe den Script-Editor. Markiere den Würfel und sieh Dir die Komponentenliste an. Das Script in der Komponentenliste, unser RotateMe-Script, hat jetzt eine Einstellung erhalten: Rotate Speed! Sie hat den Wert 10, weil wir ihn so zugewiesen haben. Den kann man jetzt aber ändern, und diese änderung beeinflusst dann das Verhalten der Script-Komponente, nicht des Scripts selbst! Hätten wir z.B. zwei Würfel mit RotateMe-Script und änderten wir den Rotate Speed-Wert des einen, so hat das keinen Einfluss auf den anderen, genau wie die änderung der Position eines Objekts die anderen nicht beeinflusst. ändert man den Wert einer Variable im Unity Editor, dann gilt der veränderte Wert innerhalb des Scripts für die eine Instanz des Scripts ab Spielbeginn. Man muss also nicht jedes mal das Script ändern, um eine Einstellung zu ändern, und schon gar nicht zwei Scripts schreiben, um zwei Objekte unterschiedlich schnell drehen zu lassen! Teil 3 - Funktionen Eine Funktion ist nun das entscheidenste Konstrukt in einem Script. Sie kann ausgelöst werden und beinhaltet eine beliebige Anzahl von Aweisungen, wie z.B. die Wertzuweisung (siehe oben), oder ruft andere Funktionen auf. Eine Funktion sieht folgendermaßen aus: function Name() { } Für den Namen deiner Funktion gelten die selben Richtlinien wie für Variablen, nur, dass der Konvention nach Funktionsnamen am Anfang groß geschrieben werden. Zwischen den geschweiften Klammern ( { und } , AltGr+7 und AltGr+0 auf der PC-Tastatur) stehen dann die Anweisungen, die ausgeführt werden sollen, sobald die Funktion aufgerufen wird. Beispiel: function LogVier() { print("4"); } Wird die Funktion LogVier aufgerufen, wird eine andere Funktion aufgerufen, die in diesem Fall print() heißt. print() zeigt einen String in der Unity-Konsole an (und unten links im Editor), und zwar den, der in den Klammern steht. Variablen, die in den Klammern stehen, heißen Parameter. Durch Parameter lässt sich das Verhalten von Funktionen beeinflussen. Teil 3.1 - Parameter Parameter müssen in einer Funktion deklariert sein, sonst kann man sie nicht benutzen. Sie werden ähnlich wie normale Variablen deklariert, nur ohne "var", und in der Klammer der Funktion: function PrintPlusOne(zahl : int) { } diese Funktion erwartet nun einen Parameter vom Typ int. Versucht man, diese Funktion mit anderen Paramenetern aufzurufen, gibt es einen Fehler. Parameter sind, genau wie Variablen, die innerhalb einer Funktion deklariert werden, nur innerhalb der Funktion verfügbar. Versucht man, sie von anderswo auszulesen oder zu ändern, gibt es einen Fehler. Zuweisungen und andere Funktionen aufrufen sind nicht alles, was man tun kann, man kann z.B. auch rechnen: function PrintTwoPlus(zahl : int) { print(zahl + 2); } Diese Funktion zeigt in der Konsole das Ergebnis der Addition Zahl + 2 an. So ruft man diese Funktion auf: PrintTwoPlus(5); Dann erhält man "7" in der Konsole. Mehrere Parameter sind genauso möglich wie gar keiner, man trennt mehrere mit einem Komma ( , ). Aber wie ruft man eine Funktion auf, wenn man sie nur aus anderen Funktionen aufrufen kann (die müssen ja auch aufgerufen werden!)? Teil 3.2 - Unity-Funktionen Ganz einfach: Es gibt in Unity ein paar reservierte Funktionen, die nicht der Programmierer aufruft, sondern die Unity Engine selbst. Die wichtigsten: Awake()Wird aufgerufen, wenn das GameObject, dem das Script zugewiesen ist, initialisiert wird (also ganz am Anfang) Start()Wird aufgerufen, wenn das GameObject, dem das Script zugewiesen ist, fertig initialisiert ist Update()Wird immer wieder aufgerufen, solange das Script aktiv ist Füge die Update-Funktion zum Rotate-Script hinzu, denn wir wollen den Würfel kontinuierlich drehen >>> Das Ergebnis müsste jetzt so aussehen: var rotateSpeed : float = 10; function Update() { } Jetzt müssen wir in der Update-Funktion den Würfel drehen. Dazu greifen wir auf eine andere Komponente des selben GameObjects zu, das das Script angeheftet hat. In den meisten Fällen kann man ganz bequem auf die anderen Komponenten zugreifen, zum Beispiel die transform-Komponente: transform Transform hat eine Funktion namens Rotate(xAngle : float, yAngle : float, zAngle : float). Diese nutzen wir in der Update-Funktion, um den Würfel bei jedem Aufruf ein kleines Stück weiter zu drehen, und zwar um die y-Achse: transform.Rotate(0, 1, 0); Aber wir wollen den Würfel ja mit unserer angegeben, variablen Geschwindigkeit drehen! transform.Rotate(0, rotateSpeed, 0); Eines müssen wir aber noch beachten. Jede Art von zeitabhängigen Aktionen muss modifiziert werden. Das liegt daran, dass die Update()-Funktion je nach Leistung des Systems, auf dem die Unity Engine läuft, mal öfter und mal weniger oft aufgerufen wird. Da die Drehung ganz klar zeitabhängig ist (der Würfel dreht sich ja mit x Grad pro Sekunde), multiplizieren wir die Gradzahl mit der Zeit seit dem letzten Update()-Aufruf. Wer ein gewisses Grundverständnis von Mathematik hat, sieht: Wenn wir bei jedem Aufruf um x Grad mal diese Zeit drehen, entsteht eine gleichmäßige Drehung, denn wenn ein Aufruf etwas früher kommt, wird der Würfel entsprechend weniger gedreht und umgekehrt. Dieser Wert seit dem letzten Update()-Aufruf lässt sich jedenfalls so auslesen: Time.deltaTime also muss unsere Funktion jetzt so aussehen: function Update() { transform.Rotate(0, rotateSpeed * Time.deltaTime, 0); } (Das * ist ein Mal-Zeichen). Passe die Update-Funktion des Scripts wie beschrieben an. >>> Zeit zum Testen! Der Würfel müsste sich drehen! Dreht er sich zu langsam? Einfach Rotate Speed im Unity Editor ändern! Teil 4 - Rückgabewerte Eine Funktion kann irgendwas für eine andere Funktion machen. Das ist zum Beispiel dann dann sinnvoll, wenn man etwas bestimmtes an mehreren Stellen machen will. Man schreibt dann für diese Aufgabe eine Funktion, die dann immer aufgerufen wird, anstatt ihren Code überall in anderen Scripts zu verteilen. In den meisten Fällen einer solchen Auslagerung benutzt man die Funktion, um einen Wert zu ermitteln. Diesen Wert kann die Funktion dann an die Funktion, die sie aufgerufen hat, zurück geben. Dies geschieht mit dem return-Statement: function QuadratZahl(zahl : int) { return zahl * zahl; } Der Rückgabewert wird dann verwendet, indem man die Funktion bei ihrem Aufruf wie einen Wert behandelt: var ergebnis : int = QuadratZahl(8); print("Das Quadrat von 8 ist "+ergebnis); Die Funktion, die QuadratZahl() aufruft, wartet mit dem Ausführen, bis sie den Rückgabewert hat. Teil 5 - Abschließende Worte Jetzt kannst du scripten. Auch wenn du - verhältnismäßig - nicht sehr viel gemacht hast: Wenn Du dir alles genau durchgelesen hast, hast du nicht nur die Grundlagen gelernt, sondern auch einiges mehr, das dir beim Verstehen komplizierterer Dinge helfen wird. Als nächstes könntest du dich in die offizielle Scripting-Referenz einlesen: http://unity3d.com/s...criptReference/ Der Anfang dürfte dir bekannt vorkommen, aber das ist hoffentlich auch der Grund, warum du alles schneller verstehst, was nun kommt. Viel Erfolg beim Scripten! Das nächste Tutorial wartet schon! 20 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Gast Pro-Gamer Geschrieben 9. Juni 2010 Melden Share Geschrieben 9. Juni 2010 Gute gelungenes Tutorial! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Lars Geschrieben 9. Juni 2010 Melden Share Geschrieben 9. Juni 2010 Gute gelungenes Tutorial! Kann ich nur unterschreiben. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 10. Juni 2010 Autor Melden Share Geschrieben 10. Juni 2010 Ich danke. Mal sehen, ob ich demnächst nochmal die Zeit für ein anderes finde. 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Carsten Geschrieben 10. Juni 2010 Melden Share Geschrieben 10. Juni 2010 Feines Tutorial! Genau das richtige für Einsteiger Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
regisseur4 Geschrieben 13. Juni 2010 Melden Share Geschrieben 13. Juni 2010 da schließ ich mich den anderen doch glatt an, Daumen hoch! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Lars Geschrieben 13. Juni 2010 Melden Share Geschrieben 13. Juni 2010 Meine Tutorials bekommen nicht so viel Lob Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
DoubleM Geschrieben 13. Juni 2010 Melden Share Geschrieben 13. Juni 2010 (bearbeitet) Meine Tutorials bekommen nicht so viel Lob Meine auch nicht *Schmoll* Ne, Scherz beiseite, ist doch wirklich ein gutes Tutorial. (Damit sage ich nicht dass deine nicht auch gut sind Lars) bearbeitet 13. Juni 2010 von DoubleM Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
regisseur4 Geschrieben 14. Juni 2010 Melden Share Geschrieben 14. Juni 2010 Damit unser Admin Lars auch sein verdientes Lob bekommt : Ich finde dein Spieleentwicklungs-Tutorial auch große Klasse und freue mich schon auf die Weiterführung. Gruß reg4 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Thomas Eilmsteiner Geschrieben 12. Juli 2010 Melden Share Geschrieben 12. Juli 2010 Echt Spitze! Sehr gut erklärt und hilfreich. Wunderbar gelungen! Gruß, Tom. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Gast Koenigshopser Geschrieben 12. August 2010 Melden Share Geschrieben 12. August 2010 Respekt, ein wunderbar einsteigerfreundliches und übersichtlich gestaltetes Tutorial. Ich war immer ziemlich verwirrt wenn es um die Variablen in den Funktionsklammern ging (besonders wenn ich mal was in der Scripting-Referenz nachschauen wollte) aber dank "Teil 3.1 - Parameter" hat sich das erledigt. Der Grund warum man den Variablen-Typ angibt obwohl dieser selbst erkannt wird, ist mir nun auch klar geworden. Vielen dank ! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 11. Februar 2011 Autor Melden Share Geschrieben 11. Februar 2011 Habe soeben noch einmal den Absatz "Rückgabewerte" eingefügt. Das zweite Tutorial verweist auf dessen Inhalt, irgendwie fehlte er hier aber noch. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
shock2provide Geschrieben 5. Januar 2012 Melden Share Geschrieben 5. Januar 2012 Sehr verständlich und gut. Danke Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
totesherz Geschrieben 28. März 2012 Melden Share Geschrieben 28. März 2012 Sehr gutes Tutorial danke das du dir die Mühe gibst Neueinsteiger zu helfen in Unity, trotzdem hab ich ein Problem in Punkt 3.2 da ich am Ende leider keine Drehung hinkriege bei mein Würfel der sagt mir dann das ich die Errors beseitigen soll leider finde ich den Fehler nicht da der Compiler mir nicht anzeigt wo ich meine fehler habe von Code her hab ich nur diese Zeilen. Time.deltaTime function Update() { transform.Rotate(0, rotateSpeed * deltatime, 0); } Kann mir jemand bitte sagen was ich vergessen habe oder wo man am Compiler erkennt was ich falsch geschrieben habe wie es auch in Eclipse der Fall ist? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 28. März 2012 Autor Melden Share Geschrieben 28. März 2012 Die Fehlermeldungen stehen im Unity Editor immer unten rechts in rot, bzw. in der Konsole (Strg+Shift+C). Das Problem bei deinem Script ist, dass du Time.deltaTime nicht einfach oben einfügen musst, sondern in den Code an der Stelle, wo bei dir einfach nur deltatime steht. Deswegen steht im Tutorial auch: also muss unsere Funktion jetzt so aussehen: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
totesherz Geschrieben 28. März 2012 Melden Share Geschrieben 28. März 2012 Oh ja das war nicht clever von mir, nur hab ich trotzdem Fehlermeldung wenn ich den drehen will obwohl der mir in Unityscript keine Fehler anzeigt oder muss mehr jetzt drin stehn als function Update() { transform.Rotate(0, rotateSpeed * deltatime, 0); } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 28. März 2012 Autor Melden Share Geschrieben 28. März 2012 Der Ausdruck heißt ja auch nicht deltatime, sondern [siehe Tutorial] Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
totesherz Geschrieben 28. März 2012 Melden Share Geschrieben 28. März 2012 yeah ich habs hinbekommen vielen dank für die hilfe. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Graphiler Geschrieben 20. Mai 2012 Melden Share Geschrieben 20. Mai 2012 Es wäre gut, wenn du hier noch reinschreibst wie man das serialisieren von Variablen im Unity-Editor verhindert... Statische Variablen sind böse, hab ich selbst erst von ein paar Wochen bemerkt Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
kSpiker Geschrieben 22. Mai 2012 Melden Share Geschrieben 22. Mai 2012 WOW. Sehr nettes Tutorial Hat mir echt geholfen ! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
theappcompany1 Geschrieben 2. Juni 2013 Melden Share Geschrieben 2. Juni 2013 ich verstehe nicht wie man die print funktion aufruft Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
HortusLongus Geschrieben 3. Juni 2013 Melden Share Geschrieben 3. Juni 2013 Du kannst auch Debug.Log benutzen. Ist im Grunde genommen nix anderes wie print (Quelle). Ein bißchen schon, steht ja auch in deinem Link; print() ist auf MonoBehaviour beschränkt. Außerdem ruft print() lediglich Debug.Log() auf, kostet also eigentlich doppelt gemoppelt Zeit. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
malzbie Geschrieben 3. Juni 2013 Melden Share Geschrieben 3. Juni 2013 Print schreibt sich aber schneller! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 3. Juni 2013 Autor Melden Share Geschrieben 3. Juni 2013 Performance ist in der Tat irrelevant, da man print ja nur im Editor benutzt, in dem Performance keine Rolle spielt Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
HortusLongus Geschrieben 3. Juni 2013 Melden Share Geschrieben 3. Juni 2013 Print schreibt sich aber schneller! Vor allem, wenn du das später in einem Nicht-MonoBehaviour benutzen willst und nach drei Stunden feststellst: "Aha.". :) Aber ernsthaft: tippst du die dauernd benutzten Begriffe denn jedesmal von Hand ein? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.