Jump to content
Unity Insider Forum

Sascha

Administrators
  • Content Count

    11,545
  • Joined

  • Last visited

  • Days Won

    567

Sascha last won the day on December 4

Sascha had the most liked content!

Community Reputation

2,368 Excellent

6 Followers

About Sascha

  • Rank
    Community Manager
  • Birthday 08/13/1990

Contact Methods

  • Website URL
    http://www.indiepowered.net

Profile Information

  • Gender
    Male
  • Location
    Hamburg
  • Interests
    Programmierung

Recent Profile Visitors

42,054 profile views
  1. Joa... hübsch wäre halt was anderes. Insbesondere, wenn du dann 98% zu 2% machen willst, dann fügst du erstmal 50 Dinger in die Liste ein.
  2. Wenn du genau ein Objekt aus einer Menge auswählen willst, dann ist es auf jeden Fall ein Warnzeichen, wenn du mehrere Male würfelst. Sagen wir, du hast nur zwei Ergebnisse: Eins mit einer 60%-Chance und eins mit 40%. Damit ist die Chance, dass du bei beiden "daneben würfelst", 0.4 * 0.6 = 0.24. Du hast also eine 24%-Chance, keines von beiden auszuwählen. Besser ist es, ein einzelnes Mal zu würfeln und dann zu schauen, was das Ergebnis des Wurfes bedeutet. Dazu braucht man die Summe aller Gewichtungen (im Beispiel 0.4 + 0.6 = 1, aber muss ja nicht immer auf 1 summieren) und skaliert das Ergebnis um diesen Wert. Es wäre eine Elegante Methode, ein Struct zu haben, das das mögliche Objekt und dessen Gewichtung hat: public struct RandomResult { public int result; public float weight; } Dann kriegt man eine Menge Instanzen dieses Structs und bildet die Summe: public int PickRandomly(RandomResult[] results) { var sumOfAllWeights = results.Select(result => result.weight).Sum(); Anschließend kannst du würfeln über deine Ergebnisse iterieren und schauen, "wie weit" dein Zufallsergebnis kommt: var roll = Random.value * sumOfAllWeights; for (var result in results) { if (roll < result.weight) { return result.result; } else { roll -= result.weight; } }
  3. Ich hab da gestern auch drüber nachgedacht... ist kein einfaches Thema. Zum einen würde ich @devandart Recht geben - Regionen und andere Features zum Zerlegen großer Klassen sind immer ein Alarmsignal. Andererseits entwickelt man ja nicht nur die Klasse selbst, sondern auch ihr Interface. Wenn ich eine Klasse schreibe, die vier Methoden mit jeweils drei Überladungen anbietet, dann ist das kein zu großes Interface, und man kann sich sicher einen Haufen Fälle vorstellen, in denen man eine Solche überschaubare Menge an Methoden unter einem Klassennamen zusammenfassen will. Ich denke da zum Beispiel an statische Klassen als semantisch gebündelte Methodensammlung, wie Mathf. Die Menge an Zeilen, die dabei entstehen kann, geht aber schnell über ein schönes Maß hinaus. Jetzt müsste man sich entscheiden, ob man die Funktionalität in mehrere Klassen aufteilt, was das semantisch sinnvolle Interface zerstückelt, oder eben die Klasse mit vielen Zeilen behält. Und wenn man sich für letzteres entscheidet, sind Regionen schon ganz praktisch. Dass man die nicht einfach überall reinknallen sollte, sondern sich jede Benutzung gründlich überlegen sollte (wie bei Röntgen-Untersuchungen), das können wir, glaube ich, auf jeden Fall so stehen lassen.
  4. Warum willst du unbedingt mit dem Kopf durch die Wand? Du stehst halt gerade vor einem Haufen Holz und willst einen Tisch bauen, und jetzt fragst du mich, wie du die Nägel mit der Hand reinschlagen kannst, anstatt dir von mir einen Hammer geben zu lassen. Vertrau mir bitte einfach, dass dein aktueller Weg dir mehr Problem als Lösung sein wird. Erzähl mir doch mal lieber, was das für ein Tisch werden soll.
  5. Sascha

    Character Flip

    Wie gesagt, ist einfach Quatsch. CheatEngine tut Dinge im Ram. Ram und Update/FixedUpdate hat exakt nichts miteinander zu tun. Und wenn du Performanceunterschiede siehst, wenn etwas von Update nach FixedUpdate kommt, dann liegt es nicht an FixedUpdate, sondern an deinem Fixed Timestep oder an deinem Code selbst.
  6. Ich wette, das stimmt nicht wirklich. Ein Objekt, das einen Wert eines beliebigen Typs speichern kann, ist bei typstarken Sprachen grundsätzlich etwas falsches. Was auch immer du eigentlich zu erreichen versuchst, es geht mit Sicherheit auch anders. Darum einfach mal gefragt: Was willst du mit diesem ScriptableObject erreichen?
  7. MaZy hat Recht: Schau dir halt Grundlagen an. Gucke Intros auf Youtube, kaufe dir ein Buch... Du musst halt ein paar Sachen erstmal lernen bevor du anfängst, solche Fragen zu stellen. Ansonsten sind unsere Antworten 1:1 das, was du in Anfängerressourcen hättest lernen können.
  8. Das G von GameObject klein. Nächstes Mal aber bitte die ganze Fehlermeldung posten und deinen Code mint dem <>-Knopf richtig formattieren.
  9. Sascha

    Character Flip

    Sorry was? Das ist völliger Humbug. Also alles, bis auf Bewegungscode in FixedUpdate. Aber die Begründung ist Quatsch, sorry.
  10. Uff. Das sieht echt nicht nach etwas aus, das man machen möchte. Ich meine... Du gibst mit sowas sämtliche Vorteile einer typstarken Sprache auf.
  11. Was macht sie denn, was ein Struct nicht kann? 🤔 Kommt ein bisschen darauf an. Die simpelste Variante ist: Neue Liste erstellen, durch die alte Liste durchgehen und Kopien aller Objekte in die neue Liste einfügen. Dafür würde sich eine "Clone()"-Methode in deiner Klasse anbieten. Allerdings bist du dann im Zweifelsfall auch nur eine Ebene "deep". Objekte, die wiederum von deinen kopierten Objekten referenziert werden, werden nur dann kopiert, wenn du das explizit implementierst. Nicht wirklich. Und da C# typstark ist (und das ist auch gut so), willst du das auch nicht.
  12. Wenn "Variable" eine Klasse ist, dann hast du hier wieder dasselbe Problem. Mit new List<T>(originalList) erstellst du eine so genannte "Flat Copy". Du hast also eine neue Liste, die aber wieder dieselben Objekte referenziert. Du kannst jetzt überlegen, ob du "Variable" zu einem Struct machst (dann ist die Referenzsemantik weg) oder du baust eine Deep Copy, wobei nicht nur die Liste Kopiert wird, sondern auch die Objekte, die sie referenziert. Dazu solltest du noch deine base_var private machen, damit da kein Script dran rumpfuschen kann. Mit einem [SerializeField] darüber wird das Ding trotzdem im Editor angezeigt und serialisiert.
  13. OnAfterDeserialize wird (wenn die Klasse auch das Interface ISerializationCallbackReceiver implementiert) direkt nach dem Deserialisieren aufgerufen, also dem Schritt, in dem Unity die ganzen Sachen lädt, die im Editor eingestellt wurden. Der Ansatz ist daher nicht schlecht, aber er wird hier vergessen, dass List<T> ein Objekt ist und kein Struct, also Referenzsemantik hat. Die letzte Zeile kopiert die Referenz auf die geladene Liste in die zweite Variable, und beide Variablen zeigen danach auf dieselbe Liste (und nicht auf die gleiche). Wenn du dann an dieser Liste etwas änderst (und dabei ist es egal über welche Variable), dann gelten diese Änderungen auch für die serialisierte Variable. Bei Komponenten ist das egal, weil die sowieso zurückgesetzt werden. Ich nehme aber mal an, hier geht's um ScriptableObjects. Wenn du da verhindern willst, dass Laufzeit-Änderungen persistent sind, dann musst du eine Kopie der Liste erstellen: var = new List<Variable>(base_var);
  14. Es geht hier nicht um Performance. Lies dir den Artikel am besten einfach mal durch
  15. Hier geht's weiter. Mal sehen, was noch kommt ¯\_(ツ)_/¯
×
×
  • Create New...