Jump to content
Unity Insider Forum

[Gelöst]Tags vs. Layers


Jomnitech

Recommended Posts

Hallo Zusammen

Ich möchte gerne wissen ob das Verwenden von Tags oder Layers besser ist, in bezug auf Performance oder ev. noch andere Gründe.

Es geht mir Hauptsächlich um die Abfage von Trigger Events, also OnTriggerEnter/Exit/Stay. Mit beiden kann ich beides machen, ich frage mich nur was besser ist?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Weder, noch. Tags sind mMn komplett bescheuert, ich benutze sie niemals. Layer sind begrenzt, da sie sich in einem Integer als Bitmaske darstellen lassen müssen und sollten daher nur da verwendet werden, wo Unity es haben will: Kollisionsfilter der Physik-Engine... (und leider auch PostProcessing-Stack).

Wenn du für jeden anderen Fall einen Weg suchst, Objekte zu identifizieren, klatsche eine leere Komponente drauf und checke mit GetComponent statt CompareTag. Da hast du Compile Time Safety und alle Boni, die das mit sich bringt.

"Das kann doch aber nicht gut für die Performance sein", schallte es aus einer dunklen Ecke... Aber obwohl ich sauberen Code jederzeit minimalen Performanceverbesserungen vorziehe, ahbe ich das mal gebenchmarkt... benchgemarkt... gemessen. GetComponent ist sogar schneller als CompareTag. Kleine Einbußen hat man daher höchstens bei der Deserialisierung (Instanziieren von Objekten, inkl. Szenen laden).

Davon mal abgesehen stellte sich heraus, dass man eigentlich niemals ein Objekt identifizieren will, um dann nicht mit einer Komponente zu arbeiten, die grundsätzlich immer da ist, wenn ein bestimmter Tag vorliegt. Heißt: Die leere Komponente bleibt in der Regel nicht lange leer.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Sascha

Vielen Dank für deine Antwort

vor 2 Stunden schrieb Sascha:

dass man eigentlich niemals ein Objekt identifizieren will, um dann nicht mit einer Komponente zu arbeiten

Das ist richtig, man will ja etwas tun mit dem was man triggert. Hätte aber nie gedacht dass das holen der Komponente und Variable abfragen was es ist, immer noch besser ist als Tags zu verwenden, da bin ich jetzt doch sehr überrascht. Werde ich aber sicher so umsetzen, macht das Ganze ja auch einiges leichter wenn z.B. in der Enemy Component auch automatisch als Enemy zurückgegeben wird, statt immer das "oh nein jetzt habe ich vergessen den Tag auch auf Enemy zu setzen".

Ich habe derzeit begrenzt mit Tags gearbeitet und häufig mit Layers. Meine logik war dass wenn im Layer nur die dinge sind die miteinander interagieren können, die es auch sollen, braucht es ja weniger Abfragen alls wie wenn alles in einem Layer ist und alles gegenseitig abgefragt werden muss ob es den triggert oder nicht.
Ist dem denn so? Oder macht das für Unity praktisch keinen Unterschied?

Momentan habe ich 30 verschiedene Layers, ich stell mir jetzt mal vor dass du dir dabei an den Kopf fasst....

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 17 Minuten schrieb Jomnitech:

Hätte aber nie gedacht dass das holen der Komponente und Variable abfragen was es ist, immer noch besser ist als Tags zu verwenden, da bin ich jetzt doch sehr überrascht.

Und das sogar doppelt. GetComponent ist schneller (und eben string-los und damit sauberer) als CompareTag. Aber selbst, wenn das nicht so wäre, vergleiche mal die CompareTag-Variante

private void OnTriggerEnter(Collider other)
{
  if (other.CompareTag("Some Tag"))
  {
    var componentOfInterest = other.GetComponent<ComponentOfInterest>();
    if (componentOfInterest)
    {
      componentOfInterest.DoStuff();
    }
  }
}

mit der Variante ohne CompareTag:

private void OnTriggerEnter(Collider other)
{
  var componentOfInterest = other.GetComponent<ComponentOfInterest>();
  if (componentOfInterest)
  {
    componentOfInterest.DoStuff();
  }
}

Ist einfach eine if-Abfrage weniger, es sei denn, du nimmst oben die Abfrage raus und verlässt dich darauf, dass jedes Objekt mit dem Tag auch diese Komponente hat. Ist irgendwie albern, oder? :)

