Jump to content
Unity Insider Forum
Sascha

Scripten in Unity für Einsteiger

Recommended Posts

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 klein

var 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!

  • Like 20

Share this post


Link to post
Share on other sites

Meine Tutorials bekommen nicht so viel Lob :(

 

Meine auch nicht wink.gif

*Schmoll* rolleyes.gif

 

Ne, Scherz beiseite, ist doch wirklich ein gutes Tutorial.

(Damit sage ich nicht dass deine nicht auch gut sind Lars)

Edited by DoubleM

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Guest Koenigshopser

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 ! ;)

Share this post


Link to post
Share on other sites

Habe soeben noch einmal den Absatz "Rückgabewerte" eingefügt.

Das zweite Tutorial verweist auf dessen Inhalt, irgendwie fehlte er hier aber noch.

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

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:

;)

Share this post


Link to post
Share on other sites

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);

}

Share this post


Link to post
Share on other sites

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 ^_^

Share this post


Link to post
Share on other sites

Steht doch im Eingangspost:

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.

 

print selber ist nicht nur auf function beschränkt sondern kann so gut wie überall verwendet werden. Angenommen, du hast einen Button erstellt und willst testen ob der funktioniert. Schreibst halt zwischen den Button-Code ein print("Der Button funktioniert"); rein. Klickst du jetzt auf ihn, sollte "Der Button funktioniert" in der Konsole auftauchen. Du kannst auch Debug.Log benutzen. Ist im Grunde genommen nix anderes wie print (Quelle).

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Performance ist in der Tat irrelevant, da man print ja nur im Editor benutzt, in dem Performance keine Rolle spielt :)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...