Jump to content
Unity Insider Forum

Score erstellen


Chris90

Recommended Posts

Hallo Leute

 Ich bin jetzt dran mit UFPS ein spiel zu erstellen. Das klappt recht gut. Ich habe jetzt ein Player mit Waffen und Zauber und ein paar Enemy's.

Jetzt bräuchte ich einen Punkte Zähler. Der sich pro getöteten Feind erhöht.

Gibt es ein Asset das ich verwenden könnte das leicht einzufügen ist ohne das ich viel machen muss.

Oder gibt es sonst einen weg der nicht zu kompliziert ist?

LG

Chris

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Da gibt es wieder mehrere Möglichkeiten, hier eine kurzes Rezept:
- ein Canvas erstellen und ein GUI-Text hineinpacken
- ein Skript mit einem Zähler erstellen, GUI dem Skript zuweisen
- dieses Skript einem GameObject in der Scene zuweisen (und zum Beispiel. "ScoreManager" benennen)
- wenn ein Gegner getötet wird eine Methode (z.b. IncreasePoints()) dieses Skriptes aufrufen (könnte man auch als statische Methode dieser Klasse umsetzen, dann benötigt man keine Referenz auf das Skript)

Hier ein Unity Tutorial aus einem Space Shooter, welches auch einen Punktzähler umsetzt:
https://unity3d.com/de/learn/tutorials/projects/space-shooter-tutorial/counting-points-and-displaying-score

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke für die Antwort. Bin mir aber nicht sicher wie ich das Script auf meinem Enemy genau ändern kann. Es ist ja nicht das gleiche wie im Video. Gibt es eine Möglichkeit das ich meinem Enemy ein neues Script hinzufügen kann? Das es der Punktzähler erkennt. Das ich dann das Script auf alles was Punkte geben soll drauf Packen kann und im Inspector dann einstellen kann wie viele Punkte es bei der Zerstörung geben soll.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das geht auch, aber wenn der Enemy zerstört wird, dann werden auch sämtliche Skripte die an dem Objekt hängen zerstört.
Du könntest es aber über 2 Skripte machen, ein Skript hängst du an jedes Objekt das Punkte geben soll und du verwendest dann in diesem Skript diese Methode:
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnDestroy.html

Dann brauchst du noch eine 2. Klasse, die die Punkte speichert und hochzählt.

Hier das Skript zum hinzufügen:

using UnityEngine;
using System.Collections;

public class ScorePoints : MonoBehaviour {

    public int points = 1;

    void OnDestroy()
      {
         GameScore.AddScore(points);
      }
}

Und hier die Klasse die die Punkte aufsummiert:

using UnityEngine;
using System.Collections;

static class GameScore
{

    private static int sumScorePoints = 0;

    public static void ClearScore()
    {
        sumScorePoints = 0;
    }

    public static void AddScore(int points)
    {
        sumScorePoints += points;
        Debug.Log("Aktuelle Punkte: " + sumScorePoints);
    }

    public static int GetScore()
    {
        return sumScorePoints;
    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo

Danke für die Antwort. Ich habe die 3 Scripts einmal in mein Projekt eingefügt. Aber ich bekomm Errors.

Ich kann die Scripts nicht bei dem Enemy Hinzufügen.

Und auf was für ein Objekt gehört das Script zum Summieren. auf ein Gameobjekt? oder auf ein gui Text?

könntest du mir kurz aufschreiben wie das richtig angewendet wird?

 

LG Chris

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es sind nur 2 Skripts. Die Klasse "GameScore" wird nur im Projektfolder abgelegt. Ich habe die Klasse "GameScore" noch einmal erweitert, nimm den Code noch einmal von oben.
Die Klasse "ScorePoints" hängst du an den Feind. Hier kannst du dann noch die Punkte einstellen, die bei einem "Zerstören" über die Klasse "GameScore" aufaddiert wird.

Die Punkte kannst du nun in einem beliebigen anderem Skript abfragen über:

int currentScore = GameScore.GetScore();

Die Punkte zurücksetzen kannst du über:

GameScore.ClearScore();


 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hey ZerOCool

Danke. Jetzt zählt Unity schon mal mit. Wir sind also auf dem richtigen weg :-)

Wenn ich das spielt wieder beende steht unten eingeblendet. "Aktuelle Punkte 5"

Wie bekomme ich das jetzt hin das es im Game ein sichtbaren Zähler hat?

Muss ich auch so ein UI Text erstellen wie im Tutorial?

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, genau, du musst ein Canvas erstellen und ein UI Text hinzufügen. Diesem UI Text übergibst du einem Skript und rufst GameScore:GetScore() auf:

public class ScoreUI : MonoBehaviour {
    
