Objekte einsammeln und in GUI Texture anzeigen

Oft wird die Frage gestellt , wie man in Unity3D Objekte wie Healthpacks oder Magazine einsammeln und diese auf dem Bildschirm in einer GUI Texture als Grafik anzeigen lassen kann, was mich dazu veranlasst hat dieses Tutorial zu schreiben.

Dieses Tutorial teilt sich in drei Teile. Im ersten Teil geht es um das aufsammeln von Objekten und das setzen und hochzählen eines Counters. Der zweite Teil befasst sich mit der Anzeige der eingesammelten Objekte auf dem Bildschirm und in Teil3 erkläre ich wie man die Grafiken für die GUI Texture erstellen kann.

Teil1 – Objekte einsammeln

Für dieses Beispiel nehme ich ein Terrain, einen First Person Controller, eine GUI Texture und eine Sphere als MediPack-Objekt.

Erstellen eines Medipacks
Wir ziehen eine Sphere in die Szene (GameObject->Create Other->Sphere) und und weisen dieser anschließend eine AudioSource zu (Component->Audio->Audio Source). Im Inspector entfernen wir den Haken bei „Play on Awake“ in der der Audio Source. Im Sphere Collider setzen wir noch das Häkchen hinter „Is Trigger“. Geben Sie der Sphere noch einen aussagekräftigen Namen wie z.B. MediPack. Das war’s auch schon was unser Medipack angeht. Natürlich kann man auch jedes beliebige und aufwendig designtes 3DModel als MediPack benutzen aber darum geht es in diesem Tutorial ja nicht.

Jetzt benötigen wir ein Script welches erkennt das der FirstPerson Collider mit dem MediPack kollidiert ist. Das heißt, wenn der Charakter über das MediPack läuft dann soll er dieses aufheben.

Script – MediPackItemControl.js

var itemPickedUpSounds : AudioClip[];
var maxAllowedMediPacks: int = 0;
var showDebugMessage : boolean = false;
static var pickedUpMediPacks = 0;

//Objekt wurde vom Charakter eingesammelt
function OnTriggerEnter(hit : Collider)
{
  if(hit.gameObject.tag == "Player")
  {
    if(pickedUpMediPacks < maxAllowedMediPacks)
    {
      //Anzahl aufgesammelter Objekte um 1 erhöhen
      pickedUpMediPacks +=1;       

      //Ton abspielen wenn ein Objekt aufgenommen wird
      if(itemPickedUpSounds && itemPickedUpSounds.Length < 0 && !audio.isPlaying)
      {
        AudioSource.PlayClipAtPoint(itemPickedUpSounds[Random.Range(0,itemPickedUpSounds.Length)], transform.position, 1);
      }

      //aufgesammeltes Objekt zerstören
      Destroy(gameObject);

      //Anzeige der Anzahl eingesammelter Items
      if(showDebugMessage) Debug.Log(pickedUpMediPacks+" von max. "+maxAllowedMediPacks+" MediPacks eingesammelt.");
    }
    else if(showDebugMessage)
    {
      Debug.Log("Die maximal zulässige Anzahl an MediPacks wurde eingesammelt!");
    }
  }
}

Übergeben Sie dem Script die maximale Anzahl an MediPacks die eingesammelt werden können.
Die Funktion „OnTriggerEnter“ wird immer dann ausgeführt wenn ein Objekt mit einem Collider mit unserem Objekt (Trigger) kollidiert. Wenn ein Objekt mit dem MediPack kollidiert dann wird als erstes abgefragt ob das Objekt überhaupt unser Player war. (Dem Player müssen wir noch das tag „Player“ zuweisen). Danach wird abgefragt ob die maximale Anzahl an MediPacks bereits eingesammelt wurde. Sollte das nicht der Fall sein dann wird als erstes der Wert der eingesammelten MediPacks um 1 erhöht. Danach wird, sollte im Inspector mind. eine Sounddatei angegeben worden sein, ein Ton abgespielt und das MediPack wird zerstört. Wenn Sie im Inspector ein Häkchen hinter „Show Debug Message“ setzen dann können Sie sich die Anzahl der eingesammelten und der maximal einzusammelnden MediPacks ausgeben lassen. Wenn die maximale Anzahl an MediPacks eingesammelt wurde, dann werden so lange keine mehr eingesammelt bis sich die Anzahl verringert hat weil man z.B. ein MediPack verloren hat.

Um uns die weitere Arbeit zu erleichtern, erzeugen wir aus dem MediPack-Objekt ein Prefab. Dazu klicken Sie im Projekt-Fenster auf „Create“ und anschließend auf „Prefab“. Benennen Sie dieses Prefab um zu MediPack. Sie sehen dass das Symbol des Prefabs grau ist. Das bedeutet dass das Prefab noch leer ist. Ziehen Sie nun das MediPack-Objekt aus dem Hierarchy-Fenster auf das Prefab. Das Symbol des Prefabs sollte jetzt blau sein. Sie können  nun das MediPack-Objekt aus dem Hierarchy-Fenster entfernen. Wenn Sie jetzt MediPacks auf Ihrem Terrain verteilen wollen, dann ziehen Sie einfach das Prefab „MediPack“ in die Scene.

