Jump to content
Unity Insider Forum

Sascha

Administrators
  • Content count

    11,150
  • Joined

  • Last visited

  • Days Won

    514

Sascha last won the day on April 19

Sascha had the most liked content!

Community Reputation

2,250 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

35,259 profile views
  1. Sascha

    Objekt mit Resources.Load() laden

    Wenn "cube" ein Ordner ist, kannst du den schlecht laden. Mal davon abgesehen, müssen Ressourcen in einem Ordner namens "Resources" sein. Mit "Objects/cube" lädst du also z.B. das Asset mit dem Pfad "Assets/Resources/Objects/cube.prefab" oder "Assets/Banana/Resources/Objects/cube.prefab". Das ist auch schon so der erste Punkt, an dem die Warnleuchten angehen dürfen - Resources sollte man einfach generell nicht außerhalb von Editorscripts benutzen.
  2. Bitte was? Das Spiel hat ein FoV von irgendwas um 110, 120. Dinge, die zwei Felder weit weg sind sind nur noch halb so groß wie Dinge, die ein Feld weg sind. Also einfach hoch den Slider. Zusätzlich dazu scheint die Kamera nicht auf der Rotationsachse des Spielers zu sitzen, sondern leicht dahinter.
  3. Genau das. Deine IDE und der Compiler können schon vor Programmstart schauen, ob das, was dein Code machen will, überhaupt möglich ist. Ein String ist immer korrekt, bis du ihn in einem bestimmten Kontext benutzen willst, also fäält frühestens in dem Moment ein Fehler auf.
  4. FindObjectsOfType ist auch doof, aber mit einer anderen Begründung - diese ist leider etwas komplexer als die Begründung gegen Strings. Für Anfänger (und wohl auch eine Weile für Fortgeschrittene) ist das ne heftige Nummer. Ich arbeite seit über zehn Jahren mit Unity und habe erst letztes Jahr wieder ein richtig dickes "Klick" gehabt, was dieses Thema angeht. Ich versuche aber mal, das zu erklären. Unity ist ein dickes, fettes "Dependency Injection"-Framework. Stelle dir vor, du hättest den Unity-Editor nicht. Dann müsste deine Player-Kamera mit sowas wie GameObject.Find den Player finden, um ihm zu folgen. Stattdessen kannst du ein serialisiertes Feld in dein Kamera-Script packen, dem Script beibringen dem Ding zu folgen, das von der Variable referenziert wird, und den Player reinziehen. Das bedeutet, dass Unity irgendwie für dich dafür sorgt, dass das richtige Ding referenziert wird, ohne dass du dafür selber Code schreiben musst. Unity "injiziert" hier das Objekt, von dem das Verhalten der Kamera abhängt ("Dependency"), denn die Kamera fliegt anders, je nachdem, wem sie folgt. Darum "Dependency Injection". Ich merk grad schon, da sollte ich auch mal einen Artikel drüber schreiben Jedenfalls bewirkt Unity als Dependency Injection-Maschine zwei Dinge: Du kannst als Designer arbeiten, ohne zu coden. Gute Scripts lagern Abhängigkeiten, die als Teil des Gamedesign-Prozesses festgelegt werden, aus dem Code aus, sodass man keinen Code mehr braucht, um das Spiel letztenenedes zu verkabeln. Das macht Designarbeit angenehmer, weil richtig gute Scripts und Editor-Tools komplettes WYSIWYG machen, aner es erlaubt es auch, Teammitglieder zu haben, die nicht coden können und trotzdem Gamedesign machen. Es nimmt die Verantwortung aus den Scripts. Das Kamera-Script hat keine Verantwortung mehr, sich mit dem Aufbau der Szene zu beschäftigen. Gibt es ein Player-Objekt? Gibt es mehrere? Was passiert, wenn es mehrere gibt? Folge ich dann dem erstbesten? Statt das Kamera-Script sich über so etwas Sorgen machen zu lassen, sagst du ihm: "Das wird dir dann schon gesagt, wem du folgen musst". Das sorgt für schlanke Scripts, die einfach nur das machen, was sie machen, und nicht noch Ahnung von lauter anderen Teilen des Projekts haben müssen. Teil 2 ist hier das Wichtige. Wann immer dein Script nach etwas sucht, bedeutet das, dass es ein Mindestmaß an Ahnung haben muss, wie dein Projekt augebaut ist. Dazu gehört zum Beispiel ein bisschen Code, der definiert, was passiert, wenn es mehrere Player gibt, sofern du nicht irgendwie anderweitig sicherstellen kannst, dass es immer nur einen gibt... oder du lässt Unity pseudo-zufällig einen auswählen. Daher ist es immer schlecht, wenn dein Script etwas sucht, sei es nun mit Strings oder anderweitig. Was meiner Meinung nach einen richtigen Unity-Coding-Pro ausmacht ist die Fähigkeit, für jede Situation eine elegante Art zu finden, wie Objekte sich "kennenlernen", ohne dabei Scripts zu erstellen, die mehr von der Welt wissen als das, was sie notwendig für ihre eigene Aufgabe benötigen. Wenn es z.B. darum geht, mit dem Player zu arbeiten, dann gibt es da direkt mehrere Möglichkeiten, die ohne das eigenständige Finden des Player-Objekts auskommen. Die erste Verbesserung wäre ein Pseudo-Singleton, über das ich auch schon einen Artikel habe: http://blog.13pixels.de/2019/unity-and-the-mysterious-singleton/ Wenn man nach Singletons sucht, findet man hin und wieder die Info, dass man die Finger davon lassen sollte. Letztenendes sind die auch nicht das Gelbe vom Ei, aber sie sind schonmal ein Stück besser als das Suchen von Objekten in der Szene. Mein Artikel hat als Konklusion auch, dass man die Dinger ruhig benutzen kann. Es wird etwas heftig, etwas besseres zum Laufen zu kriegen (das was mein "Klick"-Moment letztes Jahr), und bis man soweit ist, kann man ruhig Pseudo-Singletons benutzen.
  5. Die NullReferenceException tritt immer dann auf, wenn eine Variable den Wert null hat (oder ein Ausdruck zu null evaluiert), du aber etwas von dem referenzierten Objekt willst, das es ja nicht gibt. "Etwas vom referenzierten Objekt wollen" bedeutet syntaktisch, dass du den Variablennamen bzw. den Ausdruck hast, gefolgt von einem Punkt. myCar.Drive(); // Hier könne myCar null sein GetCar().Drive(); // Hier könnte GetCar() null zurückgegeben haben GetCar().motor.Start(); // Hier könnte GetCar() null zurückgeben oder motor null sein (In Unity gibt's noch die "MissingReferenceException", die quasi dasselbe ist, und zudem die Eigenschaft von UnityEngine.Objects, wie null behandelt zu werden, obwohl sie existieren.) Wir haben also deine Fehlerzeile: ply = GameObject.Find("Player").GetComponent<Transform>(); Wenn "ply" null wäre, würde hier kein Fehler passieren. null ist ein gültiger Wert und kein Fehler, denn damit beschreibst du den Zustand, dass ein bestimmtes Ding nicht da ist - wenn jemand kein Auto besitzt, keinen Vater hat, oder das Auto keinen Motor. Sind ja alles Sachen, die passieren können, und die werden dann mit null dargestellt. Was aber eben nicht geht, ist dass du den Motor eines Autos anlässt, wenn das Auto gar keinen Motor hat. Deshalb wird bei "irgendwas.blub" die Exception ausgelöst, wenn irgendwas null ist. Bei deiner Zeile hast du folgende Sachen mit Punkt dahinter: GameObject Find("Player") Da GameObject eine Klasse ist und damit kein Ausdruck, der null sein könnte, bleibt nur "Find("Player")". Es wird ganz einfach kein GameObject mit dem Namen "Player" gefunden, und wenn du dann versuchst, von dem nicht gefundenen Objekt eine Komponente zu besorgen, knallt's. Dass das so schwer zu sehen war, ist einer der Gründe, warum ich dringend Empfehle, GameObject.Find oder auch Tags niemals zu benutzen. Macht Fehler einfach immer schwer zu sehen.
  6. Auf lange Sicht ist auch klar die Empfehlung, diese String-Funktionen (GameObject.Find, GameObject.FindGameObjectWithTag, Resources.Load usw) komplett liegen zu lassen. Genau solche Fehler passieren nur bei diesen Funktionen, für die es auch Alternativen gibt. Kleiner Artikel dazu: http://blog.13pixels.de/2019/why-strings-are-not-your-friend/
  7. Sascha

    Sichtfeld eingrenzen

    Klassiker mit einfacher Lösung und komplexer Begründung. Vereinfachte Begründung: Rotationen in Unity werden in Form von Quaterionen abgespeichert, nicht Eulerwinkeln. EulerWinkel sind dieses "Wie viel wird um die Achsen X, Y und Z gedreht" was man im Editor einstellt, Quaternions sind... komplizierter. Wenn du jedenfalls Eulerwinkel als Rotation setzt oder sie als solche ausliest, dann wird immer von bzw. zu einem Quaternion umgewandelt. Und dabei gehen gewisse Informationen verloren. Du kannst daher problemlos einen Winkel reinstecken und einen anderen Winkel rauskriegen, z.B. -10 rein und +350 raus. Die simple Lösung: Nicht die Roation aus deiner Transform-Komponente auslesen, sondern einen eigenen Wert deklarieren und verwalten. Dieser eigene Wert ist dann einfach nur eine Zahl, bei der nix konvertiert wird. Das, was du als Wert reinsteckst, bleibt auch als Wert drin. Beispielimplementation: private float pitch; public float pitchMin = -80; public float pitchMax = 80; private void Update() { pitch -= Input.GetAxis("Mouse Y"); pitch = Mathf.Clamp(pitch, pitchMin, pitchMax); transform.localEulerAngles = Vector3.right * pitch; } Der "pitch"-Wert ist hier der Wert, den du ansonsten aus transform.localEulerAngles ausgelesen hättest. Jetzt setzt du ihn einfach nur und kannst deshalb gemütlich clampen, weil sonst nix mit dem Wert passiert. Hier ist noch etwas zusätzliche Lektüre für Kamera-Setups: http://blog.13pixels.de/2019/creating-a-camera-setup-in-unity/
  8. Sascha

    Schusssimulation in Unity erstellen

    Zum Beispiel durch zufällige Änderung des Winkels bei jedem Schuss.
  9. Sascha

    Schusssimulation in Unity erstellen

    Diese Sachen kannst du alle machen mit Raycasts als Basis. Ob nun ein Rigidbody mit der Wand kollidiert oder du einen Raycast auf die Wand schießt, das ist für das Einschussloch, das du da spawnst egal. Ein Einschussloch, oder auch eine auf dem Boden liegende Patronenhülse sind nämlich ziemlich unabhängig von deinem Schuss. Das einzige, was wichtig ist, wenn du dich zwischen Raycast oder einer anderen Lösung entscheiden willst, ist ob dein Projektil eher groß und langsam ist oder klein und schnell. Ein kleines und schnelles Projektil solltest du eher mit Raycasts machen. So oder so musst du danach lauter verschiedene Techniken obendrauf tun, damit's hübsch aussieht. Ein Partikelsystem bietet sich für Patronenhülsen und das Mündungsfeuer an, ein Linerenderer für die Spur des Projektils, Decals für Einschusslöcher, usw. Wenn deine Flugbahn nicht Quake-ähnlich einfach nur geradeaus bis zu ersten Hindernis geht, musst du halt mehrere Raycasts hintereinander packen.
  10. Sascha

    2D Image Effects

    Deine Szene wird von Postprocessing überhaupt nicht beeinflusst. Da wird das fertige Bild genommen und nachbearbeitet. Also sozusagen der Photoshop-Schritt bei Fotografen. Da wird dann mit den vorhandenen Pixeln etwas aufgehübscht. Bloom z.B. macht, dass helle Pixel etwas nach außen leuchten, sodass die hellen Areale des Bildes heller wirken. Dafür musst du die richtigen Einstellungen machen, damit's sichtbar ist, aber nicht zu krass. Da geht's schonmal mit der Frage los ob du in HDR renderst oder nicht.
  11. Sascha

    Schusssimulation in Unity erstellen

    Tipp: Computerspiele sind komplett virtuell - da fliegt auch nicht wirklich etwas durch die Luft wenn du irgendetwas anderes machst als Raycasts Wenn es dir darum geht, dass man da etwas sieht - Kugeln sieht man nicht. Zu klein, zu schnell. Darum werden in der Regel, wenn's nicht realistisch sein soll (oder Tracer Rounds im Spiel sind) Schweife gezeichnet. Geht super mit einem LineRenderer.
  12. Sollte damit nichts zu tun haben, eigentlich. Aber das ist das Problem mit dreistellig Zeilen langen Gottklassen - man kann die Zusammenhänge nicht erkennen, die Struktur nur erraten und eine der besten Techniken beim Debuggen - das Isolieren der Fehlerquelle, sodass man sich nur noch mit wenigen Zeilen beschäftigen muss, von denen man weiß, dass der Fehler in ihnen steckt - steht nicht zur Verfügung.
  13. Au Backe. Über 700 Zeilen Spaghetticode, wie beim Italiener. Das zu Debuggen ist nahezu unmöglich... es sei denn man schreibt dafür alles neu. Alles, was ich da sagen kann ist, dass das Spieler-Objekt offenbar keine "Shoot"-Komponente hat, während diese Zeile ausgeführt wird. Warum das im Play mode nicht ist, im Build aber schon, ist echt schwer zu sagen. Ich nehme jedenfalls an, dass du keine Preprocessor-Direktiven in einer der anderen Klassen hast?
  14. Ja gut, ich hab das dann mal wieder gelöscht. Was ist daran merkwürdig? Die bringt uns nur halt nix. Wir reden von deinem Code.
×