Jump to content
Unity Insider Forum

Sascha

Administrators
  • Gesamte Inhalte

    13.619
  • Benutzer seit

  • Letzter Besuch

  • Tagessiege

    780

Alle erstellten Inhalte von Sascha

  1. Ach soo Na dann: direction = direction.normalized * _directionRayLength.value;
  2. Der Ansatz klingt erstmal nicht schlecht, aber ich kann dir leider gerade nicht sagen, ob du damit zum Ziel kommst. Wenn du mit deinem Projekt nicht gerade unter Zeitdruck stehst, dann würde ich es an deiner Stelle einfach versuchen. Im Zweifelsfall lernst du bestimmt eine Menge. Dein Design kommt zuerst. Wenn du prozedural generierte Level oder einen Level-Editor haben willst, dann ist die Lösung raus. Deine Vision davon, wie das Spiel sein soll, für einen Kompromiss zu opfern, kommt meiner Meinung nach nicht in Frage, solange es noch andere Optionen gibt. Davon abgesehen könnte es durchaus funktionieren.
  3. Es gibt noch Vector3.ClampMagnitude, welches einmal das Berechnen der Quadratwurzel einspart. Ist vielleicht auch minimal lesbarer. Aber das sind nur minimale Optimierungen gegenüber @Antragons Lösung.
  4. Moin! Deine Kugel rollt ja nicht horizontal, sondern ein wenig nach unten. Das macht die Gravitation, die jedes Physik-Update draufgerechnet wird. Und die willst du ja auch haben. Dass du trotzdem horizontal bleibst, liegt nur an den Collidern unter der Kugel, mit denen du in jedem Frame aufs neue kollidierst. Das Problem entsteht dadurch, dass die Kugel je nach Umstand nicht mit der Oberseite, sondern mit der vorderen Kante eines Cubes kollidieren kann. Die Kugel rollt hier von links nach rechts. Schwarz ist die aktuelle Position, rot die Zielposition, bevor Kollisionen aufgelöst werden. Links betritt sie den rechten Cube durch die Oberseite (Kontakt-Areal ist orange), rechts geht's durch die Ecke. Die Physik-Engine versteht leider nicht, dass der linke Collider die Kugel eigentlich davon abhält, die vertikale Seite des rechten Colliders zu berühren. Deshalb wird eine Kollision an einer vertikalen Wand ermittelt. Je nach Winkel springt die Kugel deshalb nach oben oder bleibt komplett stehen. Du kannst in den Physik-Einstellungen in den Project Settings eine Einstellung ändern, die den Mindestwert eines Kollisionsimpulses beschreibt. Wenn du ihn höher stellst, dann ignoriert die Engine kleinere Hüpfer. Das hilft natürlich nicht so richtig, weil du immer noch drüber kommen kannst, aber auch, weil damit das Stehenbleiben nicht behoben wird. Mal davon abgesehen kannst du damit Impulse kaputt machen, die du eigentlich behalten wolltest. Das war aber leider auch schon die einzige simple Lösung. Wesentlich sinnvoller, aber leider auch schwieriger, wäre "Skin Width". Da kriegt der Collider noch eine Speckschicht außen herum, und wenn da etwas hinein gerät, wird deine Kugel einfach so weit verschoben, dass die Schicht wieder frei ist - ohne dabei einen Impuls zu erzeugen. Leider können Rigidbodys das meines Wissens nach aber nicht. Du kannst sonst noch ein bisschen mit der Form der Collider experimentieren. Eigentlich brauchst du da ja keine Würfel. Aber so richtig endgültig wird auch das nicht sein. Wenn du da nicht selber so richtig tief einsteigen willst, kann noch ein Blick in den Asset Store helfen. Leider ist ausgerechnet so etwas simples wie ein rollender Ball gar nicht mal so einfach umzusetzen.
  5. Moin und willkommen! Du kannst deinen Autos, wenn sie das nicht schon haben, Collider geben. Die sind nicht nur für Physik und Kollisionen da, sondern werden auch dafür benutzt, dass du in die Szene klicken kannst und dann wird geschaut, was du getroffen hast. Die professionellere Variante ist das jetzt nicht, aber für den Anfang reicht es aus, deinem Auto-Prefab ein Script zu geben (bzw. ein vorhandenes zu erweitern), das eine OnMouseDown-Methode hat: private void OnMouseDown() { Debug.Log(name + " wurde geklickt"); } Wenn das soweit funktioniert, kann man da was sinnvolleres reinschreiben. Z.B. kannst du das markierte Auto in einem statischen Feld referenzieren. Statisch bedeutet, dass nicht jede Instanz dieses Script (also jedes Auto für sich) dieses Feld (Variable) hat, sondern es das Feld nur einmalig im Programm gibt. Wenn du da also "hineinschreibst", welches Auto gerade markiert ist, dann kann immer nur eines zur Zeit markiert sein. // "NameDesAutoScripts" = Name dieses Scripts hier public static NameDesAutoScripts selectedCar; private void OnMouseDown() { selectedCar = this; } Und in deinem Code, der Autos bewegt, kannst du dann diesem Auto sagen, dass es sich bewegen soll: NameDesAutoScripts.selectedCar.MoveTo(position); ...oder wie auch immer dein Code da aussieht. Jedenfalls kannst du mit "NameDesAutoScripts.selectedCar" von überall im Code das aktuell ausgewählte Auto abfragen und damit machen, was du willst. Ist alles etwas rudimentär - für eine Stelle als Entwickler solltest du dich mit diesem Code eher nicht bewerben. Sollte aber funktionieren. Nur nicht drauf verbeißen
  6. Ja, das ginge auch. Sehen vermutlich nicht super überzeugend aus, aber wenn es gut genug aussieht, dann ist es eben gut genug Und wenn du dir bei der Variante ordentlich Coding-Stress sparst, dann ist wäre das auch ne gute Sache.
  7. Moin und willkommen! Ich glaube, das geht schlicht nicht. Zumindest nicht einfach so. Ich vermute, dass bei der Anforderungsanalyse damals (ist schon ein Weilchen her, dass an dem System was gemacht wurde) heraus kam, dass das zu selten gebraucht wird. Ich sehe aktuell höchstens die Möglichkeit, dass du ein Objekt immer wieder (vermutlich in FixedUpdate) an eine Position verschiebst, die du aus Cloth.vertices ziehst. Dort hast du die Positionen aller Vertices drin. Wie du die richtigen Indizes heraus findest, weiß ich gerade nicht mit Sicherheit. Vermutlich ginge aber ein initiales Iterieren durch die Vertices. Da schaust du für jeden Bommel, ob das aktuelle Vertex das nächstgelegene ist und wenn ja, merkst du dir das für den jeweiligen Bommel. Ich würde dafür eine Bommel-Komponente machen: public class Bommel : MonoBehaviour { private Vector3 attachedVertexIndex = -1; private float attachedVertexDistance = Mathf.Infinity; public void OverrideClosestVertexIfCloser(Vector3 vertex, int index) { var distance = Vector3.Distance(vertex, transform.position); if (distance < attachedVertexDistance) { attachedVertexDistance = distance; attachedVertexIndex = index; } } } Die kommt auf jeden Bommel drauf. Dann gibt's hier so einen Code, um durch alle Vertices durchzugehen: for (var vertexIndex = 0; vertexIndex < vertices.Length; vertexIndex++) { foreach (var bommel in attachedBommels) { bommel.OverrideClosestVertexIfCloser(vertices[vertexIndex], vertexIndex); } } Ich nehme stark an, dass das Vertex-Array allerdings im Local Space ist. Da muss man also nochmal Transform.TransformPoint oder so drauf schmeißen. Da das performance-mäßig nicht so knorke ist, sollte man das vielleicht in ein Editor-Tool packen. Hast nen Knopf, drückst drauf, er macht das einmalig im Editor und merkt sich die Ergebnisse einfach. Dann muss der Rechner, auf dem das Spiel läuft, das nicht bei jedem Spielstark machen. Dafür müssen die beiden Felder in der Bommel-Klasse noch [SerializeField, HideInInspector] abkriegen. Ist jetzt nicht mehr so wirklich Anfängerkram, aber soweit ich das sehen kann, gibt es dafür leider einfach keine anfängerfreundliche Lösung.
  8. Da fällt mir direkt keins ein. Ist aber eigentlich nicht so komplex. Du hast halt Entitys (hier "GameObjects"), die keine eigene Semantik haben, sondern nur Container für Komponenten sind. Diese Komponenten definieren dann, was das für ein Objekt ist. Eine Unterkategorie davon sind MonoBehaviours, also deine Scripts. Die klinken sich in Events ein, die aus der Engine kommen und kriegen so ihre Impulse, um irgendetwas zu tun. Wann du was auf welches GameObject packst, ist nicht fest definiert, aber es gibt natürlich Ansätze, die schlauer sind als andere. Z.B. sollten Objekte sich so weit wie möglich selber managen. Ein Hubschrauber hat dann eine Komponente, die sich um das Einsteigen können kümmert und eine weitere für's Fliegen. Vermutlich noch die eine oder andere mehr, um's single purpose und modular zu halten. Wenn du so etwas abstraktes hast, das eigentlich gar nicht so richtig Teil deiner Szene ist, dann kannst du das Ding auf irgendein ansonsten leeres GameObject schmeißen. Oft kann man die Komponente aber auch direkt mit auf den Button kleben, der deinen Code auslösen soll. Man kann aber auch überlegen, ob man das überhaupt als Komponente braucht und ggf. stattdessen einfach eine normale Klasse bauen.
  9. Also, wenn die Exception bei "this.myText.text = ..." fliegt, dann sehe ich im Code kein Problem, das dazu führen könnte. Entsprechend würde ich sagen, dass kein Objekt durch Drag and Drop im Inspektor referenziert wurde. Wenn du das doch gemacht hast, ist das wahrscheinlichste Problem, dass du dieses Script hier mehrfach in deiner Szene hast, und die Instanz, bei der diese Methode aufgerufen wird, da nichts zugewiesen hat.
  10. Moin! Würde helfen, wenn du den relevanten Code einmal zeigen würdest
  11. Moin! Static gibt's ja nicht nur einfach. "Static" steht für eine Vielzahl an einzelnen Flags. Einige davon haben mit Performance überhaupt nix am Hut: "Contribute GI", "Navigation Static", "Off Mesh Link Generation" und "Reflection Probe Static". "Occluder Static" und "Occludee Static" beziehen sich auf Occlusion Culling, also das Nicht-Rendern von Dingen, bei denen Unity sich sicher ist, dass sie sowieso gänzlich verdeckt werden. Das anzuschalten macht aber überhaupt nichts, wenn du das Occlusion Culling-System nicht auch nutzt. "Batching Static" erlaubt es Unity, das Rendern von Meshes mit gleichem Material in einem Rutsch in Auftrag zu geben. Das reduziert Draw Calls und kann gut für die Rendering-Performance sein. Damit da spürbar was passiert, müssen die Meshes sich aber eben ein Material teilen.
  12. Ah okay... Dann schau dir mal das hier an: https://docs.unity3d.com/Manual/class-SpriteMask.html So ein Ding würde ich mit einem Tween schrumpfen lassen.
  13. Für so simple Sachen ist es vernünftig, Tweens gegenüber "echten" Animationen in Erwägung zu ziehen. Anstatt da einen so derartig simplen AnimationClip überall zu verteilen, kannst du auch einfach mit einer Coroutine die Größe immer weiter runter schrauben. Oder, und das würde ich hier empfehlen: Du benutzt ein beliebiges Tween-System. Damit sagst du "nimm dieses Objekt und animiere es über die nächsten x Sekunden hinweg auf Größe 0". Dann kannst du noch die Zerstörung des Objekts an das "Tween fertig"-Callback dranhängen und fertig bist du.
  14. Sascha

    dauer tasten druck

    Moin! Ich weiß nicht genau, wie du auf dieses Forum kommst, aber hier geht es um Spieleentwicklung mit Unity, nicht um First Level Tech Support. Für den Fall, dass trotzdem jemand was dazu sagen will, habe ich das Thema mal aus dem Entwickler-Bereich heraus verschoben.
  15. Ich würde nur halt wollen, dass der Teil des Spiels, in dem ich wegen des Kampfes gerade nicht bin, eingefroren ist. Ich hätte keine Lust auf die Art von Bugs, die entstehen kann, wenn da noch irgendwelche Logik im Hintergrund weiter läuft.
  16. Moin, bei UML geht's immer darum, dass andere verstehen, was du da gebaut hast und was du dir dabei gedacht hast. Drölf mal String zu schreiben gibt kaum eine sinnvolle Information; aber gar kein Parameter suggeriert dass da nur etwas committed wird und nicht dass du da erst deine Daten übergibst. Der einzige Grund, warum du nicht Variante 3 nehmen willst, ist, dass sie ewig lang ist. Aber das ist kein UML-spezifisches Problem, das ist einfach ein Problem mit deiner Methode. Wenn du so viele Parameter hast, ist das einfach eine unschöne Methodensignatur, UML hin oder her. Was üblich wäre, wäre eine "Person"- oder "Customer"-Klasse, und du übergibst einfach eine Referenz auf eine Instanz davon.
  17. Moin! Mein letzter Stand ist, dass es nach wie vor keine Möglichkeit gibt, eine Szene zu deaktivieren. Was du machen kannst, ist alle Root-GameObjects der Szene zu deaktivieren, oder noch simpler, alle Root-GameObjects einem neuen GameObject unterzuordnen. Die zweite Variante ist ganz hübsch, aber es ist auch leider ein bisschen eklig, dass man dann immer drauf aufpassen muss, dass man nirgendwo den Parent auf null setzt, sonst fliegt das betroffene GameObject aus dem Deaktivierungs-System heraus. Naja gut - wenn in deiner theoretisch deaktivierten Szene immer noch irgendetwas passiert, hast du das Problem so oder so. In beiden Fällen hast du Scene.GetRootGameObjects als Einstiegspunkt. Du musst Variante 2 nämlich nicht unbedingt im Editor machen, sondern kannst in Start oder bei einer anderen Gelegenheit damit alle Objekte raussuchen und einem automatisch generierten GameObject unterordnen.
  18. Moin! Bildschirme haben unterschiedliche Seitenverhältnisse. Ein 16:9-Bildschirm ist breiter als ein 4:3-Bildschirm. Deshalb kann man Dinge auf Bildschirmen nicht immer gleich anzeigen. Die Möglichkeiten sind: Auf dem breiteren Bildschirm kann links und rechts mehr sehen. Das ist das, was Unity standardmäßig macht und das, was auch dein Canvas Scaler macht, wenn du den Regler ganz nach rechts schiebst. Das Bild wird vergrößert, damit links und rechts gleich bleiben. Dafür rutschen natürlich oben und unten Teile des Bilds heraus. Das macht der Canvas Scaler mit dem Regler ganz links. Das Bild wird verzerrt. Nicht unbedingt, was man möchte. Es gibt dafür keine simple Lösung, die immer funktioniert. Deshalb tun sich Entwickler auch oft ein bisschen schwer mit Widescreen Support. Was du machst ist, dass du deinen UI-Elementen mit Ankern sagst, wie sie sich verhalten sollen. Sie können zum Beispiel an die Seite geankert werden und gehen dann mit breiter werdendem Bild mit nach außen. Oder sie sind in der Mitte verankert und tun das nicht. Du kannst auch angeben, dass deine Elemente sich mit strecken sollen. Das, zusammen mit den für dich richtigen Einstellungen im Canvas Scaler, und du baust ein UI, das sich vernünftig an verschiedene Auflösungen anpassen kann. In der Game View kannst du dabei zum Testen verschiedene Auflösungen einstellen.
  19. Moin! Ich hab ein bisschen mit UI Toolkit gearbeitet, aber nicht so viel dass ich mehr als raten könnte. Kann es sein, dass dein UIDocument nicht dieselbe Referenzauflösung hat wie das Spiel selbst? So wie das bei UGUI mit dem Canvas Scaler ist. Ich würde einfach mal schauen (oder ggf. direkt testen) welche Positionen die vier Ecken darstellen. Und dann kannst du mit WorldToViewportPoint eine Position auf dem Normalquadrat (0, 0) bis (1, 1) kriegen und sie dann auf das UI-Rechteck mappen. Sobald du verstanden hast, wo die Werte herkommen, versteht sich.
  20. Ohne eine halbwegs brauchbare Beschreibung des Problems wird das nix.
  21. Genau! Interpolation hat aber halt auch nix mit Physik oder Kollision zu tun Freut mich, dass es das war
  22. Der Code sieht in Ordnung aus, soweit ich das sehen kann. Meine erste Idee wäre, dass da vielleicht der Rigidbody irgendwie Interpolation machen will... ist der auf Interpolate gestellt?
  23. Moin! Beide Links 404en. Ist dein Repo privat?
  24. Das kannst du machen, wie du willst. Wenn du die Bilder mit einfügst, wird dein Spiel entsprechend groß, und es dauert, bis es heruntergeladen ist. Wenn du die Bilder online hostest und dem Spiel beibringst, wie sie herunterzuladen sind, dann braucht man zum Spielen eine aktive Internetverbindung (was z.B. unterwegs mit dem Handy nerven kann). Du kannst dann aber natürlich auch cachen, also Bilder rechtzeitig herunterladen und dann schon mal parat haben. Vor allem aber musst du nicht alle Bilder auf einmal herunter laden, sondern kannst einzelne oder Gruppen laden. Hat beides seine Vor- und Nachteile, daher musst du dir Gedanken machen, was du haben willst. Machbar ist jedenfalls beides.
  25. meinInput.text = meineStringVariable; Wenn rechts vom = der Name einer Variablen steht, dann wird der Wert dieser Variablen genommen und auf der linken Seite zugewiesen.
×
×
  • Neu erstellen...