Die Medipacks sollten nun verschwinden wenn wir darüber laufen und auch die Debug Message sollte ausgegeben werden wenn Sie den entsprechenden Haken gesetzt haben.

Teil2 – Anzeige der MediPacks in einer GUI Texture

Um die eingesammelten MediPacks nun in einer GUI Texture auszugeben, klicken wir im Menü auf „GameObject->Create Other->GUI Texture“. Benennen Sie diese um in „GUI_MediPacks“!
Nun müssen wir als erstes die Position der Anzeige auf dem Bildschirm konfigurieren. Dazu ziehen wir als erstes unsere Grafik, die die komplette Anzahl an eingesammelten MediPacks zeigt (in meinem Fall sind das 5), aus dem Objektinspektor in das Texture Feld der GUI Texture. So können wir die Änderungen die wir an Position und Größe vornehmen direkt auf dem Bildschirm sehen. Geben Sie nun die Position der Texture auf dem Bildschirm an! X = 0.1 und Y = 0.1, zeigt die Texture z.B. im unteren, linken Eck an. X = 0.1 und Y = 0.9 würde die Texture im oberen, linken Eck anzeigen.
Öffnen Sie nun Pixel Inset und geben Sie die Breite und Höhe des zugewiesenen Images an.

Nun benötigen wir auch für diese Komponente ein Script.

Script – MediaPackItemGUI.js

var MediPackImage: Texture2D[];

function Update ()
{
  if(MediPackImage && MediPackImage.Length > 0)
  {
    if(MediPackItemControl.pickedUpMediPacks < MediPackImage.Length)
    {
      guiTexture.texture = MediPackImage[MediPackItemControl.pickedUpMediPacks];
    }
  }
}

Dieses Script wird im Inspector der GUI Texture zugewiesen.
Im Script wird abgefragt ob die Anzahl der eingesammelten MediPacks kleiner als die erlaubte maximale Anzahl ist. (Die max. Anzahl sollte die selbe Anzahl + 1 sein die im Script bei dem MediPack-Objekt gemacht wurde. Geben Sie unter „MediaPackImage“ hinter „Size“ die Anzahl der Bilder ein die angezeigt werden sollen. Das heißt, wenn der Charakter maximal 5 MediPacks einsammeln darf, dann sollten Sie eine 6 eingeben und anschließend Ihre 6 Images zuordnen. Wie Sie die Bilder erstellen können und worauf man achten sollte, können Sie unten lesen.

Einstellungen für die GUI Texture 

Teil3 – Grafiken für die MediPacks erstellen

Ich gehe in diesem Beispiel davon aus dass der Charakter 5 MediPacks einsammeln kann, was heißt dass auch 5 Medipacks angezeigt werden müssen wenn er diese eingesammelt hat.

Ich erstelle in einem Programm wie Photoshop eine Grafik mit transparentem Hintergrund in der Größe 200 x 40 px. Um die 5 Grafiken eines MediPacks auch richtig ausrichten zu können, erstelle ich eine neue Ebene und ziehe mit dem Auswahlwerkzeug eine Auswahl in der Größe 40 x 40 px. Diese Auswahl fülle ich mit einer beliebigen Farbe. Ich verschiebe die Auswahl 80 px nach rechts und fülle diese erneut mit einer Farbe. Dies mache ich insgesamt 3 mal, so das ich abwechselnd ein farbiges und ein transparentes Feld habe. Nun suche ich mir eine geeignete Grafik die in das 40 x 40 px große Feld passt und setze diese in einer neuen Ebene in das erste Feld. Diese Ebene dupliziere ich nun und verschiebe diese um 40 px nach rechts. Das mache ich jetzt insgesamt 5 mal so das ich in jedem Feld eine Grafik habe wovon jede in einer eigenen Ebene liegt. Nun blende ich alle Ebenen aus und speichere die leere Grafik unter „MediPack0“. Danach mache ich die erste Grafik sichtbar und speichere erneut aber diesmal unter dem Namen „MediPack1“. Das wiederhole ich nun insgesamt 6 mal so dass ich eine leere und in jedem weiteren Bild 1 Grafik mehr habe. Also jede Grafik hat die selbe Größe, auch wenn nur 1 oder gar kein MediPack darauf abgebildet sind.

So ich denke ich habe das Thema einigermaßen verständlich erklärt und hoffe Ihr könnt etwas damit anfangen. Für Anregungen, Vorschläge oder bei Fragen stehe ich jederzeit gern zur Verfügung.

Über Enrico S.

Programmierer, Webdesigner, Grafiker, Blogger, Screencaster, Arduino- und eMobility Enthusiast.

Kommentare geschlossen.