Beiträge von Cryptogene

    Heute ist der letzte Tag, an dem das "Monster Creature Pack 1 - Semi Realistic" kostenlos im Maker Shop zur Verfügung steht. :gift_heart:

    Das Angebot wurde im 24. Türchen des Adventskalenders erwähnt.

    Wie hat euch der Kalender gefallen? Wie fandet ihr das Format? Wir freuen uns über euer Feedback im Forum!

    Euch allen noch einen besinnlich, ruhigen 2. Feiertag. :christmas_tree: :gift:


    https://rpgmaker-mv.de/jcoins-shop/


    An dieser Stelle ein herzliches Dank an PandaMaru !
    Du hast wie jedes Jahr dir wahnsinnig viel Mühe gegeben, damit der Kalender einzigartig aussieht und die Community jeden Tag eine tolle, kleine Überraschung vorfinden konnte.
    Danke für dein Engagement sowie deiner Mühe und Herzblut, welches du in dieses Forum steckst! :)

    Hallo Community,


    wie bereits im gestrigen Türchen unseres Adventskalenders zu sehen, beherbergt unser Maker Coins Shop ein neues Produkt.

    Es handelt sich hierbei um ein mittelalterliches GUI (grafische Benutzeroberfläche).

    Diese ist mit Vektorgrafiken für jede Auflösung skalierbar, jedoch für Desktop-Anwendungen gedacht / gemacht.

    Das Pack beinhaltet ebenso 4 verschiedene 'gerenderte' Größen, sodass ihr diese als .png Dateien in eurem Projekt sofort benutzen könnt.


    Das Produkt ist hier (über den Maker Coins Shop) zu finden.


    Anbei noch ein paar Beispiel-Bilder (mehr Bilder sowie eine genauere Beschreibung ist in der Produktbeschreibung im Shop vorzufinden)









    Fragen, Log, Kritik oder Anregungen zu diesem Produkt können gerne hier in diesem Thread gestellt werden.



    An dieser Stelle möchte ich auch nochmals auf unseren Adventskalender verweisen.
    Seid gespannt, was sich weiterhin hinter den Türchen befindet.

    Wir freuen uns über eure Kommentare und wünschen euch auch weiterhin eine besinnliche Weihnachtszeit! :|

    Die Vorstellung und der Traum davon ein eigenes Spiel zu realisieren nach meinen Vorstellungen.

    Eine eigene Geschichte, die Wendepunkte im Spiel, etc...


    Ich liebte es Rätsel zu erstellen, zugegeben waren diese meist zu kompliziert, was ich erst lernen musste.

    Aber es hatte wahnsinnig viel Freude bereitet und es betraf immer nur einen kleinen Freundeskreis.


    Vieles davon hat sich bis heute nicht wirklich geändert. Lediglich der zeitlich limitierende Faktor.

    Willkommen bei "[Neuling] Roll a Ball Extended Version - Lektion 8 - Exportieren des Spiels + weitere Ideen" 8)

    Diese Lektion setzt Lektion 7 dieser Reihe voraus und baut entsprechend darauf auf.


    Dies ist die letzte Lektion dieser Reihe.

    Hier werdet ihr erfahren, wie ihr euer Spiel exportieren könnt und weitere Ideen für das Projekt vorfinden.


    Bevor wir das Menü zum Exportieren öffnen, speichert euer gesamtes Projekt und Szenen ab.

    Öffnet das das Menü über "File => Build Settings ... "

    Es öffnet sich ein neues Fenster. Das Unity Logo zeigt in der Liste der "Plattformen" die ausgewählte Plattform, auf die wir exportieren wollen.

    Via "Switch Plattform" kann eine andere ausgewählt werden - dies wollen wir hier jedoch nicht.

    Windows, Linux oder Mac ist soweit ganz gut. In meinem Fall ist es Windows (64 Bit), da Unity sich gemerkt hat, das ich damit entwickle.

    Zieht nun alle Szenen in das "Scenes in Build" Fenster im oberen Bereich. In unserem Fall sollte das nur eine sein, sofern ihr nicht mehr hinzugefügt habt. Es kann auch sein, dass diese schon dort inbegriffen ist.


    Klickt nun auf den "Build" Button unten rechts.

    Es öffnet sich nun ein Art Explorer Fenster. Legt nun einen neuen Ordner "Builds" im selben Level an, wie "Assets" und "Library".

    Navigiert nun in den "Builds" Ordner, den ihr soeben erstellt habt.

    Erstellt einen neuen Ordner mit dem Namen "Version_1.00" und navigiert ebenso in diesen bzw. wählt diesen für Unity aus.

    Sobald ihr dies bestätigt habt, wird Unity automatisch alle notwendigen Schritte für euch erledigen und das Spiel für das jeweilige Betriebssystem 'verpacken'.


    Unter dem von euch gewählten Pfad findet ihr nun das Spiel.

    In meinem Fall eine "Roll a Ball Extended Version.exe" Datei.

    Startet die Datei und erfreut euch an eurem 1. Unity Spiel! :)

    (Wenn ihr es ohne Fenstermodus startet, müsst ihr mit z.B. "ALT + F4" das Spiel wieder beenden.)



    Herzlichen Glückwunsch!

    Du hast diese Reihe erfolgreich beendet.


    Nun ein paar Schlussbemerkungen:

    • Die Zwischenräume, die nun noch frei sind, könnt ihr selber gestalten.
    • Nutzt Rampen oder Elevator Objekte um in die jeweilige nächste Mauer / Bereich vorzudringen.
    • Denkt daran: Wenn ihr mehr Münzen habt, müsst ihr beim "Player" Objekt die Anzahl der Münzen in der Skript Komponente erhöhen.


    Weitere Ideen:

    • Eine Timer Funktion, nach Ablauf der Zeit hat man verloren
    • Rampen oder Plattformen, die sich rotieren, bzw. ggf auch Mauern
    • Blöcke die man nicht berühren darf, sonst hat man verloren / Spieler wird deaktiviert => verloren.
    • ...


    Ihr seht, selbst ein solches Spiel kann man noch gut ausbauen.

    Nutzt die Gelegenheit und baut euch eigene Levels mit den verbleibenden Freiraum.


    Zeigt in diesem Thread sehr gerne eure Meisterwerke! Bereichert andere mit euren Ideen!

    Hat euch die Reihe gefallen?

    Lasst mir doch etwas Feedback hier, da es sehr aufwändig war, diese zu erstellen.


    Ich bin gespannt auf eure Rückmeldungen!

    Anbei noch 2 Dateien - einmal die Unity Projekt Datei im Stadium der letzten Lektion, solltet ihr nicht mitgekommen sein und dann das fertige Spiel zum Spielen.


    Viel Spaß damit!


    Spielbare Version zum Testen:

    Roll a Ball Extended Version - v1.00 - Win64.zip


    Source-Code des Projektes:

    Roll a Ball Extended Version - SourceCode.zip

    Willkommen bei "[Neuling] Roll a Ball Extended Version - Lektion 7 - Anzeigen der Score sowie Texte" 8)

    Diese Lektion setzt Lektion 6 dieser Reihe voraus und baut entsprechend darauf auf.



    Wir haben nun einen beweglichen Spieler, Münzen sowie Hindernisse.

    Aber uns fehlt noch eine Score sowie ein Win-Text.


    Dies wollen wir nun ändern und entsprechend integrieren.

    Es bieten sich nun verschiedene Möglichkeiten an, wie wir die Score implementieren können.

    Einmal von 0 nach oben zählend und als zweite Möglichkeit von Oben (also von der Anzahl der Münzen bei Spielstart) nach unten (zu 0) zählend.

    Ich entscheide mich hierbei für die zweite Möglichkeit. Sprich: Wenn die Münzen alle eingesammelt wurden und der Counter auf 0 geht, ist das Spiel gewonnen.

    Die Anzahl der Münzen könnt ihr somit später noch erhöhen und das Spiel endet dennoch bei dem Wert 0, wenn alle Münzen eingesammelt wurden.

    (Und der Spieler weiß somit automatisch, wie viele ihm noch zum Beenden des Spiels fehlen.)


    Öffnet nun das Skript "ControllerPlayer".

    Wir wissen: Münzen sind gerader Anzahl, also keine halben oder dreiviertel Münzen. Daher benötigen wir eine neue Variable vom Typ "int" (integer).

    Fügt nun diese Zeile "public int coinCounter;" bei der Zeile "public float speed;" unterhalb ein.

    Die Reihenfolge hat hier nichts miteinander zu tun, es ist lediglich aufgeräumter.


    Wir haben es "public" gewählt, damit wir später bei Unity die Anzahl der Münzen eingeben können.

    Ergänzt nun im Skript folgenden Ausschnitt:


    Csharp
    1. void OnTriggerEnter(Collider other)
    2. {
    3. if (other.gameObject.CompareTag("Coin"))
    4. {
    5. other.gameObject.SetActive(false);
    6. coinCounter = coinCounter - 1;
    7. }
    8. ...


    Neu ist:

    Csharp
    1. coinCounter = coinCounter - 1;


    Wir ziehen also eine Münze ab, wenn wir eine eingesammelt haben.

    Die selbe Zeile ließe sich auch mit dieser ersetzen:

    Csharp
    1. coinCounter--;


    Dies hat sie selbe Bedeutung wie die obere - zum Verständnis von Neulingen sollte es hierbei jedoch bei der oberen erstmal bleiben. An alle, die mit C# oder Programmiersprachen vertraut sind, dürfen natürlich auch die zweite Version hier nehmen.


    Das komplette Skript sollte nun etwa so aussehen:


    Speichert das Skript ab und kehrt zu Unity zurück.

    Klickt per Rechtsklick in das Hierarchy Fenster und wählt "UI => Text".

    Es sollte nun ein "Canvas" mit einem "Text" und einem "EventSystem" Objekt erschienen sein.

    Wichtig: Lasst diese Objekte stets so zusammen. Ein UI (User Interface - also Benutzeroberflächen) Element benötigt immer ein Canvas Objekt, von dem es ein Kind Objekt ist, so wie es Unity hier schon für uns vorgegeben hat.

    Andernfalls würde der Text (Objekt) nicht richtig funktionieren.


    Man kann sich das Canvas auch als Bereich vorstellen, in dem der Text an Gültig erhält.

    Gibt es kein Canvas, ist der Text als solches Objekt nicht gültig.


    Benennt nun den soeben erstellten Text in "txtCoinCounter" um.

    Wählt außerdem in der "Text (Script)" Komponente des txtCoinCounter Objektes die Farbe "Color" an (Klick auf das dunkle Farbfeld).

    Wählt nun einen helleren Hex-Wert wie "FFFFFF".

    Damit ihr das Objekt sehen könnt, drückt "F" im Scene Fenster, sodass es zum Text hinzoomt.

    Scrollt etwas raus, sodass ihr das gesamte Canvas sehen könnt. Wie ihr seht, befindet sich das Canvas nicht im Spiel direkt. Es wird aber später wie über dem Bildschirm gelegt aussehen, also keine Sorge.


    Ersetzt nun von unserem txtCoinCounter Objekt im Text Feld "New Text" mit "Coin Counter".

    Diese Information ist nur für uns, das wir wissen, worüber es sich handelt.


    Geht nun in die oberste Komponente "Rec Transform" und wählt das Bild aus, welches wie ein Schießkreuz aussieht.

    (Dieses Bild ist für die Positionierung und die Verankerung des Text Elementes im Canvas verantwortlich.)

    Beim Klick auf dieses Symbol öffnet sich ein Art Untermenü mit mehreren, ähnlich aussehenden Bildchen.

    Haltet nun "SHIFT" und "ALT" gleichzeitig und wählt dann das Symbol oben links.


    Gebt nun die Transform - Positions Werte ein: "Pos X = 20" und "Pos Y = -20".

    Zuletzt noch die "Font Size" auf "20" erhöhen. Diese befindet sich unter der "Text (Script)" Komponente.


    Wenn ihr alles richtig gemacht habt, sollte es so aussehen:


    Als nächstes wollen wir uns um die Programmlogik kümmern, die mit dem Text Objekt in Verbindung steht.

    Öffnet das "ControllerPlayer" Skript.


    Wir benötigen nun einen zusätzlichen Namensraum (namespace), um die UI Elemente in C# mittels Skript zur Verfügung zu haben.

    Ein Namensraum ist z.B. der schon vorhandene "using UnityEngine;" in einen der ersten Zeilen im Skript.


    Wir fügen darunter nun einen weiteren nämlich "using UnityEngine.UI;"

    Nun haben wir auch Zugriff auf die UI Elemente von Unity.


    Erstellt eine neue Variable "public Text txtCountText;" unter den anderen "public ..." Variablen.

    Speichert nun das Skript ab und kehrt zu Unity zurück. (Weiter unten in dieser Lektion ist notfalls auch wieder der gesamte Code zu finden, sollte es nicht klar gewesen sein.)

    Wählt nun den Player an und betrachtet die Skript Komponente. Wir haben 2 Felder, die wir noch nicht bearbeitet haben.

    Einmal das Feld "Coin Counter" mit dem Wert "0" und einmal das "Txt Count Text" Feld.

    In dem ersteren Feld gebt den Wert 20 ein.

    In zweiteres zieht ihr von der Hierarchy das Objekt "txtCoinCounter" in das Feld.

    Es sollte nun wie auf dem Bild aussehen:

    Wir haben nun das txtCoinCounter Text-Objekt mit unserer im Skript befindlichen Text Variable verknüpft. bzw. diese Variable mit dem Text Objekt 'befüllt'.


    Der Wert von "Coin Counter = 20 " sagt aus, dass der Spieler 20 Münzen einsammeln muss.

    Solltet ihr später mehr hinzufügen, müsst ihr diesen Wert entsprechen erhöhen, daher bitte merken!


    Kehrt nun wieder zum Skript zurück - wir sind noch nicht fertig mit dem "ControllerPlayer.cs" Skript.

    Erweitert nun "void Start()" um die folgende Zeile:

    Csharp
    1. void Start()
    2. {
    3. rb = GetComponent<Rigidbody>();
    4. txtCountText.text = "Verbleibende Münzen: " + coinCounter.ToString();
    5. }

    Wir greifen mit der neuen Zeile nun auf das Text Objekt zu und wollen die darin befindliche "text"-Komponente Beeinflussen. Es soll darin stehen "Verbleibende Münzen: 20" bzw. der aktuelle Stand, der in dieser Variable gespeichert ist.

    (Nach jedem einsammeln soll der Wert ja kleiner werden.)


    Da es hier jedoch nur einmal in Start gesetzt wurde, dies auch nur einmal lädt, müssen wir die Zeile auch noch andernorts setzen.

    Also muss diese Zeile auch nochmal in den Code von OnTriggerEnter().

    Dann hätten wir jedoch 2 mal den Selben Code an 2 verschiedenen Zeilen.

    Das ist eher schlecht und möchte man nicht. Daher erstellen wir uns eine neue Funktion, die diesen Code durch Funktionsaufruf ausgibt.

    => So müssten wir nur an einer Stelle den Code ändern, statt an 2 verschiedenen.


    Löscht daher die soeben getippte Zeile in der "void Start()" Methode und ergänzt / vergleicht euren Code mit dem Folgenden, sodass es übereinstimmt:


    Neu ist die selbst definierte Funktion "SetCountText()" sowie ihre 2 maligen Aufrufe in OnTriggerEnter() sowie Start().

    Speichert nun das Skript ab und kehrt zu Unity zurück.

    Zeit für einen Test - Startet den Play-Mode.


    Doch halt ... Was ist das?

    Unser Count - Text ist abgeschnitten...

    Dies hat den Grund darin, dass die Breite ("Width") wie im Bild hervorgehoben von unserem "txtCoinCounter" - Text Objekt nur eine Breite von 160 aufweist. Unser Text scheint jedoch länger zu sein. Wir wollen den Wert daher von 160 auf 400 ändern.


    Aber! Achtung.

    Nicht im Play-Mode - wir erinnern uns, alle Änderungen, die wir hier machen, gehen nach beenden dieses Modus verloren.

    Es ist jedoch gut zum Testen, ob 400 ausreichen. Nach einen kurzen Test: Ja, es reicht.


    Beendet den Play-Mode und ändert den Wert von 160 auf 400.

    Speichert euer Projekt und geht erneut in den Play-Mode.


    Nun sollte der Counter nach einsammeln von 3-4 Münzen jedesmal um eins herunter gehen. Probiert es nur für ein paar Münzen.

    Wir wollen nun noch eine "Win" bzw. "Gewonnen" Nachricht ausgeben, wenn alle Münzen eingesammelt wurden.


    Dupliziert nun im Hierarchy Fenster das "txtCoinCounter" Objekt.

    Benennt es in "txtWinText" um.

    Setzt von diesem Objekt mittels der "Rect Transform" Komponente die Verankerung in die Mitte (Klick auf das Bild, SHIFT und ALT drücken und die Mitte auswählen).

    Erhöht den Text etwas mit "Pos Y = 75", ebenso erhöht die Höhe "Height = 50".

    Jetzt wollen wir den Text noch zentrieren und etwas größer machen. Geht hierzu in die "Text (Script)" Komponente und tragt bei "Text" den Text "Win Text" ein. Bei "Font Size" den Wert "40" und bei "Alignment" jeweils das in der Mitte befindliche Symbol.


    Es sollte nun so aussehen:


    Als nächstes müssen wir noch sicherstellen, dass der Text nur dann angezeigt wird, wenn das Spiel gewonnen wird.

    Wechselt daher wieder in das "ControllerPlayer" Skript.


    Wir benötigen nun wieder eine public Text Variable.

    Erstellt daher eine neue Zeile unter der anderen Text Variable:

    Csharp
    1. public Text txtWinText;


    Fügt außerdem in der "void Start()" Funktion am Ende der Zeilen die folgende Zeile hinzu:

    Csharp
    1. txtWinText.text = "";

    Damit gehen wir sicher, dass am Anfang des Spiels der 'Gewonnen' Text leer ist, also nichts anzeigt. (Es soll ja nur am Schluss nach dem Einsammeln aller Münzen eine entsprechende Meldung erfolgen.)


    Geht nun runter zu diesem Abschnitt:

    Csharp
    1. void OnTriggerEnter(Collider other)
    2. {
    3. if (other.gameObject.CompareTag("Coin"))
    4. {
    5. ...

    setzt nun in der ersten "if-Abfrage" eine entsprechende Bedingung ein, ob wir mit dem Zählen bei 0 angekommen sind. Und wenn, dann soll der Text "Gewonnen" erscheinen. :

    Csharp
    1. if (coinCounter == 0)
    2. {
    3. txtWinText.text = "Gewonnen!";
    4. }


    Der ganze Skript-Code sollte nun so aussehen:


    Anmerkung: Solltet ihr einen längeren Text wie "Gewonnen" ausgeben wollen, achtet darauf, dass im Unity Editor das Objekt "txtWinText" in "Width" ausreichend an Länge verfügt. Also der Platz z.B. 800 statt 400 ist.

    Für "Gewonnen" reicht uns jedoch 400 gut aus.


    Speichert nun das Skript ab und kehrt zum Editor zurück. Wählt den "Player" an und betrachtet die Skript Komponente.

    Das Feld "Txt Win Text" ist noch leer. Und wie ihr euch sicherlich schon denken könnt, ja hier muss das Objekt "txtWinText" aus der Hierarchy rein gezogen werden, damit es entsprechend verknüpft ist.


    Speichert alles ab und testet euer Spiel im Play-Mode.

    Habt ihr alle Münzen eingesammelt, sollte diese Meldung erscheinen:


    Nun fehlt uns nur noch ein letzter Schritt.

    Der Export unseres Spiels und die Weitergabe an andere!




    Weiter geht es in "[Neuling] Roll a Ball Extended Version - Lektion 8 - Exportieren des Spiels + weitere Ideen"

    Willkommen bei "[Neuling] Roll a Ball Extended Version - Lektion 6 - Münzen für den Spieler" 8)

    Diese Lektion setzt Lektion 5 dieser Reihe voraus und baut entsprechend darauf auf.


    Als nächstes wollen wir uns um die Münzen in unserem Spiel kümmern, welcher der Spieler einsammeln muss um das Spiel erfolgreich zu beenden.


    Navigiert in den FBX Ordner und zieht das Objekt "Coin" auf das Spielfeld und ändert die Position der Münze folgendermaßen: "x = 0, y = 0.7, z = 0" die Rotation sollte jeweils auf 0 sein - die Scale (Größen-Werte) sollten bei ca -70, -70 und -13 (mit jeweiligen Nachkommastellen liegen.)

    Gebt dem Coin Objekt eine "Mesh Collider" Komponente.


    Wechselt in den Material Ordner, erstellt ein neues Material mit den farblichen Hex-Wert"987930" und zieht es auf das Coin Objekt in der Szene.

    Wechselt nun zum Prefabs Ordner und zieht dieses Objekt (Coin) vom Hierarchy Fenster in den Prefabs Ordner.


    Erstellt Anschließend in der Hierarchy ein leeres Empty (Rechtsklick => Create Empty) und benennt es "Coins".

    Stellt sicher, dass der Ursprung auf 0 ist und wenn nicht, resettet es. Zieht nun die Münze (Coin) der Szene in das "Coins" Objekt um ein Kind-Element / Kind-Objekt zu erhalten.



    Dupliziert nun das "Coin" Objekt (die Münze) in der Hierarchy, sodass ihr insgesamt 20 Stk als Kind-Objekte habt. Ich übergebe im Folgenden die Positionen der 20 Münzen.

    Die Größe sowie die Rotation bleiben wie im Bild gezeigt die gleichen Werte.

    Es ändert sich nur jeweils im Transform Komponent die "Position".

    Jede Zeile steht für eine Münze - Die Spalten geben die Koordinaten an:


    Position "x" - Wert Position "y" - Wert Position "z" - Wert
    14.87 0.7 4.16
    15.12 3.12 -1.89
    14.32 1.92 9.54
    15.75 1.78 13.19
    14.49 0.7 -14.4
    2.35 0.7 -16.51
    -7.27 0.7 -15.81
    -6.74 0.7 5.57
    5.83 0.7 -5.91
    5.06 0.7 15.9
    -5.49 0.7 12.05
    -12.21 0.7 18.4
    -18.04 0.7 9.24
    -12.53 0.7 0
    -17.7 0.7 -9.84
    -12.02 0.7 -17.83
    -18.95 1.75 -17.31
    -7.91 3.87 13.8
    -14.11 3.87 7.67
    -13.07 3.87 12.79


    Euer Spielfeld sollte nun in etwa so aussehen:

    (Die Benennung dieser Münzen spielen hier keine Rolle)


    Ihr könnt nun das Spiel speichern und im Play-Mode testen.

    Doch... die Münzen sind bisher nur statische Objekte. Beendet den Play-Mode - wir wollen dies nun ändern.


    Die Münzen sollen sammelbar sein und sich zudem drehen.

    Wechselt wieder in den Prefabs Ordner und wählt dort das Objekt "Coin" aus.

    Fügt ihm ein Skript mit dem Namen "Rotator" hinzu.

    Schiebt das Skript wieder in den Scripts Ordner.


    Zum Check könnt ihr nun auch eure Münzen auf dem Spielfeld anklicken (ohne diese zu bewegen).

    Jedes der Münzen hat nun ein Skript, da das Original im Prefabs Ordner ein Skript erhalten hat.


    Wechselt nun zum Ordner mit dem Skript und öffnet dieses.

    Löscht die komplette "void Start()" Methode und fügt diese Zeile in die "void Update()" Methode ein:

    "transform.Rotate(new Vector3(5, 45, 0) * Time.deltaTime);"


    Euer Rotator Skript sollte nun so aussehen:

    Csharp
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class Rotator : MonoBehaviour {
    5. // Update is called once per frame
    6. void Update () {
    7. transform.Rotate(new Vector3(5, 45, 0) * Time.deltaTime);
    8. }
    9. }


    mit "transform.Rotate()" greifen wir auf die Rotation des Objektes zu, welches dieses Skript bekommt. Also in diesem Fall die Münze.

    wir geben dem ganzen einen Vector3, da es sich um ein 3D Objekt handelt, welches sich entsprechend im 3D Raum drehen (rotieren) soll. Die Werte sind x=5, y=45 und z=0 entsprechend.

    Da Update einmal pro Frame aufgerufen wird, wir jedoch die Objekte "Frame-unabhängig" rotieren sehen wollen, multiplizieren wir das ganze noch mit "Time.deltaTime".

    Mehr zu Time.deltaTime hier.


    Speichert das Skript ab und kehrt zum Editor zurück.

    Testet ruhig das Spiel erneut - alle platzierten Münzen sollten sich nun drehen.

    Wenn nicht, haben sie nicht das Skript und sind ebenso nicht synchron zu eurem Prefab.


    Nun kümmern wir uns darum, dass die Münzen einsammelbar werden.

    Hierzu ist ein bisschen Theorie und Hintergrundwissen notwendig.

    Wir wissen bereits, dass die sogenannten "Collider" dafür verantwortlich sind, dass unser 'Player' an diesen abprallt bzw. die Objekte 'bemerkt' und nicht durch diese hindurch rollt.

    Genau diese Collider können (ähnlich wie beim Maker) auf als "Trigger" bei Kontakt mit diesen funktionieren.

    Heißt: Unser Player berührt einen Münzen Collider und da dieser ein "Trigger" ist bzw. diese Eigenschaft von uns bekommt, prüft unser "Player" via Skript, ob es sich um eine Münze handelt und wenn ja, soll diese verschwinden (deaktiviert werden). Wir sammeln sie ja so gesehen ein.


    Hierzu navigieren wir in Unity zu unserem Prefabs Ordner und wählen das Coin Objekt an.

    Schaut euch die "Mesh Collider" Komponente genauer an. Unter der Checkbox "Convex" gibt es auch eine Chekbox "Is Trigger".

    Diese Checkbox benötigen wir - um diese zu aktivieren, wählt "Convex [x]" an und danach "Is Trigger [x]".

    Nun sollte jede Münze auf dem Spielfeld diese Eigenschaften übernommen haben.


    Doch woher weiß nun der Player, dass es sich um eine Münze handelt?

    => Das Geheimnis lautet "Tag's". Wir fügen unserem Prefab "Coin" einen 'Tag' also eine Kennung ähnlich wie #RpgMaker hinzu, damit wir dieses als Münze verifizieren können. (Später im Skript.)


    Um ein 'Tag' zu erstellen, wählt das "Coin" Prefab aus und schaut unter dem Namen oben beim Inspector nach.

    Hier ist eine Bezeichnung "Tag" mit dem Wert "Untagged" (Standardmäßig).

    Wählt nun "Untagged", wodurch sich ein Drop-Down öffnet. Wählt nun "Add Tag ...".

    Klickt auf das kleine Plus um einen neuen Tag hinzuzufügen. Nennt diesen "Coin" und klickt auf "Save".

    Wählt nun erneut euer Prefab Objekt "Coin" aus und klickt erneut auf das Tag Feld mit dem Wert "Untagged".

    Ihr solltet nun euren Tag "Coin" in der Liste vorfinden. => Merke: So werden Tags erstellt, die in Skripts verwendet werden können.

    Wählt nun den Coin Tag aus, so das es so aussieht, wie auf dem Bild:


    Nun sollten ebenso alle Münzen einen "Coin" Tag haben.

    Wählt nun im Scripts Ordner das ControllerPlayer.cs Skript aus und öffnet dieses.


    Wir wissen ja, dass es mit dem Collider und dem Trigger zusammenhängt.

    Suchen wir in der Unity Scripting API finden wir folgendes dazu.

    Wir wollen das Beispiel (ganz unten) übernehmen und schreiben in unser Skript unterhalb der "void FixedUpdate() { ... } " Methode:

    Csharp
    1. void OnTriggerEnter(Collider other)
    2. {
    3. Destroy(other.gameObject);
    4. }


    Nun wüssten wir, wie man das Objekt zerstören könnte. Aber das wollten wir eigentlich nicht. Sinnvoller wäre es dieses zu deaktivieren.

    Daher löschen wir wieder die Zeile:

    Csharp
    1. Destroy(other.gameObject);


    Wir brauchen also eine "If-Abfrage" um den Fall zu überprüfen, "wenn" das Objekt den "Tag = 'Coin' " besitzt, soll es deaktiviert werden.

    Dies kann nun in Unity gesucht werden oder man schaut sich im Editor den Aufbau eines "GameObjects" an. Also eines jeden Objektes in Unity.

    Jedes Objekt kann Komponente haben. Wir greifen nun in unserem Skript über die Funktion "void OnTriggerEnter(Collider other)" mit einer Variable "other" vom Typ "Collider" auf alles weitere zu.

    Wir benötigen aber das gameObject. (Und wir müssen den Tag vergleichen (compare - im Englischen).


    Die Zeilen, die uns noch in unserem Code fehlen sind demnach folgende:

    Csharp
    1. if (other.gameObject.CompareTag("Coin"))
    2. {
    3. other.gameObject.SetActive(false);
    4. }

    Wir vergleichen hier, ob der Tag des berührten Objektes dem Tag "Coin" entspricht und wenn ja, soll er den Status auf "false" also "deaktiviert" setzen.

    Sprich: unsere Münzen sollen deaktiviert werden.


    Dies kann man durch kennen der Methoden die Unity einen bietet herausfinden, durch googeln oder durch die Sctipting API von Unity bzw. Erfahrung mit C#.

    Daher: Auch wenn ggf. meine C# Tutorials noch nicht so weit sind, würden diese hierbei beim Verständnis sicherlich sehr helfen. (Zumindest was Funktionen, if-Abfragen und allgemein die Programmlogik betrifft.)


    Das gesamte Skript sollte nun wie folgt aussehen:


    Speichert es ab und kehrt zu Unity zurück.

    Nun könnt ihr das Spiel testen und die Münzen sollten bei Berührung verschwinden. Zumindest jene, an die man heran kommt.

    Wir haben 3 Münzen, die oberhalb unserer Reichweite liegen.

    Um diese wollen wir uns nun auch noch kümmern.


    Wechselt in den Prefabs Ordner und wählt das Objekt "Elevator" an.

    Markiert die Checkbox "Is Trigger" im "Box Collider" Komponent.

    Da es sich hierbei um ein "Primitiv" Objekt handelt, muss es nicht Convex sein, da ohnehin.

    Erstellt nun wieder einen neuen Tag Namens "Elevator" und übergebt diesen Tag den "Elevator" Objekt. (Analog zu dem Coin Objekt)


    Wechselt nun zu unserem Skript "ControllerPlayer" und öffnet dieses.

    Wir wollen nun den "Elevator" wirklich zum "Aufzug" machen, bzw. einen ähnlichen Effekt beim Berühren geben.

    Wir haben wieder einen Tag vergeben und einen Collider, der als Trigger funktioniert. Demnach brauchen wir eigentlich nur eine weitere Abfrage, die prüft, ob der Tag / das Objekt beim Berühren ein "Elevator" / Aufzug ist.

    Wenn ja, soll er uns nach oben befördern / drücken. Wenn nein, soll nichts passieren, bzw. bei einer Münze (Coin) soll diese deaktiviert werden.


    Wir gehen daher in die Zeile von "void OnTriggerEvent(Collider other)" unterhalb der "if-Abfrage" der 'Coin'.

    Wir fügen folgenden Code ein:

    Csharp
    1. else if (other.gameObject.CompareTag("Elevator"))
    2. {
    3. rb.velocity = new Vector3(0, 0, 0);
    4. rb.AddForce(0.0f, 8, 0.0f, ForceMode.Impulse);
    5. }


    Wir sagen hiermit also: "Wenn es keine Münze ist - 'Ist es ein Objekt mit dem Tag "Elevator" ' ? " Wenn ja:

    Unser Player (der Rigidbody) soll seine Bewegung komplett einstellen (rb.velocity = new Vector3(0, 0, 0);

    Und im Anschluss soll er (wie schon mal realisiert) eine Kraft erhalten. Aber diesmal nach Oben. Diese Kraft /Bewegung soll außerdem "Impulsiv" also plötzlich sein, wie eine Rakete.

    Das war es auch schon.


    Vergesst generell nicht für euch selber Kommentare mit " // .... " in eurem Code zu hinterlegen, sodass ihr entsprechend diesen später wieder versteht.

    (Eine Beschreibung könnt ihr ja anhand meiner Erklärung übernehmen.)


    Euer Skript sollte nun vollständig so aussehen:


    Speichert euer Skript ab und testet nun erneut das Spiel.

    Ihr solltet nun alle Münzen, die bisher erstellt wurden einsammeln können.

    (Die 3 Münzen auf der Plattform, bzw jene, die von der Plattform zu erreichen sind, können über den "Elevator" am Boden erreicht werden, wenn ihr mit dem Player auf diesen rollt).

    Sollte dies nicht funktionieren, prüft, ob dieser wie das Prefab den "Elevator" Tag besitzt und im Collider der "Trigger auf 'Is Trigger [x]' " gesetzt ist.




    Weiter geht es in "[Neuling] Roll a Ball Extended Version - Lektion 7 - Anzeigen der Score sowie Texte"

    Willkommen bei "[Neuling] Roll a Ball Extended Version - Lektion 5 - Gestaltung des Spielfeldes" 8)

    Diese Lektion setzt Lektion 4 dieser Reihe voraus und baut entsprechend darauf auf.


    Wir werden nun das Spielfeld gestalten. Diese Lektion könnt ihr entsprechend entweder selber gestalten oder ihr folgt weiterhin dem Inhalt.

    Falls ihr gänzlich Neu mit Unity arbeitet wird empfohlen sich weiterhin strikt an die Anweisungen zu halten.

    Ab Lektion 6 solltet ihr euch in jedem Fall wieder an das Vorgehen halten.


    Erstellt im Hierarchy Fenster per "Rechtsklick" => "Create Empty" ein leeres Spielobjekt. Empty's können so gesehen als Ordner missbraucht werden und sind teils sogar dafür gedacht.

    Stellt sicher, dass das soeben erstellte Objekt wie alle anderen kein Kind-Objekt ist. (Also keinen anderem untergeordnet ist.)

    Benennt es nun in "WallsLv5" um.


    Erstellt nun 1x ein 3D Cube Objekt. Benennt es in "WallNorth" um und zieht es im Hierarchy Fenster auf das "WallsLv5" Objekt, sodass es ein Kind-Objekt wird.

    Nun dupliziert die "WallNorth" 3 weitere Male (für jede Himmelsrichtung). Dies kann per "Rechtsklick => duplicate" oder mit "STRG + C" und "STRG + V" bewerkstelligt werden.

    Benennt die Duplikate nun folgendermaßen um in "WallEast", "WallSouth" und "WallWest".

    Markiert nun das "WallsLv5" Objekt sowie alle 4 Kind-Objekte (die 4 Wall... Objekte) und resettet ihre Position (über das Zahnrad), sodass alles im Ursprung sich befindet.


    Ändert nun die Transformation der 4 Elemente wie im Bild gezeigt:


    Ihr solltet nun einen Rahmen erhalten, der sich als Grenze um euer Spiel-Board zieht.


    Dupliziert nun 4 weitere Male das "WallsLv5" Ojekt, sodass sich insgesamt 5 derartige Gruppen in eurer Scene befinden.

    Die Duplikate benennt ihr in "WallsLv4", "WallsLv3", "WallsLv2" und "WallsLv1" um.

    Ändert nun die Transformation der Emptys (WallLv...) Objekte folgendermaßen:


    Ihr solltet nun lauter kleinere Rahmen im Spielfeld sehen.


    Erstellt nun ein neues Empty und benennt es "ObjectsLv1" - resettet zudem auch die Position, damit es im Ursprung sich befindet.

    Navigiert nun zum "FBX" Ordner im Project Fenster und wählt aus diesen das Objekt "Ramp4" aus und zieht es auf das "ObjectsLv1" Objekt im Hierarchy Fenster.

    Ändert nun die Koordinaten dieser Ramp4 zu "x= -19, y = 1, z = -19".

    Navigiert nun zu dem Ordner "Materials" und fügt ein neues Material in den Ordner hinzu.

    Benennt dieses "Environment" und ändert wie in einer vorherigen Lektion gezeigt die Farbe entsprechend mit dem Hex-Wert: "781E28"

    Wechselt nun wieder zum "Ramp4" Objekt, welches in der Szene zu sehen ist und zieht dieses soeben (rötliche) Material auf diese Rampe.


    Navigiert nun in den Prefabs Ordner im Project Fenster.

    Zieht nun die im Hierarchy befindliche "Ramp4" in den Prefabs Ordner. Setzt die Werte der Ramp4 im Prefabs befindlichen Ordner der Transformation nun auf "x = 0, y = 0, z = 0".

    Euer Editor sollte nun entsprechend ca. so aussehen:


    Der Vorteil eines "Prefabs" Objektes liegt darin, dass alle Instanzen, also alle Objekte, die von diesem Objekt in die Szene 'gezogen' wurden, miteinander mit dem Original 'Prefab' zusammen hängen.

    Sprich: Würden wir die Farbe dieser Rampe im Prefab Ordner ändern und davor weitere Objekte in die Szene ziehen, so werden diese automatisch auch ihre Farbe ändern.

    Wenn ein Objekt zudem ein Prefab ist, wird es in der Hierarchy mit einer blauen Schrift dargestellt (siehe Bild).


    Klicken wir nun im Scene Fenster auf die Rampe, sehen wir folgendes:



    Mittels "Select" gelangen wir zum Original (Prefab).

    Sollten wir auf dem Original Prefab etwas ändern, z.B. eine neue Komponent hinzufügen, können wir mit "Revert" das im Scene befindliche Objekt mit dem Original synchronisieren, falls es zuvor nicht mehr synchron war (!) Im Normalfall, wenn nichts geändert wird, synchronisiert es automatisch alle Komponente.

    Haben wir hingegen z.B. eine Komponente im Scene Fenster befindlichen Objekt hinzugefügt, so können wir dies auch mit dem Original (Prefab-Ordner-Objekt) mit "Apply" synchronisieren.

    (Werte, die vom Scene befindlichen Objekt vom Prefab abweichen, werden "Fett" dargestellt".)


    Testet nun kurz das Spiel und rollt zur unteren Seite, um die Rampe zu begehen.

    Wenn ihr alles richtig gemacht habt, so könnt ihr die Rampe nicht betreten, sondern fahrt durch sie hindurch.

    Dies liegt daran, dass unsere Rampe kein Primitiv ist und somit kein voreingestellten "Collider" als Komponente aufweist.

    Verlasst den Play-Mode und vergleicht die Mauern mit der Rampe. Die Mauern besitzen von Unity aus schon einen Box Collider.


    Navigiert nun zum im Prefab Ordner befindlichen "Ramp4" Objekt. Klickt dieses an und fügt ihm eine Komponente hinzu.

    Add Component => Physics => Mesh Collider

    Nun sollte auch das in Scene befindliche Objekt (Ramp4) eine solche Komponente besitzen.

    Wir haben eine andere Form, als die üblichen Collider und nehmen daher dieses. Standardmäßig setzt Unity euer 3D Objekt Mesh als Collider von dieser Komponente in das Feld "Mesh" ein.

    Da es sich hierbei um ein Low Poly Objekt handelt, ist dies absolut okay für uns. Andernfalls würde man ein Low Poly Mesh nehmen.

    Dies ist hier jedoch nicht der Fall / von Relevanz.


    Testet nun erneut das Spiel und ihr werdet sehen, dass ihr nun die Rampe befahren könnt, sofern ihr alles richtig gemacht habt.

    Wenn nicht, prüft ob euer Prefab die Komponente Mesh Collider besitzt und somit auch das Objekt in der Szene.

    (Wie es zu synchronisieren ist, steht ja oben.)


    Als nächstes fügt als Kind-Objekte in das Objekt "ObjectsLv1" folgende Objekte ein:

    7x Cube Objekte (3D) und aus dem FBX Ordner 1x Ramp1, 1x Ramp2, 1x Ramp3 und 1x Archway.


    Die 7x Cube Elemente werden wie auf dem Bild zu sehen entsprechend so angepasst, sodass jeder eine Transform-Komponente aus dem Bild erhält:

    Die restlichen Einstellungen bzw. Komponente der Cube's können so bleiben, wie sie sind. (Bitte achtet auch auf die Umbenennung der Cube's.


    Wechselt nun in den Materials Ordner des Project Fensters und zieht das "Environment" Material auf die Elemente "Ramp1, Ramp2 und Ramp3".

    Wenn ihr nicht an die Objekte kommt, verschiebt diese entsprechend so, dass ihr die Materials darauf platzieren könnt.

    Bleibt in den Materials Ordner und erstellt ein neues Material mit dem Namen "Elevator" und den farblichen Hex-Wert: "1E5532".

    Zieht dieses neu erstellte Material nun auf den "Elevator" Cube und den "Plattform" Cube.


    Wählt nun in der Hierarchy die verbleibenden Ramp1, Ramp2, Ramp3 und Archway Objekte nacheinander an und übergebt ihnen ein "Mesh Collider" Komponent (es kann auch die Sucher im Kontextmenü von "Add Component" verwendet werden.) Wenn jedes der 4 Objekte einen Mesh Collider besitzt, geht in das jeweilige Transform Komponent der Objekte und resettet sie, sodass ihr Ursprung bei 0 liegt.

    Wechselt nun in den Prefabs Ordner des Project Fensters und zieht diese genannten 4 Objekte (über das Hierarchy-Fenster) nacheinander in den Prefabs Ordner. Zieht außerdem auch den "Elevator" sowie die "Plattform" in den Prefabs Ordner.


    Wir haben nun mehrere Bauteile, die wiederverwendet werden können in unserem Prefabs Ordner.


    Nun wollen wir noch die Ramp1, Ramp2, Ramp3 und Archway Objekte an ihre Position in der Szene bringen. Die Namen habe ich im folgenden Bild daher nicht verändert. Gebt für das jeweilige Objekt die Transform Daten genau so von der Szene ein, in der sie platziert sind.


    Habt ihr alles richtig gemacht und diese Lektion entsprechend so nachgemacht, sollte es folgendermaßen aussehen:


    Sollte es nicht so aussehen, wäre es gut die entsprechenden Schritte zu wiederholen.


    Ihr könnt diesen kleinen Hindernislauf nun im Play-Mode testen.

    => Speichern nicht vergessen.



    Weiter geht es in "[Neuling] Roll a Ball Extended Version - Lektion 6 - Münzen für den Spieler"

    Willkommen bei "[Neuling] Roll a Ball Extended Version - Lektion 4 - Bewegung der Kamera" 8)

    Diese Lektion setzt Lektion 3 dieser Reihe voraus und baut entsprechend darauf auf.


    Nun wollen wir das Kamera Objekt entsprechend verändern.
    Wählt hierzu die "Main Camera" aus und ändert die folgenden Werte in der Transform Komponente:


    Anschließend zieht das Kamera-Objekt in der Hierarchy auf den Spieler, sodass es ein Kind-Objekt des Spielers ist:

    Die Kamera bewegt sich nun mit dem Spieler.

    Mit dem Play-Mode kann dies getestet werden. Doch ... nun rotiert die Kamera im Play-Mode auf eine sehr seltsame Weise mit dem Spieler.

    Das liegt daran, dass alle Koordinaten vom Spieler Objekt übernommen werden. Dies wollen wir so aber nicht, also müssen wir es entsprechend mit einem C# Skript unterbinden.


    Wählt nochmals die "Main Camera" aus und erstellt als neue Komponente für die Kamera ein C# Skript mit dem Namen "ControllerCamera".


    Schiebt nun wie beim Player Skript das soeben erzeugte Skript in den Scripts Ordner des Project Fensters.

    Es befinden sich nun 2 Skripte in diesem Ordner. Wählt das soeben erzeugte Skript aus und öffnet es.


    Ergänzt nun den Code um folgendes, sodass er wie dieser aussieht:


    Mittels der "public GameObject player;" Zeile stellen wir erneut Unity ein Feld zur Verfügung, in dem ein "Spiel Objekt" wie z.B. unser Player Objekt reingezogen werden kann. (Mehr dazu später).

    Der Offset als Vector 3 wird entsprechend der Grafik berechnet:

    Wir nehmen die Transformation der Kamera und subtrahieren diese mit der Transformation mit dem Spieler.


    Ergänzt nun folgendes in der "void Start()" Methode:

    Csharp
    1. offset = transform.position - player.transform.position;

    Und folgendes in der "void Update()" Methode:

    Csharp
    1. transform.position = player.transform.position + offset;


    Wir berechnen mit ersterem das Offset gemäß der oben erwähnten Regel.
    Bei dem Zweiten Code übergeben wir der Kamera Position die des Spielers + den Offset (also den Abstand) zwischen beiden.


    Unsere void Update() Methode ist jedoch nicht ganz der richtige Ort für eine solche Operation mit der Kamera.

    Es wäre im Prinzip zwar nicht falsch, aber da es sich hierbei um das "Rendern" also das anzeigen der Frames auf dem Bildschirm handelt, wird dies als letztes ausgeführt, hinter jeder Programmlogik.


    Hierfür steht von Unity die Methode "void LateUpdate()" zur Verfügung. Diese unterscheidet sich sofern, dass sie nicht vor jedem Frame aufgerufen wird, wie in void Update(), sondern erst nachdem jeder Programm Code des Scriptes fertig berechnet wurde, aufgerufen wird.

    Ändert demnach den Code so, dass er so aussieht wie hier:


    Speichert das Skript ab und kehrt in den Unity Editor zurück.

    Wählt das Kamera Objekt an und zieht im Hierarchy Fenster die Kamera aus dem Player Objekt wieder heraus.

    Die Kamera muss nun nicht länger ein Kind-Objekt vom Player sein.

    Aber wie weiß Unity nun, wer der Spieler / Player ist, bzw. das Objekt, welches er folgen soll.

    Wählt hierzu die Kamera erneut an und schaut euch die Skript Komponente an.


    Zieht nun vom Hierarchy Fenster das Player Objekt in den freien Platz des "Player" Slots in der Skript Komponente.


    Speichert nun das Projekt ab und testet es erneut im Play-Mode.

    Nun sollte euch die Kamera bei der Player Bewegung exakt so folgen, wie es gewollt ist.



    Weiter geht es in: "[Neuling] Roll a Ball Extended Version - Lektion 5 - Gestaltung des Spielfeldes"

    Willkommen bei "[Neuling] Roll a Ball Extended Version - Lektion 3 - Den Spieler bewegen" 8)

    Diese Lektion setzt Lektion 2 dieser Reihe voraus und baut entsprechend darauf auf.


    Wir wollen uns nun um den Spieler kümmern.

    Hierzu wählt den "Player" aus und fügt im Inspector über die Schaltfläche "Add Component" => "Physics" => "Rigidbody" hinzu.

    Es sollte nun eine weitere Komponente erschienen sein. Eine Alternative wäre diese Komponente über das Hauptmenü (oben) hinzu zu fügen.

    Klickt nun auf das Zahnrad (Settings) in der Rigidbody Komponente und wählt "Move Up", bis es unter der "Transform" Komponente sich befindet.

    Ihr wisst nun, wie man Komponenten untereinander organisieren könnt. Gewöhnt euch eine möglichst gleiche Struktur solcher Komponente in euren Projekten an, sodass ihr schnell die jeweilige Komponente im Objekt findet.


    Klickt nun auf das Buch-Icon der Rigidbody-Komponente.

    Es sollte sich ein neues Fenster öffnen, in dem ihr zur Unity Anleitung geleitet werdet.

    Laut Unity wird der Rigidbody folgendermaßen beschrieben:

    Rigidbodies enable your GameObjects to act under the control of physics. The Rigidbody can receive forces and torque to make your objects move in a realistic way. Any GameObject must contain a Rigidbody to be influenced by gravity, act under added forces via scripting, or interact with other objects through the NVIDIA PhysX physics engine


    Kurz gesagt: Diese Komponente (der Rigidbody) stellt euren Objekt die Möglichkeit zur Verfügung auf physikalische Änderungen z.b. durch einen Stoß, Bewegung, Gravitation, etc. zu reagieren.

    Es lassen sich ebenso Masse, physikalische Berechnungen, etc. damit bewerkstelligen.


    Hinweis: Um den Überblick bei sehr vielen Komponenten zu bewahren, können diese mit dem kleinen Pfeil auf der jeweils linken Seite eingeklappt werden. Dies hat keine Auswirkung auf das Objekt. Die Komponente funktioniert natürlich auch weiterhin.


    Als nächstes wollen wir ein Skript erstellen - unser erstes C# Skript, welches Funktionalität in unser Objekt bringt.

    Ein Skript kann auf verschiedene Arten erstellt werden. Einerseits in unserem Skript Ordner oder in anderen (was jedoch keinen Sinn machen würde) per Rechtsklick im "Project" Fenster => "Create" => "C# Script". Oder als Komponente für ein Objekt, wie unseren Player.

    In diesem Fall macht es mehr Sinn das Skript dem Spieler als Komponente direkt zu übergeben, da wir die Funktionalität auf dieses Objekt haben wollen.


    Wählt den Player an, klickt: "Add Component" => "New script" und wählt als Name "ControllerPlayer" => "Create and Add".

    Wichtiger Hinweis: Ihr könnt auch versuchen über die Suchfunktion bei "Add Component" einen Namen einzugeben, wie "SkriptXYZ". Dies ist als Komponente noch nicht realisiert und Unity schlussfolgert somit automatisch, dass es als Skript (C#) angedacht ist. Sprich: es ist eine schnelle Art ein Skript neu zu erstellen. Der obige Weg ist jedoch genauso gut.


    Habt ihr die Komponente hinzugefügt, sollte diese eurem Objekt hinzugefügt sein.


    Geht nun über das "Project" Fenster in euer Root Ordner "Assets", wo alle euren Ordner sind (FBX, Materials, ...).

    Hier sollte nun das ControllerPlayer.cs (C# Skript) liegen. Zieht dieses nun in den "Scripts" Ordner um Ordnung zu wahren.


    Wechselt nun in den Scripts Ordner und wählt das erstellt Skript an. Im Inspector sehr ihr nun eine Vorschau von dem Default erzeugten Code.

    Zum Bearbeiten klickt nun per Doppelklick auf das Skript.

    Je nach Entwicklungsumgebung (IDE) öffnet sich nun diese und zeigt den zuvor per Vorschau gesehenen Code an.


    Anmerkung: Ich nutze Visual Studio, solltet ihr MonoDevelop nutzen, kann die farbliche Formatierung ggf. anders aussehen. Dies tut jedoch hierbei nichts zur Sache.


    Löscht nun den folgenden Code:

    Csharp
    1. // Use this for initialization
    2. void Start () {
    3. }
    4. // Update is called once per frame
    5. void Update () {
    6. }

    Euer Skript sollte nun in etwa so aussehen:

    Csharp
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class ControllerPlayer : MonoBehaviour {
    5. }


    Unser Code kommt ab jetzt nur in diesen Teil / Klasse / Block:

    Csharp
    1. public class ControllerPlayer : MonoBehaviour {
    2. }


    Kurze Erwähnung:

    Es gibt mehrere Arten den Code bzw. euer Spiel 'aktuell' zu halten, sprich z.B. bevor Frames geladen werden den Code auszuführen.


    Meist wird hierfür void Update() verwendet:

    Csharp
    1. void Update () {
    2. }

    void Update() wird jedesmal bevor ein Frame angezeigt wird durchlaufen und führt den Code eures Programmes aus. Hier landet der meiste Spiele-relevante Code.


    Hingegen z.B. void FixedUpdate() ist für physikalische Berechnungen zuständig und wird vor jeder physikalischen Berechnung ausgeführt.

    Csharp
    1. void FixedUpdate () {
    2. }

    Da wir eine physikalische Berechnung wollen, wird diese Funktion von uns benötigt.

    Es gibt weitere Update Varianten wie z.B. LateUpdate, welches immer zuletzt geladen wird, ehe das Spiel gerendert wird.

    Mehr hier unter der Unity Referenz.


    Unser Code sollte nun so aussehen:

    Csharp
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class ControllerPlayer : MonoBehaviour {
    5. void FixedUpdate () {
    6. }
    7. }


    Schreibt nun in die FixedUpdate Funktion "Input".

    Wir wissen, wir brauchen einen Input, aber welchen genau, ist ja unbekannt.

    Es lässt sich die Unity Referenz hierzu hernehmen.

    Hier finden wir eine Fülle von Informationen über Eigenschaften, Methoden, etc. die Unity uns wie Update() und FixedUpdate() bereitstellt.

    Uns interessiert hierbei jedoch vorerst nur die statische Methode "Input.GetAxis".

    Input.GetAxis(string axisName) erwartet also einen Parameter vom Typen string.


    Wem das jetzt hier noch nichts sagt, sollte unbedingt meine C# Lektionen durchlesen und sich damit beschäftigen. Das Tutorial / Projekt hier ließe sich auch ohne dem Wissen fortsetzen, jedoch wird das Verständnis vermutlich nicht so stark aufgebaut / fehlen, um die Aktionen dahinter zu verstehen.


    In dem Beispiel auf der Seite von Unity unter Input.GetAxis sehen wir folgende Verwendung:

    Csharp
    1. float translation = Input.GetAxis("Vertical") * speed;
    2. float rotation = Input.GetAxis("Horizontal") * rotationSpeed;

    Wir können dies als ersten Anhaltspunkt hernehmen, wandeln es jedoch für uns etwas um.


    Geht nun zurück in den Skript Editor.

    Ergänzt eure FixedUpdate() Funktion um folgenden Code:

    Csharp
    1. void FixedUpdate ()
    2. {
    3. float moveHorizontal = Input.GetAxis("Horizontal");
    4. float moveVertical = Input.GetAxis("Vertical");
    5. }


    Um es jetzt klar auszudrücken: Unity weiß nun, welche Achse im Spiel die Vertikale und welche die Horizontale ist.

    Sprich, welche Pfeiltasten welchen Achsen entsprechen. Aber woher weiß Unity das?

    Hierzu schauen wir uns in Unity die Input Einstellungen an.

    Hier sehen wir also, dass der Name der horizontalen Achse gleich "Horizontal" und der vertikalen Achse gleich "Vertical" ist.

    (Also die englischen Namen) Die Tasten (Pfeil und alternative Tasten) weiß Unity ebenso durch die entsprechende Zuweisung.


    Daher ist es wichtig das euer Code exakt diese Namen zwischen den " " Zeichen enthält. Andernfalls weiß Unity nicht, welche Achsen gemeint sind.

    Stünde in den Eigenschaften bei der horizontalen Achse "Blubb" (was nicht sinnvoll wäre(!), so müsste im Code entsprechendes stehen:

    Code
    1. void FixedUpdate ()
    2. { float moveHorizontal = Input.GetAxis("Blubb");
    3. float moveVertical = Input.GetAxis("Vertical");
    4. }

    Dies wollen wir jedoch nicht, es diente nur dem Verständnis - am Besten ihr behaltet die von Unity voreingestellten Namen bei.

    Solltet ihr zukünftig andere Achsen wissen wollen, wisst ihr, wo diese zu finden sind.



    Wir haben nun die Achsen und den Input. Für die Physik benötigen wir nun jedoch den "Rigidbody".

    Also tippen wir dies entsprechend ebenso in unseren Code.


    Wir wissen jedoch nicht, was wir zur Verfügung haben.

    Daher suchen wir wieder in der Unity Scripting API nach "Rigidbody" und finden unter anderem einen Eintrag wie "Rigidbody.AddForce".
    In dem gezeigten Beispiel sehen wir auch die Verwendung von diesem:

    Anhand diesem Beispiel sehen wir in etwa, wie es zu verwenden ist. Auf der Hauptseite, die wir in der Scripting API gefunden haben, sehen wir außerdem folgendes:

    public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force);


    D.h. unsere AddForce Methode vom Rigidbody benötigt einen 3D Vektor und einen optionalen ForceMode.

    Wir belassen dies erstmal im Raum stehen. Der 3D Vektor kann separat erzeugt werden wobei es nach dem Format " X, Y, Z " -Achse definiert wird. Er kann aber auch in der Methode direkt geschrieben werden.

    Sollte dies an dieser Stelle noch nicht klar sein, wird es das hoffentlich im folgenden Beispiel anhand unseres Codes.


    Erweitert nun den Code um folgendes (Erklärung folgt) :


    Erklärung:

    Csharp
    1. private Rigidbody rb;

    Deklariert eine Variable des Types Rigidbody mit dem Namen rb.

    Diese Variable soll unseren Rigidbody beinhalten, der unserem "Player" (Kugel) Objekt in Unity als Komponente zugewiesen wurde.

    Doch... woher weiß Unity (das Skript) nun, welcher Rigidbody gemeint ist und mit welchem er sich 'verlinken' soll / es in die Variable speichern soll?


    Hierfür ist folgendes notwendig:

    Csharp
    1. void Start()
    2. {
    3. rb = GetComponent<Rigidbody>();
    4. }

    Erstmal: void Start() ist ähnlich wie Update() und FixedUpdate() eine Funktion von Unity, die das Spiel und deren Logik von elementarer Wichtigkeit sind.

    void Start() und der Inhalt, also hier die "rb = Get....." Zeile wird einmalig beim Aufruf des Skriptes ausgeführt. Meist ist dies auch gleich der Spiel-Start.

    Es wird somit nicht jeden Frame neu geladen, was hier ja nicht notwendig ist. Wir wollen nur einmalig Unity sagen, was in unserer Rigidbody Variable gespeichert sein soll.

    Dies tuen wir mit der Zeile: rb = GetComponent<Rigidbody>();


    Unity weiß nun, dass die Rigidbody Komponente unseres Players in der "rb" Variable vom Typ Rigidbody gespeichert ist.


    Bleiben noch folgende Zeilen:

    Csharp
    1. Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
    2. rb.AddForce(movement);


    Erstere Zeile mit dem "Vector3" initialisiert einen neuen Vector3 (also alle 3 Achsen), in dem wir gemäß dem Format "X, Y, Z" Achse die Daten übergeben.

    Wir wissen oder sehen anhand des Unity Gizmos (Bunte Kegel-Achsen im Scene View in Unity), dass die "Y-Achse" die Achse für oben und unten ist.

    Unser Spieler soll sich nicht nach oben oder unten bewegen, weswegen wir dies mit 0 setzen. unsere anderen Input Variablen tragen wir an entsprechender Stelle ein.


    Nun übergeben wir den Vector3 (movement) an unseren Rigidbody über "rb.AddForce(movement);"


    Speichert das Skript ab und kehrt zu Unity zurück.

    Es kann kurzzeitig dauern, bis Unity darauf reagiert. Ist im "Console" Tab neben dem "Project" Tab (unten) kein Fehler, so habt ihr alles bisher richtig gemacht.


    Startet nun das Spiel mit Klick auf dem "Play-Pfeil" oben in der Mitte.


    Ihr befindet euch nun im Spiel Modus (Play-Mode).
    Achtung!!! => Alle Änderungen, die ihr in diesem Modus macht, gehen verloren, sobald ihr wieder in den normalen Modus zurück geht!


    Ihr könnt nun die Pfeiltasten drücken und die Kugel / der "Player" sollte sich entsprechend (wenn auch langsam) bewegen.

    Derzeit ist es fast noch zu langsam. Das wollen wir nun ändern.


    Beendet den Play-Mode durch erneutes Drücken auf den "Play-Button" oben in der Leiste.

    Hinweis: Testet ruhig immer wieder euer Projekt zwischendurch um größere Fehler ausschließen zu können.


    Öffnet nun erneut das Skript des Player's. Wir könnten nun folgende Zeile verändern:

    Csharp
    1. rb.AddForce(movement);

    zu:

    Csharp
    1. rb.AddForce(movement * 50);


    dies ist aber eine sehr unelegante Methode. Denn... jedesmal, wenn wir diesen Wert ändern wollten, müssten wir in das Skript und diesen dort entsprechend abändern.

    Daher verändern wir diese Zeile nicht und erweitern unseren Code entsprechend so, wie im folgenden gezeigt:


    Mit "public float speed;" führen wir eine neue Variable ein, in der unsere Geschwindigkeit gespeichert ist. Diese wird mit "rb.AddForce(movement * speed);" multipliziert und auf unser Objekt übertragen.

    Das Gute an der "public" Deklaration unserer Variable ist, dass diese nun in Unity als Feld bei der Skript-Komponente dem Player-Objekt zur Verfügung steht. Wir können also hier den Wert eintragen, ohne im Skript 'pfuschen' zu müssen.


    Speichert das Skript und wechselt in den Unity Editor.

    Wählt den Player an und schaut die Skript Komponente an. Diese sollte nun um ein Feld "speed" mit einem Zahlenwert von "0" ergänzt worden sein.

    (Es kann etwas dauern, bis Unity das Feld anzeigt, nachdem ihr vom Skript Editor zum Unity Editor wechselt.)


    Tragt nun statt 0 den Wert "10" ein.


    Wechselt nun erneut in den Play-Mode.

    Beim Bewegen des Spielers mittels den Pfeiltasten sollte dieser nun wesentlich schneller über den Bildschirm sich bewegen.

    Beendet den Play-Mode und speichert das Prjekt ab.



    Weiter geht es in: "[Neuling] Roll a Ball Extended Version - Lektion 4 - Bewegung der Kamera"

    Willkommen bei "[Neuling] Roll a Ball Extended Version - Lektion 2 - Das Grundgerüst" 8)

    Diese Lektion setzt Lektion 1 dieser Reihe voraus und baut entsprechend darauf auf.


    Klickt nun per Rechtsklick in das Projekt - Fenster unter "Assets" und erstellt euch folgende Ordner, sodass dies entsprechend wie auf dem Bild aussieht:

    Achtet bitte auf die Rechtschreibung, wobei Groß- und Kleinschreibung egal ist.

    Manche Ordner haben in Unity besondere Funktionen, wenn diese entsprechend benannt sind, wie der "Prefabs"-Ordner. Mehr hierzu jedoch später.


    Desweiteren benötigt ihr noch ein paar Dateien, die ihr in das Fenster reinziehen müsst.

    Ich habe hierzu euch einen FBX Ordner mit 3D Elementen vorbereitet.

    Ladet diesen herunter und zieht ihn in euer Unity-Projekt hinein, sodass ein weiterer Ordner mit "FBX" und den 3D / .fbx Dateien sich in eurem Projekt befinden, neben den anderen Ordnern.

    Hier herunterladen: FBX.zip


    Es sollten nun 5 Ordner mit dem FBX Ordner vorhanden sein.


    Klickt nun in das "Hierarchy" Fenster per Rechtsklick => 3D Object => Plane.

    Es sollte nun ein Element "Plane" in eurem Hierachy Fenster erscheinen sowie in der Scene sichtbar sein.

    Diese von Unity bereitgestellten Objekte sind auch sog. "Primitives". Also Objekte, die eine sehr 'einfache / primitive' Form haben, für Demonstrationen an Code, etc. aber sehr gut geeignet sind.


    Zur weiteren Gestaltung des Spiels könnt ihr euch aussuchen, ob ihr alle Werte so übernehmen wollt, wie ich diese vorgebe oder eigene nehmt. Ich würde Neulingen jedoch empfehlen erst alles so zu übernehmen und ggf. am Ende der Reihe eigenes zu probieren oder das Spiel zu erweitern.


    Klickt nun die Plane an. Ihr sehr im "Inspector" nun viele Einstellungen die logisch angeordnet sind.

    Dies wird in Unity als "Komponente" bezeichnet. Bzw. "Component".

    Jedes "Component" bietet eine logische Gruppe an Einstellungen bzw. manchmal auch nur eine, wodurch das Objekt an Komplexität dazu gewinnen kann.


    Ganz oben können wir unser Element umbenennen. Ändert es von "Plane" zu "Boden".

    Ebenso wollen wir die Größe ändern. Dies geht über die Komponente "Transform".

    Um jedoch sicher zu stellen, dass sich unser Boden im Ursprung des Koordinaten Systems von Unity befindet, klickt zuerst auf das Zahnrad im Transform Fenster.

    Der erste Eintrag sollte "Reset" lauten. Wenn ihr versehentlich das Pannel verschoben haben solltet, befindet es sich nun wieder im Ursprung.

    Es ist oftmals wichtig, ein Objekt zu resetten, daher bitte merken.


    Ändert die Größe folgendermaßen:


    Als nächstes Grundlagen der Navigation


    Da wir in Unity auch 3D behandeln können, nicht nur 2D, wie im RPG Maker, ist die Bewegung in Unity im Scene - Fenster etwas anders.

    Mit gedrücktem Mausrad könnt ihr euch in Unity beim gleichzeitigen schieben der Maus bewegen, mit scrollen des Rades könnt ihr zoomen und ensprechend mit gedrückter rechten Maustaste die Blickrichtung ändern.

    Die linke Maustaste kann Elemente im Scene View / Fenster auswählen.

    (Ihr könnt aber auch Elemente über das Hierarchy Fenster auswählen, umbenennen, löschen, etc.)


    Solltet ihr euch zu weit vom Element entfernen, so könnt ihr die "F" Taste nach Anwahl des Objektes drücken.

    Hier wird der Fokus wieder auf das Objekt gerichtet und der Zoom neu kalibriert.

    Alternativ geht das auch über das Menü: "Edit => Lock View to Selected".


    Eine weitere Möglichkeit der Navigation ist über die "Gizmos".

    Sprich über die Koordinaten, die rechts oben als farbige Kegel-Achsen im Scene Fenster angezeigt werden.

    Klickt ihr z.B. auf die grüne Y-Achse, so seht ihr euer Projekt von oben. Der Würfel (Quadrat) in der Mitte dieses Gizmos wechselt die Ansicht zwischen perspektivisch und isometrisch. Wie wollen jedoch die voreingestellte "perspektivische" Sicht beibehalten.



    Wichtig!

    Vergesst nicht regelmäßig euer Projekt zu speichern.

    Dies könnt ihr per "STRG + S" und / oder über das Menü: "File => Save Scene" sowie "File => Save Project".


    Es sei noch erwähnt, dass die Transformation, Skalierung von Objekten sowie Rotation über die Schaltflächen unter der Menüleiste oben links am Objekt vorgenommen werden können. Dies ist jedoch auch in der Transform - Komponente der Objekte mit Zahlenwerten möglich - teils ist beides auf seine Art sinnvoll einzusetzen.


    Nun jedoch erstmal genug zu allgemeinen Hinweisen sowie der Steuerung.


    Fügt nun als nächstes eine "Sphere" ein.

    Hierarchy => Rechtsklick => 3D Objekt => Sphere

    Achtet darauf, dass die Sphere kein 'Elternteil' hat. Sprich: Wenn die Sphere eurem "Boden" untergeordnet ist, müsst ihr diese herausziehen und bei der Transform Komponente die Werte resetten.


    Zoomt nun mit "F" und der angewählten "Sphere" zu ihr hin.

    Benennt diese ebenso in "Player" um und setzt unter Position in der Y-Richtung "0.5" als Wert fest. Nun sollte die Kugel auf dem Boden sich befinden.


    Kleiner Hinweis:

    Unity Primitives haben i.d.R. Maße von 1.

    Daher ist mit der Y-Korrektur von 0.5 nach oben die Kugel auf unserem Boden.



    Achtung!

    Ich setze von nun aus voraus, das ihr wisst, wie man 3D Objekte (Unity Primitives) in eure Szene bringt. Ebenso wie diese zu resetten sind, etc.

    Dies wird in weiteren Lektionen sowie Projekten in Zukunft mit "Erstellt ein 3D Cube Objekt" / "Erstellt ein 3D Plane Objekt" abgekürzt.

    Alle Elemente zum Erstellen können über das Hierarchy Fenster und Rechtsklick gefunden werden.


    Navigiert nun im Project Fenster zu eurem "Materials" Ordner.

    Dieser sollte noch leer sein und ihr erstellt nun per "Rechtsklick => Create => Material" ein neues 'Material' und benennt dieses in "Boden" um.


    Wählt dieses nun aus - mit Materials können in Unity farbliche Veränderungen getätigt werden, ebenso Texturen auf Objekten platziert werden und vieles mehr.

    Erste Einstellungen seht ihr bereits nach der Auswahl dieses Materials im Inspector.

    Klickt hier nun im Feld "Albedo" auf den weißen Farbkasten und ändert folgende Werte:

    Zieht nun per Drag and Drop das Boden Material auf euren Boden.

    Er sollte sich nun Blau verfärben und die Kugel (Player) weiterhin weiß bleiben.


    Herzlichen Glückwunsch! Ihr habt nun das Grundgerüst für das Spiel vorbereitet sowie ein erstes Material erstellt.

    Natürlich könnt ihr auch ein weiteres Material erstellen und dieses "Player" benennen und entsprechend nach farblicher Anpassung auf die Kugel (den Player) ziehen.


    Als letztes für diese Lektion wollen wir noch das Element "Directional Light" in der Hierarchy auswählen und in der Transform Eigenschaft die "Y-Rotation" auf 60 setzen.



    Weiter geht es in "[Neuling] Roll a Ball Extended Version - Lektion 3 - Den Spieler bewegen"

    Willkommen zur 1. Lektion von "Roll a Ball Extended Version". 8)

    Der Schwierigkeitsgrad ist "Neuling", d.h. es werden keine Vorkenntnisse von Unity benötigt und wir werden in diesem Projekt erste Grundbegriffe klären.

    Es wird jedoch vorausgesetzt, dass die allgemeinen Informationen zur Kenntnis genommen worden sind.


    Dieses Projekt ist an Unity's offizielles (Englische Tutorial) "Roll a Ball" angelehnt, wurde jedoch von mir ausgebaut um weitere Mechaniken euch vorzustellen.

    Es wird am Ende ein kleines Spiel ergeben, in welchem ihr eine Kugel lenkt, die Münzen einsammeln muss. Auf dem Weg befinden sich verschiedene Hindernisse.



    So könnte das fertige Projekt aussehen:

    p01-000.png



    Nun aber auf ins Projekt!


    Startet Unity und erstellt ein neues 3D Projekt.


    Nach dem Erstellen des Projektes, sollte eure Umgebung in etwa so aussehen:

    Links haben wir die "Hierarchy". Dieses Fenster zeigt euch alle Elemente der jeweiligen Szene (Scene) an.

    Ein Projekt kann mehrere Scene's enthalten. Z.B. ein Adventure Game mit einer jeweilig anderen Scene, je nach Aufenthaltsort.


    Auf der rechten Seite befindet sich der "Inspector". Dieser gibt euch genauere Informationen über das ausgewählte Element und i.d.R. werden über diesen auch viele Einstellungen zu sog. "Komponente" der Elemente vorgenommen.


    Weiter unten findet ihr eine Übersicht, wie euer Projekt allgemein angeordnet ist inkl. Ordner-Struktur.

    Wenn ihr zukünftig z.B. 2D oder 3D Elemente in Unity 'zieht' (Drag & Drop), so werden diese von Unity in das entsprechende Verzeichnis kopiert, an dem ihr euer Projekt angelegt habt.

    Es funktioniert demnach wie der Explorer von Windows (als Vergleich).

    Ebenso ist unten standardmäßig ein Tab mit "Console" vorzufinden. Dies wird erst später bei der Programmierung interessant, da hier Fehler oder Warnungen angezeigt werden.


    In der Mitte des Bildschirmes befindet sich der 'eigentliche' visuelle Editor von Unity die "Scene" als geöffnete Datei.

    Weiterhin sind auch Tabs wie "Game" oder der "Asset Store" vorzufinden.

    Im Game - Tab wird unser Spiel gespielt und kann von der Perspektive entsprechend betrachtet werden.

    Der Asset Store - Tab kann vorerst geschlossen werden (hierzu einfach per Rechtsklick "Close Tab" drücken).


    Solltet ihr versehentlich ein Fenster geschlossen haben, so kann dieses über: "Window -> General -> ... " erneut geöffnet werden. Ihr könnt ebenso Tabs und Fenster hin und her ziehen, je nach belieben.

    Für uns soll jedoch die Standard Anordnung ausreichen.


    Nun noch eine kurze Bemerkung bzgl. der Entwicklungsumgebung.

    Unity liefert MonoDevelop mit sich, d.h. ihr könnt C# dort entsprechend programmieren.

    Für alle, die jedoch lieber eine andere IDE nutzen möchten, können das folgendermaßen einstellen:

    Edit => Preferences => External Tools => External Script Editor

    Bleibt in diesen Einstellungen und wechselt zu "Colors" (Tab).

    Ändert nun die "Playmode tint" Farbe per Klick auf das Feld über den 'Hexadecimal'-Wert "A15151", sodass diese leicht Grau-Rot dargestellt wird. Dies wird später beim Testen der Projekte nützlicher sein.


    Schließt die Einstellungen wieder.

    Nun wollen wir das eigentliche Projekt starten.


    Weiter in "[Neuling] Roll a Ball Extended Version - Lektion 2 - Das Grundgerüst"

    Hey Zusammen! 8)


    Hier ein paar Informationen über dieses Forum.

    Ich werde nach und nach Schritt für Schritt Unity Projekte zum Mitmachen und Mitgestalten hier hochladen.

    Der Schwierigkeitsgrad wird unterschiedlich sein und entsprechend markiert werden.



    Eine Übersicht der vorhandenen Projekte ist hier einzusehen:



    Für alle, die noch nie etwas mit Unity zu tun hatten, wird mindestens das Projekt "[Neuling] Roll a Ball Extended Version" empfohlen, da hier wichtige Grundbegriffe, wie auch Unity als Engine behandelt werden.

    Die Liste wird im Laufe der Monate länger, je nachdem, wie es meine Zeit zulässt.


    Fragen sind im jeweiligen Projekt-Thread bei Unklarheiten zu stellen.

    Aus bestimmten Gründen ist dieses Forum erstmals so eingestellt, dass keine eigenen Threads gestartet werden können.


    Ich setze voraus, dass Unity bereits heruntergeladen und erfolgreich installiert wurde.

    Wir werden alle Projekte von 0 aus mit einem neuen Projekt starten oder ihr erhaltet von mir ein Grundgerüst als Vorlage.


    Die Sprache, in der wir unsere Logik einbauen werden, wird C# aus verschiedenen Gründen sein. Ich biete hier erstmals keinen Support für JavaScript an, wenn auch Unity dies (noch) von sich aus anbietet.

    Ich empfehle jeden meine C# Tutorial Lektionen, sofern man nicht mit dieser Sprache vertraut ist bzw. allgemein keine Programmiererfahrung hat.

    In Unity kann mit der eigenen Entwicklungsumgebung "MonoDevelop" der C# Code geschrieben werden, ebenso jedoch auch mit Visual Studio (siehe C# Tutorials).

    Die Wahl der IDE (Entwicklungsumgebung) wird euch überlassen.

    Je nach Projekt kommen wir um manch komplexeren Ausdrücke oder Code-Gerüste nicht drum herum. Ich versuche die Beispiele jedoch allgemein verständlich und simpel zu halten.

    Bei Fragen zu einer Lektion können diese unter dem Thread gestellt werden.



    Nun viel Spaß mit den Projekten!




    FAQ:


    - derzeit keine Fragen -

    Hey Zusammen und Willkommen in der 2. Lektion zu C# 8)

    :s_rechts: Diese Lektion setzt die 1. Lektion zu C# voraus.


    Was sind Variablen?

    Im Grunde können Variablen als Behälter oder Schubladen für entsprechende Inhalte gesehen werden.

    Dabei unterschiedet man zwischen verschiedene Datentypen, also z.B. können manche Variablen Zahlen beinhalten für mathematische Operationen, andere Zeichen (Buchstaben) zur Textausgabe.

    Dieses Grundgerüst findet sich in jeder Programmiersprache - ebenso wie Schleifen, Kontrollstrukturen, ...


    Variablen müssen deklariert werden. Also ihr Datentyp sowie ihre Bezeichnung muss festgelegt werden.

    Es kann ebenso eine Wertzuweisung erfolgen, muss an dieser Stelle jedoch nicht.

    Variablen, die miteinander verknüpft werden, müssen in ihrem Typ verträglich zueinander sein. (Später mehr dazu.)


    Bsp einer Variable:

    double zelle1, zelle2;

    <Datentyp> <Liste oder einzelner Name der Variable>


    Der Name einer Variable ist frei wählbar, solange kein Schlüsselwort (siehe Lektion 1).


    Deklaration von lokalen Variablen

    • Jede lokale Variable muss vor ihrer Verwendung deklariert werden.
      Bsp.: double a, b, c;
    • Bei der Deklaration kann eine Variable mit einem Anfangswert des gleichen Typs initialisiert werden.
      Bsp.: double a = 1.51, b, c;
    • Der Geltungsbereich von lokalen Variablen ist der Block, in dem sie deklariert sind. Im selben Geltungsbereich kann keine andere Variable gleichen Namens vereinbart werden.

    Definition lokaler Konstanten

    • Lokale Variable kann auch als konstant vereinbart werden. Dann ist die Variable nachträglich nicht mehr veränderbar.
    • Eine lokale Konstante muss bei der Vereinbarung initialisiert werden.
      Bsp.: const double pi = 3.1415927;

    Eine Übersicht der in C# vertretenen Datentypen ist hier einzusehen.

    Wir beschäftigen uns am Anfang jedoch erstmal nur mit den folgenden Datentypen:

    bool, char, int, long, uint, ulong, float, double, decimal, string


    Die erwähnten Datentypen haben unterschiedliche Wertebereiche und zählen zu den sog. "einfachen Typen".


    Schlüsselwort Wertebereich
    int -2 147 483 648 … 2 147 483 647
    long -263 … 263-1
    uint 0… 4 294 967 295
    ulong 0 … 264-1
    float +-1.4E-45…+-3.4E38 (32 Bit)
    double +-5E-324…+-1.7E308 (64 Bit)
    decimal +-1E-28…+-7.9E28 (128 Bit)
    bool true, false (wahr, falsch)
    char Unicode-Zeichen
    string Unicode-Zeichen / mögliche Verkettung von char's


    Die einzelnen Wertbereiche sollten hier nicht auswendig gelernt werden, auch wenn ein gewisses Verständnis generell nicht schadet.


    Kurze Zusammenfassung:

    Ganze Zahl

    • Dezimal
    • Hexadezimal: muss mit 0x oder 0X beginnen
    • Suffix u oder U: Konstante wird im Datentyp uint oder ulong gespeichert
    • Suffix L: Konstante wird im Datentyp long gespeichert
    • Typ der Zahl ist der kleinste Typ aus int, uint, long oder ulong, zu dem der Zahlenwert passt.

    Gleitpunktzahl

    • Gebrochener Anteil wird durch Punkt (.) abgetrennt
    • Typ ist double
    • Suffix f oder F: Konstante wird im Datentyp float gespeichert
    • Suffix m oder M: Konstante wird im Datentyp decimal gespeichert

    Beispiele

    12345 => int, dezimal

    1.2345 => double (kein float !)

    1.2345f => float

    0x1A , 0X1A => int, hexadezimal (Wert: 26)

    7926U => uint

    7926L => long

    'B' => char, Zeichenkonstante

    "Maru" => Zeichenkettenkonstante (string)


    Wichtig: uint oder ulong werden nur als Datentypen für positive Zahlen verwendet.

    Es sind hiermit keine negativen Zahlen darstellbar.


    Die für uns wichtigsten Datentypen:

    int, double, string, bool, char


    Zeichen

    • Zeichenkonstanten werden in ‘ ‘ (Hochkomma) eingeschlossen.
      Es dürfen nahezu beliebige Zeichen vorkommen, außer Hochkomma, Zeilenende oder \
      Bsp.: ‘b‘

    Sonderzeichen

    • Escape-Sequenzen zur Darstellung von Sonderzeichen
      Bsp.:
      \n => Neue Zeile
      \t => horizontaler Tabulator
      \‘ => Hochkomma
      \“ => “
      \\ => \

    Zeichenketten (Strings)

    • Zeichenkettenkonstanten werden in “ “ eingeschlossen
      Es dürfen beliebige Zeichen vorkommen, außer Hochkomma, Zeilenende oder \
      Bsp.: “Hallo Welt“
    • Steht vor einer Zeichenkette das Zeichen @, dürfen darin Zeilenumbrüche vorkommen,
      \ wird nicht als Escape-Zeichen interpretiert und “ muss verdoppelt werden.


    Boolescher Datentyp

    • Für die beiden möglichen Werte eines booleschen Ausdrucks sind die Schlüsselworte true („wahr“) und false („falsch“) definiert.
    • Datentyp: bool
    • Benutzung z.B. Schalter (switches, wie beim Maker)
      Bsp.:
    Csharp
    1. bool schalter1 = true;
    2. if (schalter1)
    3. {
    4. // Code der ausgeführt wird, wenn 'schalter1' gleich true ist.
    5. }


    Zuweisung von Werten:

    <linke Seite> = <rechte Seite>

    veränderlicher Wert = wertliefernder Ausdruck


    = als Zuweisungsoperator, ";" als Anweisungsende.

    Bsp.:

    Csharp
    1. int x,y,a,b;
    2. x = 2*y +3; // Anweisung: x wird zu 2*y+3
    3. a = b = 4; // Mehrfachzuweisung: a und b beinhalten nun beide den Wert 4



    Wert-Verträglichkeit / Konvertierbarkeit der Werte


    Frage: Wie lautet bei Ausgabe an die Konsole der Wert von "ergebnis" und "ergebnis2"?



    Eine kleine, aber wichtige Randbemerkung, die auch für zukünftige Lektionen gelten wird!

    => Ihr könnt den Code kopieren. Solltet ihr einen Fehler bekommen, löscht ggf leere Zeilen und setzt diese neu.

    Aufgrund des Lerneffektes wäre es jedoch ohnehin besser, wenn es abgetippt werden würde. So stellt ihr auch sicher, dass keine Symbole falsch in die IDE kopiert werden und euer Programm ohne Fehlermeldung laufen kann.


    Typenumwandlung

    wie im obigen Bsp. gesehen, kennen wir nun die implizite Typenkonvertierung.

    Als grobe Faustregel lässt sich hier sagen: Kleine Datentypen wie lassen sich in größere überführen, große jedoch nicht in kleine zurück.

    Bsp.: byte =>short => int => long => float => double

    Aber double geht nicht in byte oder short, bzw. int, etc.



    Eine weitere Methode zur korrekten Typenumwandlung ist die:


    Explizite Typenumwandlung

    Explizite Typumwandlungen erfolgen:

    • Durch die Verwendung eines Typumwandlungsausdrucks in einer Zuweisung:
      (<neuer Datentyp>) <Ausdruck>;
      Bsp.: int int_var;
      double_var = (double) int_var;
    • Mit der Convert-Klasse:
      Bsp.: string s = Console.Readline();
      double k1 = Convert.ToDouble(s);

    Bei ersteren wird eine int Variable in eine double Variable gewandelt mittels der expliziten Konvertierung "(double)".

    Bei der Convert-Klasse wird sich einer Klasse mit Funktion bedient, die C# zur Verfügung stellt.

    Beides würde zum selben Resultat führen und den int (Integer) als double abspeichern.



    Hinweis zu weiteren Lektionen:

    Bisher haben wir nur Basics und Grundgerüste kennengelernt.

    In den weiteren Lektionen werden teils auch Übungsaufgaben einfließen um das Verständnis zu festigen.

    Es wird angeraten diese möglichst mit der Entwicklungsumgebung nach Wahl durchzuführen und sich daran zu probieren.


    In Lektion 3 behandeln wir die Ein- und Ausgabe auf der Konsole.

    Hey Zusammen und Willkommen in der 1. Lektion zu C# 8)

    :s_rechts: Diese Lektion setzt die Vorabinformationen zu C# voraus.


    Zum folgenden Ausführen und testen des Codes kann Visual Studio oder MonoDevelop von Unity verwendet werden, wie jede IDE, die C# unterstützt. Siehe hierzu die genannten Infos im Link (oben).

    Da ich persönlich Visual Studio vorziehe werde ich entsprechend hier beschreiben wie ein neues Projekt zu starten ist.

    Dieses Vorgehen zieht sich auch durch die weiteren Lektionen und wird daher nur einmalig hier erwähnt.


    Öffnet "Visual Studio" => Erstellt ein neues Projekt => "Console App" bzw. "Konsolen Anwendung" im Deutschen.

    Es sollte so aussehen:


    Benennt diese sinnvoll z.B. als "Uebung1" oder ähnliches.


    Wenn ihr alles richtig gemacht habt, sollte es in etwa so aussehen:

    (Je nach Sprache mit unterschiedlichen Benennungen der Oberflächen Elemente. Ich bevorzuge Englisch, da mehr Support im Englischen Raum vorhanden ist, sollten Fragen vorhanden sein.)

    => Der Code in "Programm.cs" ist bzw. sollte jedoch gleich aussehen bzw. kann dies auch teils bei den "using ..." Zeilen abweichen. Dies tut an dieser Stelle jedoch nichts zur Sache.


    In Zukunft wird vorausgesetzt, wie ein Projekt zu erstellen ist.


    Für was die jeweiligen Bezeichner, Namensräume, etc. nun stehen, mag uns an dieser Stelle nicht interessieren. Wichtig ist für den Anfang nur zu wissen, dass euer "Code" in den geschweiften Klammern nach:

    "static void Main(string[] args)" kommt.


    Kopiert den folgenden Quellcode und ersetzt ihr in eurem Programm, sodass es so aussieht:

    Csharp
    1. static void Main(string[] args)
    2. {
    3. // Euer Code sollte hier rein.
    4. Console.WriteLine("Hello World");
    5. }


    Wichtig! Es gilt nur

    "static void Main(string[] args)

    {

    }"

    zu ersetzen.


    Wenn ihr nun "STRG + F5" zur selben Zeit drückt, führt ihr den Code aus.

    Es sollte sich eine Konsole öffnen mit "Hello World" als Ausgabe.


    Herzlichen Glückwunsch! Ihr habt euer erstes Programm geschrieben. ninja_yeah



    Nun etwas mehr Theorie:


    Was waren die Elemente unseres Programms?

    Wir hatten:

    • Kommentar ( // Hier ein Kommentar)
    • Namensraum (using System; , ...)
    • Funktionsaufruf
    • Bildschirmausgabe

    Das wichtigste überhaupt - so meine ich zumindest: Der Kommentar.

    Angenommen es existiert ein Programm mit über 2 Millionen Zeilen an Code ohne Kommentar, so würde keiner der Entwickler (nicht einmal man selber) das Programm nach einiger Zeit nachvollziehen können.


    Kommentare werden folgendermaßen erzeugt:

    /* Hier der Text oder die Beschreibung */ Dieser Kommentar geht über mehrere Zeilen. Z.B.

    Csharp
    1. /* Dies ist ein
    2. Kommentar
    3. über mehrere Zeilen */
    4. // Ich bin ein Kommentar, der nur in einer einzelnen Zeile stehen darf.
    5. /// Dokumentationskommentar (mehr dazu später)

    Kommentieren von Code ist sehr wichtig! Bitte verwendet sinnvolle Kommentare z.B.

    "Das Programm / Die Funktion XY berechnet den Sachverhalt Z".

    Kommentare wie "Dies ist eine Funktion" werden (außer zu Lehrzwecken) eher nicht sinnvoll in einem Programm für euch sein.


    weiterhin hatten wir "class Program"

    Der Name "Program" wäre beim Erstellen einer Klasse frei wählbar - mehr hierzu später.


    "static void Main(string[] args)"

    Dies ist die Funktion, die beim Starten des Programmes aufgerufen wird. Hier wird der PC das Programm starten.

    Mehr dazu in einem späteren Kapitel.


    { ... }

    Block Klammern, die mit einem "Beginn" und "Ende" eines Abschnittes gleichgesetzt werden können.

    Sie finden unterschiedliche Verwendung.


    "Console.WriteLine("Hello World");"

    Dies ist eine 'Operation' zur formatierten Ausgabe auf der Konsole.


    Beachtet: Jede 'Anweisung' endet in C# mit einem Semikolon ";"

    Vergesst ihr diese, erhaltet ihr einen entsprechenden Fehler oder Hinweis der IDE.


    => Was hinter der Ausführung eines Programmes sich befindet / steckt (Compilieren, Interpretieren, etc. wird hier nicht behandelt.)



    Hier ein Beispiel zur Berechnung von dem Pythagoras:
    (Dieses Beispiel muss und kann an dieser Stelle noch nicht verstanden werden, zeigt jedoch eine Struktur, wie sie in einem Programm üblich ist.)


    Grundlegende Begriffe:


    Deklaration (Vereinbarung) z.B.:

    int i;

    int l, g, h;

    double f, a;


    Initialisierung (Wertzuweisung) z.B.:

    i = 6;

    f = 4.6;

    g = 7*i + h*h*(l-1);


    Bei einer Variable, wie "i" oder "g" in unserem Beispiel, kann der Name frei gewählt werden.

    Es gibt hier jedoch ein paar Ausnahmen, die sogenannten Schlüsselwörter.

    Eine Auflistung dieser findet ihr hier.

    Diese können als Variable nicht gewählt werden, da diese eine andere Bedeutung innerhalb C# besitzen.



    Mehr über Variablen in Lektion 2.

    Hallo Zusammen,


    nachdem viele RPG-Maker Nutzer mittlerweile auch Unity nutzen, war es an der Zeit für uns euch entsprechend mit Informationen zu versorgen.

    Unity als Engine bedient sich u.a. JavaScript als Programmiersprache, wie auch C#.

    Ich persönlich bevorzuge C#, wie wohl ein sehr großer Teil der Unity Gemeinde.


    Um in die Sprache entsprechend sich einfinden zu können werden in diesem Forum nach und nach Lektionen meinerseits erstellt.

    Natürlich dürfen auch von anderen Nutzern Lektionen beigesteuert werden, dann jedoch als separate Reihe oder als Vertiefung in einem bestimmten Teilgebiet.


    Je nach Zeit werden die neuen Lektionen hinzugefügt, daher bitte ich um Geduld, sollte es nicht regelmäßig sein.

    Ich persönliche studiere Informatik und versuche euch nach besten Wissen und Methoden C# etwas näher zu bringen.

    Sollten sich dennoch Fehler in meinen Lektionen schleichen, bin ich dankbar um die entsprechende Erwähnung entweder im Thread oder per PN.


    Der Kurs wird in erster Linie C# behandeln, nicht die Unity Scripting API .

    Unity selber wird in dem entsprechenden anderem Forum behandelt und ich wäre dankbar diese Fragen auch dort zu stellen, da es sonst gerade für Neulinge verwirrend sein kann.


    Dennoch empfehle ich jeden, der nicht mit C# vertraut oder allgemein mit Programiersprachen vertraut ist diesen "Kurs" / Lektionen von mir zu lesen.

    Dies wird zum späteren Verständnis enorm beitragen.


    Für meine C# Programme werde ich Visual Studio von Microsoft verwenden.

    Hier könnt auch ihr euch die kostenlose "Community" Edition herunterladen und auf Windows installieren.

    Für Mac und Linux gibt es entsprechende Alternativen, die ebenso in Ordnung sind.


    => Wer nicht am Erstellen von C# Programmen interessiert ist, sondern rein an Unity, dem sei gesagt, dass Unity eine eigene Entwicklungsumgebung (MonoDevelop) mitbringt.

    Mit welcher IDE ihr letztlich arbeitet bleibt euch überlassen. Solltet ihr dennoch Visual Studio verwenden, so installiert auch die Unity Komponente.

    Ich setze in den entsprechenden Lektionen eine korrekte Installation voraus und werde diese hier nicht separat behandeln.


    Nun noch ein Hinweis zu Fragen:

    Bitte nutzt hierfür im Besten Fall unsere Code-Funktion.

    Ihr könnt entsprechend auch C# als Programmiersprache auswählen, sodass der Code gut formatiert und uns präsentiert wird. Dies erleichtert beim Suchen von Fehlern die Arbeit enorm.

    Bitte beachtet auch, dass ich nicht als Support hier 'offiziell' tätig bin, sodass es ggf. auch dauern kann, bis eine Antwort kommt oder je nach Zeit auch erstmal keine.

    Im Besten Fall können nach und nach euch auch andere User aushelfen.


    Beispiel der Formatierung:

    Csharp
    1. using System; // Namensraum
    2. class hello
    3. {
    4.     /* jetzt die Definition des Hauptprogramms */
    5.     static void Main()
    6.     {
    7.         Console.WriteLine(“Hello World.“);
    8.     }
    9. }



    Nun viel Spaß mit den Lektionen!




    FAQ:


    - derzeit keine Fragen -