Jump to content
Unity Insider Forum

Automatisiertes Finden von Komponenten


Sascha

Recommended Posts

Moinsen!

 

Ihr kennt doch bestimmt solchen Code:

public class Example : MonoBehaviour
{
private Light l;
public Collider c;
public Transform target;

void Awake()
{
	l = GetComponent<Light>();
	c = GetComponent<Collider>();
}
}

 

Ich bastele gerade daran, wie das etwas besser aussehen könnte.

Aktuell habe ich umgesetzt:

public class Example : MonoBehaviour
{
[AutoGet]
private Light l;
[AutoGet]
public Collider c;
public Transform target;

void Awake()
{
	this.AutoGetFields();
}
}

 

Leider scheint es ohne den expliziten Aufruf in Awake() nicht zu gehen, es sei denn, man erbt nicht von MonoBehaviour, sondern von einer anderen Klasse, die ich bereitstellen würde. Das fände ich nicht so prickelnd.

 

Alternative Idee:

public class Example : MonoBehaviour
{
private Light l;
public Collider c;
public Transform target;

void Awake()
{
	this.AutoGet(l);
	this.AutoGet(c);
}
}

 

Was haltet ihr von den beiden Varianten? Bringt das in euren Augen überhaupt einen Mehrwert gegenüber manuellem GetComponent?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was haltet ihr von den beiden Varianten? Bringt das in euren Augen überhaupt einen Mehrwert gegenüber manuellem GetComponent?

 

Die Idee finde ich cool. Wenn würde ich nur die erste Variante nehmen, da diese meiner Ansicht nach auch die Lesbarkeit des Codes erhöht. Allerdings würde ich das wahrscheinlich nicht verwenden, da ich GetComponent durchaus auch nur im Methoden-Scope verwende, um meine Klasse nicht mit zu vielen Member-Variablen zu überhäufen. Ich finde das ist immer eine Abwägung zwischen Performance und Lesbarkeit: Solange ich GetComponent nicht in einer Schleife in Update habe (was aber sowieso praktisch nie sein muss), sehe ich da kaum ein Problem.

 

Ganz spannend finde ich das Beispiel mit "public Collider" - den könnte man ja auch über den Editor zuweisen. Da fände ich die erste Variante dann doch spannend, wenn sie mir prüft, ob die Variable nicht bereits zugewiesen ist (das ist zwar auch trivial, aber zwei Zeilen bzw. mit Klammerung drei Zeilen sind einfach doppelt bzw. dreifach so viel wie eine Zeile - das läppert sich dann irgendwann ;-) ).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Allerdings würde ich das wahrscheinlich nicht verwenden, da ich GetComponent durchaus auch nur im Methoden-Scope verwende, um meine Klasse nicht mit zu vielen Member-Variablen zu überhäufen.

 

Wenn ich mehr als 3-4 Komponenten-Member in einem MonoBehaviour habe, schlagen bei mir immer sofort die Alarmglocken :)

 

Die Zweite Variante könnte dann immer noch deinen Code verkürzen, da der der generische Parameter nicht mehr explizit gemacht, sondern aus dem Feldtyp gezogen wird. Dafür passieren Reflection-Dinge, und man fragt sich, ob man das will :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mich würde an Variante1 der Schreibaufwand für die Atribute und das nötige Reflection stören.

 

An Variante 2 stört mich dann wiederum dass ich AutoGet auch gegen GetComponent austauschen könnte und dadurch sogar noch Lesbarkeit gewinnen würde,

 

Von der Lesbarkeit gewinnt daher Punkt 1, benutzen würde ich dann aber eher Variante2 oder eben gleich GetComponent.

 

Ich würde auch wenn ich mir so ein System zulege wünschen dass die Komponenten auf Wunsch erzeugt werden können und ich diese auch bei Bedarf automatisiert neu holen kann. Was dann wieder in Richtung von Variante1 führen würde.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn ich mehr als 3-4 Komponenten-Member in einem MonoBehaviour habe, schlagen bei mir immer sofort die Alarmglocken :)

 

Das ist natürlich ein guter Punkt.

 

Die Zweite Variante könnte dann immer noch deinen Code verkürzen, da der der generische Parameter nicht mehr explizit gemacht, sondern aus dem Feldtyp gezogen wird. Dafür passieren Reflection-Dinge, und man fragt sich, ob man das will :)

 

Ich mag's lieber explizit - da muss man beim Lesen des Code weniger nachdenken und kann sich auf die wesentlichen Dinge konzentrieren ;-)

Link zu diesem Kommentar
Auf anderen Seiten teilen

"GetC" + <Tab> "<Light>();" -> "GetComponent<Light>();"

 

Bringt kaum Mehrwert ;)

 

Was evtl sinnvoll wäre wäre ein system was das macht was du da schreibst und dafür sorgt dass Änderungen am Komponentenstatus wiedergespiegelt werden aka, wenn die Komponente nicht da ist, sie a) selbst erstellen oder B) erneut mit getComponent abfragen bis sie wie wieder da ist.

 

Aber auch da hält sich der praktische Nutzen arg in Grenzen.

 

Sowas wie

 

private Light light = GetComponent<Light>();

 

wäre schon ne feine Sache, aber das verdammte this gibts da ja noch nicht ;)

 

private Light light = Components.GetComponent<Light>(self => self.light);

 

Wäre wohl noch mit Expressiontrees möglich, aber ob das sinnvoll ist ist wieder eine andere Sache, aber es macht ein spannendes Lernprojekt ;)

 

Einfacher aber wieder mehr Schreibarbeit wäre sowas:

 

private CachedComponent<Light> light = CachedComponent<Light>();
...
light.Value.enabled = true;
...
((Light)light).enabled = true;

Link zu diesem Kommentar
Auf anderen Seiten teilen

Join the conversation

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

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

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

Lädt...
×
×
  • Neu erstellen...