Jump to content
Unity Insider Forum

Lightstorm

Members
  • Content Count

    155
  • Joined

  • Last visited

  • Days Won

    3

Lightstorm last won the day on January 23

Lightstorm had the most liked content!

Community Reputation

16 Gut

About Lightstorm

  • Rank
    Advanced Member

Profile Information

  • Gender
    Male

Recent Profile Visitors

2,327 profile views
  1. Hallo, ich kenne mich mit dem Networking System von Unity noch nicht gut aus. Ich möchte das Unity mit einem node.js TCP Server kommuniziert. Ist das mit dem in Unity integrierten Networking System möglich oder müsste ich dafür einen eigenen .Net TCP Client schreiben? Grüße
  2. Ich möchte für ein Spiel Dialoge entwickeln. Der Spieler soll auf eine bestimmte Nachricht mit mehreren Antwortmöglichkeiten reagieren können. Abhängig von der ausgewählten Antwort des Spielers, kommt dann eine darauf eingestellte neue Nachricht. Diese Dialoge werden zahlreich und jeder einzelne Dialog kann mehrere Verläufe haben. Wie ich das programmiere weiß ich bereits. Ich frage mich nur wie ich das am besten übersichtlich organisieren kann. Am liebsten wäre mir ein Tool, womit ich visuelle Elemente erstellen kann: Nachrichten Boxen, Antwort Boxen und diese Boxen kann ich beliebig miteinander verbinden, um den Pfad des Dialogs zu bestimmen. Nachdem der Dialog geschrieben und verzweigt ist, will ich dann das ganze z.B. als JSON oder in einem anderen Format exportieren, um es dann im Spiel zu importieren. Jede Editierung und Erstellung der Dialoge würde über das visuelle Tool ablaufen. Gibt es so etwas bereits oder etwas ähnliches?
  3. Das ist der einzige Grund wieso ich manchmal überlege die Vorgehensweise ohne geschweifte Klammern zu unterlassen. Es ist dann nervig wenn man zum testen die Klammern wieder hinzufügen muss. Es ist schnell gemacht, aber es nervt wirklich
  4. Ich mag es nicht wenn verhältnismäßig viele Leerräume entstehen und ich viel scrollen muss um den Code zu lesen. Etwa in Situationen wo man dann mehrere If Abfragen hintereinander ausführt um jedes mal dabei nur eine Zeile Code auszuführen.
  5. Wenn in den Klammern nur eine Zeile Code nötig ist mache ich es meistens so: if (X == Y) print("wahr") else print("falsch") Wichtig ist zu wissen das ohne Klammern nur eine Zeile von der if Bedingung abhängt. Wenn man den Code also später erweitert und noch eine Zeile einfügt muss man die Klammern wieder hinzufügen. Folgendes geht also nicht: if (X == Y) print("wahr") print("wirklich wahr") else print("falsch")
  6. Hm ok verstehe. Ich belasse es vorerst bei der Lösung dass das rigidbody auf der Plattform auf extrapolate eingestellt wird und außerhalb auf interpolate. private void OnTriggerEnter2D(Collider2D collision) { collision.transform.parent = gameObject.transform; if (collision.attachedRigidbody) collision.attachedRigidbody.interpolation = RigidbodyInterpolation2D.Extrapolate; } private void OnTriggerExit2D(Collider2D collision) { collision.transform.parent = null; if (collision.attachedRigidbody) collision.attachedRigidbody.interpolation = RigidbodyInterpolation2D.Interpolate; }
  7. @malzbie Wenn ich die Kameraposition mit der Lerp Methode über Update aktualisiere und das Rigidbody des Spielcharakter auf Interpolate setze funktioniert es so wie es soll. Kein ruckeln auf der Plattform. Aber es taucht ein anderes Problem auf. Wenn der Spielcharakter sich auf der beweglichen Plattform bewegt stottert es dabei und bewegt sich nur langsam vorwärts. Wenn ich Interpolate auf Extrapolate einstelle ist auch dieses Problem gelöst. Ist das ok so? Über Extrapolate heißt es in der Dokumentation dass dadurch schnelle rigidbody Objekte bei Collisionen in die Collider rein geraten könnten.
  8. Das Thema bewegliche Plattformen geht in die nächste Runde glaube ich Ich habe eine Kamera die den Spielcharakter verfolgt. Im Prinzip so: transform.position = Vector3.SmoothDamp(transform.position, targetPos, ref velocity, .1f); targetPos ist die Position des Spielcharakter. Das ganze wird in FixedUpdate() ausgeführt. Der Spielcharakter wird über rigidbody2D bewegt. Wenn ich die Position der Kamera in Update() ändere entsteht ein hässliches ruckeln wenn die Kamera den Spieler verfolgt. Nun habe ich bemerkt dass eine animierte Plattform (Unity Animation mit Animator Komponente) das selbe ruckeln erzeugt nachdem der Spielcharakter auf die Plattform hüpft und zum Kindsobjekt der Plattform wird. Siehe auch: Das liese sich lösen wenn die Kameraposition in Update() statt FixedUpdate() aktualisiert wird. Dann verschwindet das ruckeln beim verfolgen auf der Plattform. Dann aber habe ich wie oben erwähnt das ruckeln wenn sich der Spielcharakter normal außerhalb der Plattform bewegt. Soweit ich verstehe hat das damit zu tun das FixedUpdate() und Uptate() unterschiedlich oft aufgerufen werden. Die Frage ist wie kann ich das nun angleichen. Wie kann ich die animierte Plattform dazu bringen dass es sich mit der Frequenz von FixedUpdate() aktualisiert?
  9. @Gadakar86 Wie @malzbie schon richtig schreibt, der Code funktioniert. Wenn du es richtig bei dir verwendest sollte es gehen. Du musst einen Collider für deine bewegliche Plattform erstellen und es als Trigger einstellen. Alles was im Spiel in diesen Collider rein geht wird durch die Funktion OnTriggerEnter2D zum kindsobjekt der Plattform.
  10. Du willst den Ball nur bewegen wenn es keine Bodenhaftung hat bzw. IsGround false ist? Das machst du damit nämlich mit !IsGrounded() Du prüfst mit IsBlocked() ob rechts vom Ball ein Hindernis ist und schaltest dann die Richtung um. Mit !IsBlocked schaltest du um wenn kein Hindernis da ist? Wenn der Ball aber nicht auf Anhieb sich vom Hindernis entfernen kann trifft der Raycast wieder auf das Hindernis und ändert wieder die Richtung. Das passiert ganz schnell und der Ball kommt gar nicht weg. Also ich habe dein Script bei mir ausprobiert und mit dem Code bewegt sich der Ball gar nicht. Erst wenn du IsGrounded nicht mehr negierst, also IsGrounded statt !IsGrounded fängt der Ball an sich zu bewegen, bleibt aber beim nächsten Hindernis kleben und ändert nicht die Richtung. Versuch doch das mit Trigger Collidern zu lösen. Wie es Sascha schon mit OnCollisionEnter2D zeigte oder mit OnTriggerEnter2D. Damit würde der Ball sich bei einem Hindernis nicht ständig rechts und links bewegen. OnCollisionEnter2D wird nur einmal ausgelöst wenn du auf ein Hindernis stößt. Wenn du den Ball stoppen willst musst du die horizontalMovement Variable auf 0 setzen. Das könntest du mit einem Trigger am Loch machen.
  11. Modularisierung. Man unterteilt ein Programm in sinnvolle Einzelteile. Ein Vorteil ist dass ein Programm so übersichtlicher wird und ein anderer Vorteil ist dass du Module bzw. Scripte miteinander unterschiedlich kombinieren kannst. Du vermeidest es gleichen oder ähnlichen Code immer wieder neu schreiben zu müssen. Ein konkretes Beispiel ist folgendes: Ich habe im Prinzip zwei Scripte um einen Charakter zu steuern. CharakterController.cs und PlayerCharacterMovement.cs. Ich könnte beides vereinen und einen einzigen Script schreiben. Kann man machen. Aber die Trennung macht den Code flexibler. Ich wollte eine automatische KI Steuerung für Gegner Charaktere und ich dachte mir, eigentlich brauchen die Gegner Charakter die selben Eigenschaften wie mein Player Charakter. Sie müssen sich bewegen, springen, Wände und Böden erfassen, Animationen abspielen. Warum soll ich den Code von CharakterController.cs neu schreiben oder kopieren wenn ich doch nur den PlayerCharacterMovement.cs Script einfach durch ein AICharakterMovement.cs ersetzen muss? Die Modularisierung macht es einfacher. Um Gegner Charaktere automatisch zu steuern musste ich nur sehr wenig Code schreiben, denn ich konnte CharakterController.cs unverändert nutzen, das ging nur weil es diese Aufteilung gibt Du könntest den Code von CharakterController.cs auch einfach kopieren aber mit so einer Vorgehensweise hast du irgendwann sehr viele Scripte mit gleichem Code. Das ist unschön und wenn du später etwas daran ändern musst, musst du es in allen Scripten ändern wo du es genutzt hast. Die Vorteile einer sauberen Vorgehensweise merkt man übrigens erst so richtig im Laufe eines Projektes. Am Anfang ist die Verlockung groß einfach schnell eine Lösung zu schaffen, weil es ja kein großer Aufwand ist Teile eines Scriptes einfach zu kopieren oder neu zu schreiben. Aber das wiederholt sich dann hunderte mal im Laufe der Entwicklung und irgendwann verwandeln sich die schnellen unschönen Lösungen zu einem unübersichtlichen und fehlerhaften Chaos. Das kann so schlimm werden dass man so nicht mehr weiter entwickeln kann ohne vieles umzubauen. Daher lohnt es sich bereits am Anfang eine disziplinierte Vorgehensweise anzugewöhnen. Wenn du weitere Fragen hast oder noch etwas unklar ist frag ruhig.
  12. Nur wenn die Reibung eines Physics Material hoch eingestellt ist. Ab einer bestimmten Geschwindigkeit der Plattform rutscht das rigidbody trotzdem. Was physikalisch korrekt ist. Bei hohen Werten für die Physic Reibung hat man unter Umständen das Problem dass man an der Platform seitlich leicht hängen bleibt weil die Reibung so hoch ist.
  13. Hallo @Schokokeks15 Ich bin auch noch am lernen und bin kein erfahrener Programmierer. Ich hatte schon früher einige Anläufe mit der der Programmierung. Der Unterschied dieses mal ist dass ich versuche systematischer vorzugehen. Früher oder später musst du dir überlegen wie deine Code Architektur in Unity aussehen soll. Schau dir diesbezüglich auch mal das an: https://gitlab.com/FlaShG/Unity-Architecture Es ist vielleicht am Anfang mühseliger sich gedanklich damit zu beschäftigen, aber es lohnt sich wirklich.
  14. @Sascha Wieder mal eine Frage Eines verstehe ich noch nicht. Wenn man ein Feld wie "[SerializeField] private int test" anlegt kann man es beispielsweise in der Reset Methode mit "test = 10" initialisieren. Aber wenn es ein Feld wie "[SerializeField] private IntReference test" ist und man es in der Reset Methode mit "test.Value = 10" festlegen will gibt es einen Fehler: NullReferenceException: Object reference not set to an instance of an object Um das zu beheben muss man das Objekt direkt erstellen. Also "[SerializeField] private IntReference test = new IntReference()". Wieso ist das so? Wenn man auf die Referenz Variable in irgendeiner anderen Methode im Script zugreift klappt das ohne zuvor "new IntReference()" aufzurufen. Den NullReferenceException gibt es meistens wenn man auf das Feld in einer frühen Phase zugreifen will. Also in der Reset Methode im Editor oder manchmal auch in der Start Methode.
  15. Was vielleicht auch hilfreich sein kann ist dir zu überlegen ob du für alle solche Aufgabenstellungen eigene Scripte erstellen willst. Vielleicht willst du z.B. ein anderen Gegner machen der sich ähnlich aber etwas anders verhalten soll. Dann könntest du deinen ganzen Script kopieren und eine leicht abgeänderte Version erstellen. Und wenn ein anderer Gegner sich ganz deutlich anders verhalten soll musst du vielleicht ein ganz neuen Script erstellen. Um so was zu vermeiden könntest du überlegen ob du nicht möglichst universell verwendbare Scripte erstellen kannst. Objekte simple hin und her bewegen macht man recht häufig. Du könntest überlegen wie du ein Script erstellen kannst das Objekte bewegen kann, die Parameter und Variationen der Bewegungen kannst du dann über den Inspector einstellen. Das was du versuchst könnte ich mit drei universell einsetzbaren Komponenten umsetzen: Bei einer Kollision löst "Collider Trigger 2D" ein Unity Event aus, mit diesem Event kann ich direkt auf "Auto Movement 2D" zugreifen und Werte wie Translation Direction verändern. "Entity Movement 2D" kümmert sich um die Bewegung der Objekte und wird von "Auto Movement 2D" angesteuert. In einem anderen Fall wird Entity Movement über einen Player Script angesteuert, es wird häufig verwendet. Ich kann über den Parameter Movement Mode einstellen mit welcher Methode das GameObject bewegt werden soll. Mit transform.Translate, AdForce, AdForce Impuls oder über rigidbody2D.velocity. Sachen wie Speed Curve sind optional. Hast du einmal solche Komponenten erstellt kannst du sie in verschiedenen Kombinationen in GameObjects nutzen. Damit werden die Fälle wo man neuen Code schreiben muss deutlich reduziert. Ich versuche jedes mal wenn neuer Code nötig wird, wieder eine möglichst universell verwendbare Komponente zu erstellen. Diese Komponenten entwickeln sich weiter. Nach und nach findet man heraus welche weiteren einstellbaren Parameter sinnvoll sind, dann passe ich die Komponenten an, irgendwann ist ein Optimum erreicht wo keine Änderungen mehr nötig sind. Mit einer Reihe von spezialisierten und einstellbaren Komponenten kann man erstaunlich viele Variationen an Objekt Verhalten erstellen. Erst wenn für eine Aufgabenstellung sehr viele solcher Komponenten nötig werden, wird es im Editor unübersichtlich und vom Code her vermutlich ineffizient. Dann kann und sollte man neue Scripte und Komponenten erstellen. Für Charakter Bewegungen nutze ich aber andere Komponenten. Ich habe einen CharakterController Script. Über das lassen sich grundlegende Eigenschaften einstellen. Dann gibt es einen PlayerCharacterMovement Script. Damit wird CharakterController angesteuert, über den Player Input. Wenn ich Gegner Charaktere machen will die sich selbst bewegen nutze ich statt PlayerCharacterMovement ein AICharacterMovement Script. Auch dieser AI Script steuert CharakterController an, nur halt nicht über Player Input sondern mit Steuermustern die andere Komponenten senden. Ich habe beispielsweise eine Timer Komponente die in einstellbaren Zeitabständen das Steuermuster für AICharakterMovement verändert. Auch kann die Komponente "Collider Triger 2D" eingesetzt werden, Gegner Charaktere bzw. die Steuereingaben können also auch über Trigger verändert werden und nicht nur über Timer. Mit einer handvoll Komponenten kann man sehr komplexe Verhaltensmuster erzeugen. Der Nachteil ist dass die Entwicklung der einzelnen Komponenten am Anfang etwas dauert. Aber man spart später enorm viel Zeit und kann die Komponenten in anderen Projekten wieder verwenden.
×
×
  • Create New...