    public Text countText;

    void Update ()
    {
        countText.text = GameScore.GetScore();
    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Au weia, bitte nicht in Update immer wieder dieselbe Zahl anzeigen lassen :(

Dann lieber GameScore nicht-statisch machen und von MonoBehavoiur erben lassen. Und dann direkt auf den UI-Text draufpacken oder so, dürfte noch am einfachsten sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe jetzt ein  Canvas erstellt und ein UI Text. Es passiert noch nichts. Was muss ich mit dem Script machen das du zuletzt gepostet hast ?

"Helishcoffe" Es soll einfach nur Punkte zählen. Und bei der nächsten Runde wieder von vorne starten. Es muss keine weiteren Funktionen beinhalten :-)

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 9 Stunden schrieb Zer0Cool:

Ich wollte es nicht zu kompliziert machen (normal würde ich die GUI auch nur aktualisieren wenn sich der Wert auch ändert), aber ich glaub diese kleine Zuweisung je Frame tut nicht weh.

Ich weiß, und ich sage nach Möglichkeit auch immer nichts. Aber du weißt bestimmt, wie Code von Menschen aussieht, die so etwas lernen und dann ein, zwei Jahre weiter in eine solche Richtung gehen beim Lernen.

Hier ist die GameScore-Klasse umgeschrieben:

using UnityEngine;
using UnityEngine.UI;

public class GameScore : MonoBehaviour
{
  private static int sumScorePoints = 0;
  private static Text display;

  void Awake()
  {
    display = GetComponent<Text>();
  }
  
  public static void ClearScore()
  {
    sumScorePoints = 0;
    UpdateDisplay();
  }

  public static void AddScore(int points)
  {
    sumScorePoints += points;
    UpdateDisplay();
  }

  public static int GetScore()
  {
    return sumScorePoints;
  }
  
  private static void UpdateDisplay()
  {
    display.text = sumScorePoints + " Punkte";
  }
}

Völlig ohne die neue Klasse ScoreUI kannst du diese Version auf dein Text-GameObject im Canvas ziehen. Wenn du es nicht tust, funktioniert das Punktezählen immer noch, aber sobald du es auf den Text ziehst, zeigt der Text die Punktzahl richtig an.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe die Klasse noch einmal leicht angepasst, aber das war nicht das Problem.

using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(Text))]
public class GameScore : MonoBehaviour
{
    private static int sumScorePoints = 0;
    private static Text display;

    void Awake()
    {
        display = GetComponent<Text>();
    }

    public static void ClearScore()
    {
        sumScorePoints = 0;
        UpdateDisplay();
    }

    public static void AddScore(int points)
    {
        sumScorePoints += points;
        UpdateDisplay();
    }

    public static int GetScore()
    {
        return sumScorePoints;
    }

