Jump to content
Unity Insider Forum

Sascha

Administrators
  • Content count

    11,064
  • Joined

  • Last visited

  • Days Won

    500

Everything posted by Sascha

  1. Sascha

    scene view in editor window anzeigen

    Ach, du willst einfach eine Asset-Vorschau haben? Da dürfte dir das hier helfen: https://docs.unity3d.com/ScriptReference/AssetPreview.html
  2. Sascha

    scene view in editor window anzeigen

    Dazu gibt's schon Versuche von Unity, wenn auch für einen anderen Kontext. Geht leider alles nicht so einfach, weil das, was in der Scene View angezeigt wird, auch in der Hierarchie zu sehen ist. Solcherlei Probleme hindern Unity daran, dir zwei Scene Views zu geben, die unterschiedliche Dinge anzeigen.
  3. Okay... ist für mich schwer zu entscheiden, wo ich ansetzen soll. Einerseits kommt einige Verwirrung daher, dass deine Schleifenvariable ("Durchlauf") keine lokale Variable ist, sondern auch nach Beendigung deines Schleifencodes weiterhin bestehen bleibt und du deshalb manuell den Wert zurücksetzt. Aber anstatt darauf einzugehen, würde ich lieber noch ein, zwei Schritte zurückgehen und darauf hinweisen, dass es mehr Datensammelstrukturen als Listen gibt. Wenn dein Ziel ist, eine Sammlung von Elementen zu haben, in der kein Element doppelt vorkommt, und du willst wissen, ob ein bestimmtes Element drin ist oder nicht, empfiehlt sich ein HashSet. Das entspricht nämlich genau dem mathematischen Konzept einer Menge und erlaubt dir superfixes Nachschauen, ob ein Element schon drin ist. Zwar hat die Liste auch eine "Contains"-Funktion, aber es gibt gute Gründe, bei einer solchen Situation das Set zu nehmen. Performance ist nur einer davon, und nicht einmal der beste Hier ein Beispiel, wie man HashSets benutzt: var menge = new HashSet<int>(); menge.Add(5); menge.Add(10); Debug.Log(menge.Contains(5)); // true
  4. Sascha

    scene view in editor window anzeigen

    Ich würde sagen: Mach halt ne Scene View auf. Du kannst mit [ExectureInEditMode] ein Script auch außerhalb des play modes laufen lassen. Ansonsten gibt's noch EditorApplication.update. Kannst einfach eine zweite Game View öffnen.
  5. Wenn das nicht eine unschöne Veränderung für deinen Code bedeutet, kannst du ein Struct verwenden, da diese sich ein- und ausklappen lassen. [System.Serializable] private struct SpeedSettings { public float speed; public float acceleration; } [SerializeField] private SpeedSettings speedSettings; DoSomethingWith(speedSettings.speed); Ansonsten geht so etwas nur mit einem eigenen Inspector. Alternativ auch mit so etwas wie Odin, wenn du dich da reinfuchsen willst. Der Inspector könnte etwa so ausshen: [CustomEditor(typeof(YourClassName))] public class YourClassNameEditor : Editor { private bool open = false; public override void OnInspectorGUI() { serializedObject.Update(); open = EditorGUILayout.Foldout(open, "Show My Variable"); if (open) { EditorGUILayout.PropertyField(serializedObject.FindProperty("myVariableName")); } serializedObject.ApplyModifiedProperties(); } }
  6. Mein Code war 100% Beispielcode. Es gibg darum, zu zeigen, dass du Werte im IMGUI-Code an bestimmten stellen ändern musst, z.B. beim Drücken eines Knopfes. Dein neuer Post und Code wirken so, als gäbe es ein grundsätzliches Verständnisproblem mit IMGUI. Zeilen wie "GUILayout.Label" erzeugen keine neuen UI-Elemente - sie zeigen sie einmalig an... vereinfacht ausgedrückt. Wenn du also in jedem OnGUI-Aufruf fünf Mal GUILayout.Label aufrufst, dann wirst du fünf Labels sehen. Wenn du Daten in ein IMGUI-Interface speisen willst (also z.B. eine Liste anziegen), dann sollte diese Liste außerhalb des UI existieren, und das gleiche gilt, wenn du Daten über IMGUI erstellen willst. Hier hast du Beispielcode für das Anzeigen und Bearbeiten einer Liste. Beachte, wie die Liste nur dann erweitert wird, wenn man auf "Hinzufügen" klickt. Der Inhalt der Liste ändert sich niemals zum Zweck der Anzeige im UI. private List<string> list = new List<string>(); private OnGUI() { var deleteIndex = -1; for (var i = 0; i < list.Count; i++) { GUILayout.BeginHorizontal(); // Textfeld zum Bearbeiten list[i] = GUILayout.TextField(list[i]); // Knopf zum Löschen if (GUILayout.Button("X", GUILayout.Width(26))) { deleteIndex = i; } GUILayout.EndHorizontal(); } if (deleteIndex > -1) { list.RemoveAt(deleteIndex); } // Knopf zum Hinzufügen else if(GUILayout.Button("Hinzufügen")) { list.Add(""); } }
  7. Sascha

    AR export nach HTML

    Mein Wissen hierzu mag nicht ganz aktuell sein, aber mein letzter Kenntnisstand ist, dass Vuforia und WebGL nicht miteinander können. Man möge mich gegebenenfalls korrigieren.
  8. Sascha

    Leeren des Eingabe Textes vom Input Field

    Einfach Mauszeiger über den Variablennamen halten, dann verrät dir jede halbwegs vernünftige IDE direkt, welchen Typ die Variable hat. Auch bei Benutzung von var
  9. Sascha

    Leeren des Eingabe Textes vom Input Field

    Ich benutze fast überall var. Ich würde behaupten wollen, dass es für die Lesbarkeit (Typ sofort erkennen) auch nur einen Unterschied macht, wenn man schlechte Variablennamen wählt.
  10. Erst einmal solltest du dir Klammern angewöhnen. if (Bedingung) { Dann Zeug } Im Gegensatz zu Python reicht es bei C# nicht aus, einfach die Sachen einzurücken. Deshalb solltest du dir angewöhnen, immer Klammern hinzuschreiben, auch wenn es möglich ist, sie bei einzelnen Zeilen wegzulassen. Die Diskussion hatten wir auch gerade in einem anderne Thema. Zum eigentlichen Problem: Bau dir einen Input-Vektor, benutze ihn für einen einzelnen Translate-Aufruf (auch wenn du dabei nicht lange bleiben solltest, aber das ist ein anderes Thema), und dann nutze ihn außerdem für die Drehung. Oder du drehst einfach nur und bewegst dich dann vorwärts in die jeweilige Richtung. // Habe hier mal versucht, den Vektor an dein Richtungsschema anzupassen // TODO Ggf. ändern var input = new Vector3(0, Input.GetAxis("Vertical"), Input.GetAxis("Horizontal")); if (input != Vector3.zero) { // Rechne aus, wo du dich in Abhängigkeit zum Input hindrehen willst var targetRotation = Quaternion.LookRotation(input); // Drehe dich da mit turnSpeed hin transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed * Time.deltaTime); // Bewege dich in deine Blickrichtung vorwärts transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime); }
  11. Sowas? private bool displayPopup; private int number = 0; private void OnGUI() { GUILayout.Label("number: " + number); if (GUILayout.Button("Show popup")) { displayPopup = true; } if (displayPopup) { if (GUILayout.Button("Count + 1")) { number++; displayPopup = false; } } } Du hast ja schon bestimmte Momente, in denen die Werte geändert werden sollen (in diesem Fall displayPopup). Du musst halt dafür sorgen, dass die Wertänderung ausschließlich dann passiert, wenn du sie auch haben willst, z.B. beim Klicken eines Knopfes.
  12. Musst halt deine bools außerhalb der Methode haben, damit sie bleiben. private bool displayLabel; private void OnGUI() { if (GUILayout.Button("Toggle Label")) { displayLabel = !displayLabel; } if (displayLabel) { GUILayout.Label("Hi there."); } }
  13. IMGUI-Code gehört keinesfalls in Update. Woher deine Fehlermeldung jetzt genau kommt, kann ich nicht sagen, aber wenn du deinen UI-Code nur noch in OnGUI bzw. den ausschließlich darin aufgerufenen Methoden hast, läst sich das Problem vermutlich von alleine.
  14. Sascha

    Schöner oder kurzer Code?

    Das ist die Sache mit der Robustheit. Du hast zwei Möglichkeiten, etwas in einer Situation zu tun. Die eine Möglichkeit funktioniert immer und die andere erfordert, dass du bei bestimmten Folgesituationen (Debugging, Änderung im Code) erstmal deinen bestehenden Code abändern musst.
  15. Sascha

    UI Shader Draw on Top

    Einen Shader brauchst du für die Reihenfolge von 2D-Objekten nicht. Aber im Falle von UI-Elementen kannst du einen Canvas nehmen, ihn deinen anderen UI-Elementen unterordnen und mit der Option "Override Sorting" die Sortierung ändern. Im Zweifelsfall würde ich aber auch empfehlen, noch einmal gründlich darüber nachzudenken, warum du das überhaupt machen willst - eigentlich braucht man diesen Workaround nämlich gar nicht.
  16. Sascha

    Richtlinien beim Programmieren (Sprache)?

    Auf dem Niveau kann man das nicht prüfen und es juckt auch keinen. Deutsche Variablennamen sind einfach aus dem Grund verpönt, weil du von anderem Code immer englische Namen hast und du dann ein Sprachmischmasch hast. Wenn du allerdings alleine arbeitest und du von niemandem jemals erwartest dass er deinen Code liest, dann ist so etwas völlig wurscht.
  17. Ich ralle zwar nicht ganz, was du da machen willst, aber ich versichere dir, dass ein temporäres Löschen der Referenz in jedem Fall Quatsch ist.
  18. Warum sollten nicht mehrere Komponenten gleichzeitig eine Referenz auf deinen Text speichern?
  19. Sascha

    NavMesh per Collider erstellen

    Sich durch sowas durchzuwühlen kann ganz schön Zeit kosten, die ich nicht wirklich habe - vor allem, weil ich selber aktuell keinen Bedarf habe.
  20. Sascha

    NavMesh per Collider erstellen

    Oh, das hab ich übersehen. Ja, Vanilla-Navmeshes und 2D gehen überhaupt nicht zusammen. Da brauchst du ein 3rd Party-Plugin.
  21. Sascha

    Schöner oder kurzer Code?

    Einfach nicht ellenlangen Code schreiben, dann hat man das Problem nicht
  22. Sascha

    Schöner oder kurzer Code?

    Early Outs sind bei mir auch die einzige Ausnahme, bei der if-Abfragen keine geschweiften Klammern kriegen.
  23. Sascha

    Schöner oder kurzer Code?

    Ich mach das nie so. Ich mag Konsistenz. Möglichst wenige Regeln, möglichst wenige Ausnahmen. Je mehr verschiedene Herangehensweisen es für quasi dieselbe Situaion gibt, desto weniger einfach ist der Code zu lesen. Deswegen halte ich 90% aller C#-Sprachupdates auf für großen Käse...
  24. Sascha

    Editor-Script/ scene lädt nicht ?

    Dir ist sicher aufgefallen, dass Unity, wenn du oben auf Play drückst, ne Sekunde oder so braucht, bis es startet. Das passiert im Hintergrund und blockiert damit nicht dein EditorScript. Ganz einfacher Test: EditorApplication.isPlaying = true; Debug.Log(EditorApplication.isPlaying); Da wird "False" ausgegeben. Nicht gerade sauber von Unity, ist aber so. Allgemein ist deine Abfrage nicht hilfreich, denn wenn "isPlaying" eben "false" ist, dann wird ja auch nicht gewartet, bis es true wird. Es wird einfach festgestellt "ist false" und die Sache ist fertig. Es hilft dir auch EditorApplication.isPlayingOrWillChangePlaymode nicht weiter, obwohl es "true" ist, sobald du "isPlaying" auf true gesetzt hast. Denn da läuft das Spiel ja noch nicht, deshalb kannst du keine Szene laden. Also musst du warten, bis der Playmode läuft. Ich habe da mal was gebastelt: public static void StartPlaymodeAndLoadScene(string scene) { EditorPrefs.SetString("scene to load", scene); EditorApplication.isPlaying = true; } [RuntimeInitializeOnLoadMethod] private static void RuntimeLoadScene() { if (EditorPrefs.HasKey("scene to load")) { EditorSceneManager.LoadSceneInPlayMode(EditorPrefs.GetString("scene to load"), new LoadSceneParameters { loadSceneMode = LoadSceneMode.Single }); EditorPrefs.DeleteKey("scene to load"); } } Was hier passiert: Du rufst an irgendeiner Stelle LoadSceneAndStartPlaymode("Assets/Scene.unity"); auf. Es muss der gesamte Pfad der Szenendatei im Assets-Ordner sein, plus "Assets/" am Anfang. Das Script braucht using UnityEngine.SceneManagement; using UnityEditor.SceneManagement; Als Ausgleich dazu kannst du jede Szene laden, ohne dass sie in der Build List stehen müsste. Wenn dir das nicht gefällt, kannst du auch das normale Scene Management benutzen, also die Zeile mit EditorSceneManager.LoadSceneInPlayMode ersetzen. Unity speichert in den EditorPrefs den Namen der zu ladenden Szene und startet den Playmode. Das Attribut [RuntimeInitializeOnLoadMethod] sorgt dafür, dass die Methode "RuntimeLoadScene" bei Spielstart aufgerufen wird. Es wird geprüft, ob in den EditorPrefs eine Szene zum Laden hinterlegt wurde. Wenn ja, wird sie geladen und der EditorPrefs-Key wird gelöscht. Wenn die übergebene Szene nicht existiert, also der Pfad nicht zu einem Szenen-Asset führt, dann wird eine leere Szene geladen. Da kann man sicher noch ein paar Sicherheitsüberprüfungen einbauen.
  25. Sascha

    Schöner oder kurzer Code?

    Richtig, es gibt da kein absolutes Maß. Ist von Fall zu Fall unterschiedlich. Gerade, wenn man in diesem Fall bedenkt, dass auch print(X == Y ? "wahr" : "falsch"); geht.
×