vor 20 Minuten schrieb Jomnitech:

Ich habe derzeit begrenzt mit Tags gearbeitet und häufig mit Layers. Meine logik war dass wenn im Layer nur die dinge sind die miteinander interagieren können, die es auch sollen, braucht es ja weniger Abfragen alls wie wenn alles in einem Layer ist und alles gegenseitig abgefragt werden muss ob es den triggert oder nicht.
Ist dem denn so? Oder macht das für Unity praktisch keinen Unterschied? 

Wenn es um die Kollisionsmatrix oder Raycasts geht, dann solltest du bei Layern bleiben. Ich gehe sehr stark davon aus, dass tatsächlich nur Kollisionschecks gemacht werden mit Objekten, die auf den richtigen Layern sind. Und mit "sehr" meine ich "so sicher wie man sich nur sein kann, ohne den Source Code gesehen zu haben".

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Sascha

vor 26 Minuten schrieb Sascha:

private void OnTriggerEnter(Collider other)
{
  if (other.CompareTag("Some Tag"))
  {
    var componentOfInterest = other.GetComponent<ComponentOfInterest>();
    if (componentOfInterest)
    {
      componentOfInterest.DoStuff();
    }
  }
}

mit der Variante ohne CompareTag:


private void OnTriggerEnter(Collider other)
{
  var componentOfInterest = other.GetComponent<ComponentOfInterest>();
  if (componentOfInterest)
  {
    componentOfInterest.DoStuff();
  }
}

So vor Augen geführt macht es Sinn:D

vor 26 Minuten schrieb Sascha:

Wenn es um die Kollisionsmatrix oder Raycasts geht, dann solltest du bei Layern bleiben.

Jap, bei Raycasts bleibt mir ja fast nichts anderes übrig. Ich will ja nicht das der Raycast mit etwas kollidiert was er nicht soll und dann nicht weiter geht.

vor 26 Minuten schrieb Sascha:

Ich gehe sehr stark davon aus, dass tatsächlich nur Kollisionschecks gemacht werden mit Objekten, die auf den richtigen Layern sind. Und mit "sehr" meine ich "so sicher wie man sich nur sein kann, ohne den Source Code gesehen zu haben".

Da muss ich jetzt doch nochmals nachhaken. Macht es jetzt Sinn alles in verschiedene Layer zu packen was miteinander interagieren kann (Stichwort 30Layers), oder soll ich gewisse Layers zusammenpacken und über die Komponente steuern?
Vielleicht als Beispiel:
-Die Waffe meines Spielers soll nur mit Gengern interagiern. +1Layer
-Die Waffe meines Gegner interagiert mit Gegnern und dem Spieler. +1Layer

Macht es nun Sinn, diese zusammen zu fassen und über die Komponente zu steuern?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Naja, wenn's um Kollisionen geht, dann ist das mit Layern schon sinnvoll. Irgendwo muss man seine Grenze ziehen. Natürlich könnte man jetzt versuchen, alles über Layer zu machen. Theoretisch gibt's performancemäßige Vorteilchen, wenn du Trigger, in denen nur der Player etwas auslösen soll, auch nur mit dem Player kollidieren lässt. Aber irgendwann wird's auch einfach albern und unübersichtlich. Bei Performance gilt immer: Mach dich erst krumm, wenn's zum Problem wird.

Ich bevorzuge es, wenn ich eine einfache Änderung vornehme, wenn ich eine einfache Änderung haben will. Wenn ich ein neues System baue und dann doch Trigger sein sollen,  wo Player und Gegner drin etwas auslösen, will ich nicht erstmal die gesamte Kollisionsmatrix überarbeiten. Physik-Engines haben sowieso Beschleunigungsstrukturen und Optimierungen des Todes - da geht dem Rechner erst sehr spät die Puste aus.

Da sind sind Bedenken wie "Ich will einen Raycast haben der durch Dinge durch kann ohne dafür mein Erstgeborenes zu verkaufen" schon viel besser.

Also... lange Rede, kurzer Sinn: Guter Code und sauberes Projekt > Performance, solange bis die Performance ein Problem wird. Und Layer managen ist nicht so ganz geil, also würd ich's vermeiden, solange dein Code nicht drunter leidet, wie er's beim Raycast tun würde.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...