    private static void UpdateDisplay()
    {
        if (display!=null) display.text = sumScorePoints + " Punkte";
        Debug.Log("Aktuelle Punkte: " + sumScorePoints);  
    }
}


Du musst die Klasse "GameScore" direkt auf dein UI Text ziehen.

Es sollte jeweils die Meldung (du kannst diese Debugausgabe später wieder entfernen):
"Aktuelle Punkte: xx" .. kommen, sobald ein Objekt zerstört wurde.

Und es zählt nur dann hoch, wenn das Objekt auch wirklich zerstört wird, d.h. das Objekt muss in der aktuellen Szene verschwinden und nicht etwa nur deaktiviert werden oder ähnliches!

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 28 Minuten schrieb Zer0Cool:

Und es zählt nur dann hoch, wenn das Objekt auch wirklich zerstört wird, d.h. das Objekt muss in der aktuellen Szene verschwinden und nicht etwa nur deaktiviert werden oder ähnliches!

Ich glaube, das ist das Problem.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das stimmt. Meine Enemys und Kisten verschwinden nicht. Sie werden nur deaktiviert :-( ich weis aber nicht wie ich das ändern kann.

Der Zähler funktioniert aber. die Konsole zählt mit. Ich hab jetzt noch ein zweiten Enemy hinzugefügt und wenn ich es stop sehe ich wie viele Punkte ich habe in der Console.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dann musst du jetzt schauen, wie du das machen willst. Wenn du es für richtig hältst, dass deine Gegner deaktiviert werden, ginge OnDisable statt OnDestroy. Dann dürfen die Gegner natürlich nicht zu einer anderen Gelegenheit deaktiviert werden, sonst gibt's dafür auch Punkte. Alternativ kann du da, wo du den Gegner deaktivierst einen zusätzlichen Methodenaufruf hinzufügen. Statt

void OnDestroy()

schreibst du dann

public void Kill()

und unter

gegner.enabled = false;

(oder wie auch immer das bei dir aussieht) kommt dann

gegner.Kill();

"gegner" muss hierbei dann eine Referenz auf die ScorePoints-Komponente haben - oder du integrierst ScorePoints in eine andere Klasse, die auf jedem Gegner sitzt, und referenzierst hier die.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ändern sollst du an der Stelle nichts. Aber irgendwo in deinem Code muss ja genau das passieren:

vor 2 Stunden schrieb Chris90:

Meine Enemys und Kisten verschwinden nicht. Sie werden nur deaktiviert

Und an der Stelle in deinem Code, bei der das passiert, musst du ansetzen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Lass erst einmal alles so wie es war und tausche nur die OnDestroy() gegen die OnDisable() aus (wie Sascha schon gesagt hatte) mit etwas Glück passiert dann das was du wolltest, mit Pech wird es zu oft aufgerufen, dann musst du an deinen Gegnercode ran ... Hier die Änderung:

using UnityEngine;
using System.Collections;

public class ScorePoints : MonoBehaviour {

    public int points = 1;

    void OnDisable()
      {
         GameScore.AddScore(points);
      }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dann hatte ich glück. Es zählt jetzt im Game. Ich musste aber noch das Damage Handler Script von UFPS auf den Enemy Hinzufügen.

Jetzt ist noch ein Fehler aufgetreten. ( also den hatte ich eigentlich vorher schon)

Kurz Erklärung fürs Verständnis wie mein Problem entstanden ist:

Ich benutze Emerald Ai für die Enemys. Dafür musste ich bei UFPS folgendes ändern. http://emerald-animal-ai.wikia.com/wiki/Tutorials#Implement_UFPS_with_Emerald_AI

Somit benutzen die Enemys die Scripts von Emerald Ai und mein Player kann die Scripts von UFPS verwenden.

Ich musste dann nur noch bei  Bullets von Damage Handler auf Unity message umstellen. Somit konnte ich die Enemys angreifen.

Das hat eigentlich sehr gut funktioniert.

bis:

Ich eine Kiste mit einem Damage Handler Scipt von UFPS angreife dann kommt diese Warnung.

Warning (MachinegunBullet (vp_FXBullet)) Target object has a vp_DamageHandler. When damaging it with DamageMode: 'UnityMessage' or 'Both', you probably want to change 'DamageMethodName' to something other than 'Damage', or too much damage might be applied.

Das selbe habe ich jetzt auch beim Enemy weil ich noch das Damage Handler Script hinzugefügt habe. Mit der gleichen Hp wie das Emeralde Ai Script.

Dafür zählt es jetzt :-)

haha sorry ich hab echt nicht viel Ahnung aber ihr seid der Hammer. Es Zählt ja schon mal hoch. Bin noch Positiv eingestellt das wir das hin bekommen:-)

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...