Jump to content
Unity Insider Forum

Leaderboard


Popular Content

Showing content with the highest reputation since 09/20/2018 in all areas

  1. 4 points
    Hi, ich habe in den letzten zwei Jahren immer wieder an einem Flüssigkeit Simulations Shader gearbeitet und seit Mitte letzten Monats ist er jetzt im AssetStore erhältlich. Mit Fluid Flow kann man in Echtzeit simulieren wie beispielsweise Blut oder Farbe an einer Oberfläche herunter fließt. Es ist keine 100% physikalisch korrekte Simulation, sondern das Asset versucht mit möglichst geringen Performance Einbußen überzeugend Flüssigkeit zu simulieren. Dazu werden die Berechnungen mithilfe eines Compute Shaders auf die Grafikkarte ausgelagert. Compute Shader benötigen allerdings mindestens DirectX 11 oder OpenGL 4.3 support! Zudem sind Android und iOS momentan nicht unterstützt! Fluid Flow Echtzeit Flüssigkeit Simulation dynamisches Anpassen der Flussrichtung unterstützt animierte Objekte Tropfen* * werden asynchron von der GPU zur CPU gelesen. Dieses Feature gibt es erst seit Unity 2018.2, und mit OpenGL wird es nicht unterstützt! Demo (win): https://drive.google.com/drive/folders/1ewcJn2Cc56Pcg3IVXPgvDDYucfRrU2mg Asset Store: https://assetstore.unity.com/packages/vfx/shaders/fluid-flow-143786
  2. 3 points
    Hier hast du einge Möglichkeiten: https://docs.unity3d.com/Manual/PositioningGameObjects.html Interessant für dich dürften wohl Surface Snapping oder Vertex Snapping sein.
  3. 2 points
    Warum willst du überhaupt FixedUpdate für eine lineare Animation benutzen? Gibt's doch gar keinen Grund für. yield return null; rein und fertig. Nein. Standardmäßig (!) ist der Zielwert (!) 50 Mal pro Sekunde. Aber ein exaktes einhalten einer konstanten Frequenz ist gar nicht möglich. Lies dir am besten mal das hier durch: http://blog.13pixels.de/2019/what-exactly-is-fixedupdate/
  4. 2 points
    SRY Aber ich muss das jetzt einfach mal so sagen. Anscheinend hast du dich noch nicht wirklich mit programmieren auseinander gesetzt. Durch stures Copy&Paste wirst du auf dauer nicht weit kommen. Schau dir am besten erstmal die C# Grundlagen an. Dann solltest du deinen fehler auch selbst erkennen.
  5. 2 points
    Der erste Testlauf einer Kartengenerierung mit PerlinNoise ist erfolgreich abgeschlossen. Etwas mehr fein Tuning beim Algorithmus und mehr als 3 Kartenfeldtypen sollten es aber schon sein sonst ist das nicht sehr ansehnlich. Aber immerhin, es funktioniert und geht ins nächste NightlyBuild.
  6. 2 points
    Ich hatte nicht viel Zeit für dein Mesh, aber ich konnte erkennen, dass deine Wichtungen nicht gut sind. Die Meshpunkte haben alle Wichtungen von allen 5 Joints des Armes. Die Punkte , die von jedem Joint die gleiche Wichtung haben, sehen gut aus, die die unterschiedlich gewichtet sind, verzerren schon beim Einfügen in der Szene. Sobald du einen Unterjoint drehst, verstärkt sich die Verzerrung, was klar ist, denn der Überjoint bleibt ja stehen. Warum von vornherein, schon Verzerrungen da sind, weiß ich jetzt erstmal nicht. Kann aber an der Animationsspur liegen. Evtl. ist dort im ersten Frame schon eine Änderung der Drehung der Joints drin. Egal. Seh zu, dass deine Punkte maximal von 2 Joints Wichtungen bekommen (an den Gelenken). Und versuch's erstmal nur ohne Animationsspuren um den Fehler einzugrenzen.
  7. 2 points
    Moinsen! Ich habe eben mal meine Script Templates hochgeladen. Dieses Bild sagt vermutlich einiges: Alles schön sortiert, außerdem zusätzliche Templates für ScriptableObjects oder Editor-Scripts. Sind auch ein paar Änderungen gegenüber den Vanilla-Templates drin. Windows Line Endings und überall 4 Leerzeichen statt Tabs und so. Wenn ihr Sachen objektiv besser findet, immer her mit den Merge Requests, wenn subjektiv, gerne forken. Hier gibt's das Ganze: https://gitlab.com/FlaShG/unity-script-templates Anleitung steht in der Readme.
  8. 2 points
    Anstatt durchegehend einen Wert hochzuzählen, könntest du auch konstant die Startzeit speichern. Dann erhöhst du nicht mehr in jedem Update deinen Timer-Wert, sondern rechnest ihn aus, indem du diesen Wert von der aktuellen Zeit abziehst. Dann kann man so oft Pause machen, wie man will, da sich der Wert dadurch nicht ändert.
  9. 1 point
    Wenn ich jetzt gerade mal so in meine magische Glaskugel schau, dann sehe ich, dass du einen Fehler gemacht hast! Denn wenn nicht, würde es genauso funktionieren, wie bei dem Tutor aus dem Video. Hilft dir das? Nö? Schade, aber ich (wir) kann (können) dir nicht helfen, wenn du uns lediglich erzählst was passiert und dann ein Bild zeigst, wie deine Szene aussieht. Stell dir mal vor, ich würde dir erzählen, dass bei mein Auto immer eine Warnleuchte im Armaturenbrett leuchtet. Und dann zeige ich dir zusätzlich ein hübschen Foto, wie mein Auto auf einem Parkplatz steht. Jetzt müsstest du mir doch eigentlich sagen können, was mit meinem Auto los ist! Nein? Ist doof, oder? Aber so ist das nunmal wenn man nur irrelevante Infos bekommt. Also geh mal in dich und überlege dir, was wir uns anschauen sollten um dir helfen zu können. Kleiner Tipp: Ein Screenshot von der Szene ist es nicht!
  10. 1 point
    Hier sind ein paar gelistet: https://de.wikipedia.org/wiki/Kürzester_Pfad Der üblichste Algorithmus für dein Problem ist der Dijkstra-Algorithmus. Der ist auch vergleichweise noch recht einfach zu implementieren.
  11. 1 point
    Versuche wirklich mal den <>-Knopf über dem Textfeld Dröseln wir das mal ganz entspannt auf. Wie schon gesagt, sind solche Zahlencodes doof und wirklich nicht nötig. Bei der Antwortmethode ("ja oder nein gedrückt") meinte ich ja schon, dass du da einfach mehrere Methoden haben kannst. Statt public void MotherEat(int answer) { if (answer == 0) { FOO } else if (answer == 1) { BAR } } machst du public void MotherEatYes() { FOO } public void MotherEatNo() { BAR } Wenn du willst, kannst du so weiterprogrammieren. Grundsätzlich kann ich dir aber sagen, dass es immer besser ist, solche Strukturen in Daten zu definieren als in Code. Statt also lauter Methoden anzulegen, die alle auf dieselbe Art funktionieren, ist es besser, nur eine einzelne zu haben, die je nach Zustand des Objekts anders arbeitet. Im Optimalfall hast du dann am Ende kein einziges String-Literal mehr in deinem Code. Aber... das muss ja auch nicht alles auf einmal passieren. Solange du einen Weg findest, der für dich funktioniert, ist das schonmal gut. Du darfst dich dann halt nur nicht wundern, wenn du immer mehr schwierig zu lösende Probleme kriegst, je mehr du auf solchem "funktioniert irgendwie"-Code aufbaust. Was ich noch wichtig fände, wären private Hilfsmethoden. Hier mal ein Beispiel: public void Foo() { if (something) { // warte 1 sekunde // ändere den text zu "Eins" // warte 1 sekunde // buttons erscheinen } else { // warte 1 sekunde // ändere den text zu "Zwei" // warte 1 sekunde // buttons erscheinen } } Die Kommentare stehen hier für zwei sehr ähnliche Abläufe, die sich nur minimal unterscheiden. In so einem Fall solltest du eine private Hilfsmethode schreiben, die diesen Ablauf durchführt, und die Unterschiede über Parameter einstellbar hat: public void Foo() { if (something) { ShowTextAndButtons("Eins"); } else { ShowTextAndButtons("Zwei"); } } private void ShowTextAndButtons(string text) { // warte 1 sekunde // ändere den text zum wert des text-Parameters // warte 1 sekunde // buttons erscheinen } Auf diese Weise musst du den Code nicht immer kopieren. Und wenn er sich in der Zukunft doch mal ändern soll, musst du nicht an vielen Stellen, sondern nur an einer einzigen diese Änderung vornehmen. Genau so eine private Hilfsmethode hatte ich dir eingangs gepostet. Mit ein paar Parametern kannst du wunderbar eine Coroutine erstellen, die sich immer wieder verwenden lässt.
  12. 1 point
    Da gibt's verschiedene Varianten. Statt deine Texte in deine Methode einzubauen, kannst du auch direkt die strings übergeben: private IEnumerator DoMonologue(string[] texts, float delay) { var wait = new WaitForSeconds(delay); textComponent.text = texts[0]; for (var i = 1; i < texts.Length; i++) { yield return wait; textComponent.text = texts[i]; } } Auf lange Sicht kannst du auch eine Klasse für Monologe oder Dialoge schreiben, und die stattdessen da rein tun. Da kannst du dann beliebig schick werden und verschiedenste Erweiterungen einbauen. Sei es unterschiedlich lange Zeiten pro Satz oder ein wechselndes Charakter-Portrait je nach Situation. P.S. Du kannst deinen Code auch so lesbar machen, und zwar mit dem <>-Knopf
  13. 1 point
    Also es ist ja so, dass du irgendwo deine Listen abarbeiten musst. Ob das nun direkt in einer Methode ist oder woanders, ist erst einmal egal. Ich persönlich würde es aber nicht innerhalb der Methode machen, in die der Button etwas sendet. Die Methode dient ja lediglich dazu, zu registrieren, dass ein UI Element etwas gemacht hat. Du kannst da einfach eine Variable verändern, die ein anderer Codebereich für die Listenabarbeitung nutzt. Das würde das Ganze übersichtlicher machen, denn die Buttons wären aus der Verarbeitung dann einfach heraus genommen. Aber wie gesagt; irgendwo musst du duch die Listen gehen. Entscheide selbst und lerne dabei ob es gut war oder eher nicht. Ich selber verändere ständig meine Herangehensweise bei neuen Projekten denn ich habe auch noch keinen goldenen Weg gefunden. Aber es wird jedes Mal besser!
  14. 1 point
    Willkommen! Schön, dass du uns gefunden hast.
  15. 1 point
    Gibt da verschiedene brauchbare Varianten, aber lauter Listen, die eine versteckte semantische Verbindung haben, dass Werte mit demselben Index zusammengehören, ist keine davon. Du möchtest in jedem Fall Objekte haben und dann eine Liste dieser Objekte, ob das jetzt ScriptableObjects sind oder nicht. Du kannst z.B. eine neue Klasse SwordInstance anlegen, die irgendwie so aussehen könnte: public class SwordInstance { public Sword swordClass { private set; get; } public int someVariableData; public SwordInstance(Sword swordClass) { this.swordClass = swordClass; } } Wenn du dann deinen Laden hast und du kaufst davon ein Schwert, dann erstellst du eine neue Instanz dieses Schwerts. Das ScriptableObject enthält nur die immer gleichbleibenden Daten, während die SchwertInstanz neben der Referenz auf die Schwert-Klasse die ganzen variablen Daten enthält. public void BuySelectedSword() { var swordClass = swordsForSale[displayIndex]; playerInventory.AddSword(new SwordInstance(swordClass)); } Da gibt's dann wieder neue offene Fragen, wie man das baut, aber... so als Beispiel dafür, wie du ScriptableObjects mit dynamischen Laufzeitdaten kombinieren kannst.
  16. 1 point
    Zunächst möchte ich mich mal ordentlich entschuldigen - da hat Sascha vollkommen recht - das dumme Genöle von mir bringt natürlich gar nichts ! Ich hatte eine sch.... Tag und dann noch die Errors....... Nachdem ich alles gelöscht und mich etwas beruhigt hatte Gehirn eingeschaltet und das Ganze von vorne: Hub installiert, die letzte 18er Version wieder installiert, Altes Projekt geöffnet, (war noch auf Festplatte) auch hier wieder einige Errors - div. Assets (AQUAS Water !!) reloaded, Projekt geschlossen - Projekt geöffnet VOILA - ALLES GEHT WIEDER !!! Mit der 19er warte ich noch.
  17. 1 point
    TextMeshPro ist doch jetzt Standartmäßig drin. Am besten du suchst dir die Textur und machst dort deine schrift drauf. Ist denke ich am performantesten (wird das so geschrieben?🤯).
  18. 1 point
    Ich hab's! Ich habe den Layer meiner Tilemap von Default auf eines der anderen fünf Vorlagen umgestellt. Vielen Dank für deine Unterstützung!
  19. 1 point
    Als Erstes würde ich dir empfehlen solche Sachen einfach zu animieren. Dafür musst du natürlich erst einmal lernen, wie das mit Animationen so funktioniert. Aber glaub mir, es lohnt sich. Zu deinem Problem will ich aber auch noch was schreiben. Du fährst eine Schleife durch, bei der du den Alphawert einfach solange erhöhst, bis er 255 erreicht hat. So eine Schleife wird komplett ausgeführt und erst danach geht es im Code weiter. Da ist es komplett egal, ob du innerhalb der Schleife eine Coroutine startest. Das Einzige, was es bewirkt: Diese Coroutine wird 256 mal in diesem einen Frame gestartet. Sie würde dir dann auch nach der Sekunde Verzögerung 256 mal etwas ausgeben, wenn du hinter dem Yield etwas hättest, was ausgegeben würde. Da ist aber nichts! Das was du da machst, passiert innerhalb eines Frames. Aus diesem Grund wirkt es so, als würde der Button sofort den neuen Zustand annehmen.
  20. 1 point
    Hi. Du kannst die UI auch als Prefab anlegen und diese in den verschiedenen Szenen einsetzen. Eine Änderung wäre dann in jeder Scene zu finden. Beim Game Over wäre die Möglichkeit zum nächsten Level zu gelangen nicht gut! Welche Probleme hast Du mit der Funktion Game Over? Hast Du schon verschiedene Szenen mit verschiedenen Level?
  21. 1 point
    == führt einen Vergleich durch. + zwischen zwei Strings konkateniert die Strings, schreibt sie also hintereinander. if (other2.tag == "Quader1" + "Quader2" + "Quader3" + "Quader4" + "Quader5") ist also gleichbedeutend mit if (other2.tag == "Quader1Quader2Quader3Quader4Quader5") Leider lässt sich das nicht mal eben innerhalb dieser einen Zeile fixen, weil OnTriggerEnter(2D) nur einmal aufgerufen wird, wenn ein neues Objekt den Trigger berührt. Dieses Objekt wird als Parameter übergeben (heißt bei dir "other2"). Welche Objekte sonst noch in deinem Trigger sind, ist OnTriggerEnter(2D) gänzlich egal. Du versuchst daher abzufragen, ob das eine neue Objekt alle fünf Tags hat, was natürlich nicht geht. Was du ja aber wirklich wissen willst ist, ob alle fünf Tags über Objekte im Trigger vertreten sind. Dafür musst du ein bisschen was dazu bauen. Erstmal die Frage: Brauchst du überhaupt fünf Tags? Ich lass die Sache mit "niemals überhaupt Tags benutzen" erstmal in der Kiste, aber ich vermute einfach mal, dass du immer nur ein Objekt pro Tag hast. Dass die fünf Objekte unterschiedliche Tags haben, benutzt du hier ja gar nicht, da du einfach nur schaust, ob alle fünf da sind. Du könntest dann einfach einen Tag "Quader" haben und schauen, ob (alle) fünf Objekte mit diesem Tag im Trigger sind. Um das zu machen, gibt es mehrere Möglichkeiten. Ich denke, eine einfach nachzuvollziehende ist ein Zähler. Dafür brauchst du eine int-Variable, die hochzählt, wenn ein "Quader"-Objekt den Trigger betritt, und wieder herunterzählt, wenn einer davon der Trigger wieder verlässt. Ist der Zähler bei 5 angekommen, wissen wir, dass alle 5 Objekte im Trigger sind. Das würde dann so aussehen: private int objectsInTrigger = 0; private void OnTriggerEnter2D(Collider2D other) { if (other.CompareTag("Quader")) { // Erhöhe um eins objectsInTrigger++; // Schaue ob es fünf sind if (objectsInTrigger == 5) { Debug.Log("Nächstes Level"); } } } private void OnTriggerExit2D(Collider2D other) { if (other.CompareTag("Quader")) { // Senke um eins objectsInTrigger--; } } Das kann man dann noch aufhübschen, z.B. indem man die 5 nicht hardcoded, sondern als Variable einfügt, die man im Editor setzen kann. Dann kannst du jedes Mal, wenn du dieses Script auf ein GameObject tust, eingeben, wie viele Quader benötigt werden. So kannst du mit demselben Script, ohne den Code abändern zu müssen, mehrere Level bauen, in denen verschieden viele Quader gebraucht werden. Sonst noch so: CompareTag ist besser als == "meinTag", da es dir eine Fehlermeldung wirft, wenn der Tag gar nicht existiert, z.B. weil du dich vertippt hast. Auch mit CompareTag sind Tags immer eine potentielle Fehlerquelle. Ich empfehle dringend, auf lange Sicht Tags komplett sein zu lassen. Wenn du mal Lust hast, kann ich erzählen, wieso... aber im Moment führt's einfach zu weit.
  22. 1 point
    Btw kannst du statt immer Input.GetKey(w), Input.GetKey(s) etc. zu benutzen einfach mit Input.GetAxis(""Vertical") und das selbe für Horizontal. Finde so wird der Code viel übersichtlicher und es geht beim zweiten mal schneller. Kannst es ja mal nachlesen wen du willst https://docs.unity3d.com/ScriptReference/Input.GetAxis.html Gibt auch genug Youtube Tutorials dafür.
  23. 1 point
    Es lag beim Rig Einstellung, war auf Legacy eingestellt, hab es auf Generic getan und schwubdiwub geht alles wie gehabt. Lg Ricky-W
  24. 1 point
    Naja, so wirklich viel ist das auch wieder nicht. Das teuerste an der Sache ist das Wurzelziehen, und das kann man bei Vergleichen sogar weglassen. Schauen wir doch mal ganz genau: public static bool CheckIfCloserThan(Vector3 a, Vector3 b, float maxDistance) { var maxDistanceSquared = maxDistance * maxDistance; var distanceSquared = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z); return distanceSquared <= maxDistanceSquared; } Diese Funktion checkt, ob der Abstand zwischen a und b kleiner-gleich der gegebenen Maximaldistanz ist. Wir benutzen in der Mitte nicht einfach (a - b).sqrMagnitude, weil das etwa 4-Mal so langsam ist. Es bleibt damit bei vier Multiplikationen, sechs Subtraktionen und einem Kleiner-gleich-Vergleich. Das sind elf FLOPS. Dagegen kann ein Physik-Check mit Collidern gar nicht ankommen. Da ist ja erstmal der AABB Check. Der alleine ist im Zweifelsfall ja auch schon gerne mit neun FLOPS und drei Bool-Abgleichen am Start. Und danch kommt erstmal der richtige Kollisionscheck. Wenn es also wirklich nur um den Abstand zwischen zwei Punkten geht, nicht immer gleich verrückt machen lassen. So viel ist da gar nicht los, und mit einer simplen Funktion wie der da oben bist du in jedem Fall schneller unterwegs als mit der Physik-Engine. Einer Kernaussage von @malzbie muss ich außerdem grundsätzlich zustimmen: Und ich würde da hinzufügen: Alles unter fünfstellig zählt für mich hier als "wenige". Mal so als Vergleich: Meine Funktion oben läuft bei mir auf dem PC in unter 10ns. Eine Nanosekunde entspricht 0,000001ms. Das heißt, dass du die Funktion schon 100.000-Mal aufrufen musst, damit ihre Benutzung 1ms kostet. Und das sequenziell, denn solche Berechnungen kannst du wunderbar parallelisieren oder batchen. Performance ist erst dann ein Problem, wenn es ein Problem wird. Zu versuchen, irgendwelche Performance-Optimierungen zu machen, bevor der Profiler überhaupt Probleme aufzeigt, ist schlichtweg keine gute Idee. Kümmer dich darum, dass dein Spiel funktioniert, achte darauf, dass du gute Code-Qualität hast (Robustheit, Modularität, geringe Redundanz...). Und wenn du dann irgendwann Performance-Probleme feststellst, dann kannst du mit dem Profiler die Problemstelle finden und verbessern.
  25. 1 point
    Du kannst das im Inspector im Bereich MeshRenderer umschalten. Get natürlich auch über script umzuschalten. Renerer myRend = GetComponent<Renderer>(); myRend.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; Aber trotzdem hast du viel zu viele Shadowcaster. Kann es sein, dass deine Objekte aus ganz vielen Einzelpolygonen bestehen? Leg mal nur ein Unity Würfel in die Szene und schau dir die Werte an. Dann füge mal einen manupulierten Blender-Würfel der Szene hinzu und schau dir die Werte wieder an.
  26. 1 point
    So kann man das aber nicht rechnen. Machste noch ein 145es Objekt landest du ja auch nicht bei 0 Schau mal, ob du die Objekte in Batches rendern kannst. Außerdem: Wie viele Polygone sind da insgesamt im Spiel?
  27. 1 point
    Ein GetKeyDown ist das lomplette Update über aktiv und kann so nicht ausgewertet werden. An sich ist deine If-Else Abfrage schon soweit ok. Ob du da aber else If nutzt oder nur ganz viele If hintereinander oder eben über Switch die Auswertung machst, ist in deinem Codefall egal. Aber trotzdem nochmal zu den Basics. Eine If Abfrage ist eine boolsche Überprüfung ob eine gewisse Bedingung wahr ist. Diese Bedingung kann aus mehreren Teilen bestehen. Also in deinem Fall fragst du ja z.B. ganz oben ab, ob du im Menü bist. Ist das Ergebnis true, wird alles innerhalb dieser If-Abfrage ausgeführt. Wenn nicht, wird der kompeltte Block übersprungen . Würdest du jetzt noch ein Else nutzen, könntest du im Falle, dass das Ergebnis false ist, etwas anderes ausführen. Also auf deutsch: Wenn der Zustand wie gewünscht ist, dann mache etwas, wenn er nicht so ist, dann mache etwas anderes. Ein else if ist eine weitere Abfrage, bei der du wieder eine Bedingung einfügst. Also wenn die Grundbedingung nicht erfüllt ist, dann mache etwas anderes, aber nur wenn die weitere Bedingung auch erfüllt ist. In deinem Falle geht es um die menüPosition. Wenn in Position 0 dann mache etwas, wenn nicht dann mache etwas anderes, aber nur wenn ich in Position 1 eins bin. Das kann man zwar mit else if abbilden, aber in Endeffekt kann man ja nur auf einer Position sein, deswegen brauchst du kein else und könntest einfach nur lauter ifs nutzen. Aber wie gesagt, dein Problem sind nicht die else ifs sondern der Zustand der Taste, der komplett bis zum nächsten Frame erhalten bleibt. Du hast jetzt 2 Möglichkeiten. Entweder dein Submenü (und der Tastaturbefehl da drin) wird im Code vor dem Hauptmenü abgefragt, was zwangsläufig erst im nächsten Frame ausgewertet werden kann, nachdem weiter unten ja erst erkannt wird, dass du im Menü bist, oder aber du baust eine Variable für die Taste ein, die den Code erkennen lässt, dass es immer noch der Erste Tastendruck ist. Also beim setzen des activeSubmenu setzt du auch die Variable isPressed für den Tastendruck. Mit GetKeyUp setzt du diese Variable wieder auf false. in deinem Submenü fragst du zum Tastendruck zusätzlich noch ab, ob isPressed denn false ist. Und nur dann wird der 2te Tastendruck ausgewertet. Deine ganze Routine braucht jetzt also 2 Frames.
  28. 1 point
    Hi. Also fangen wir mal am Anfang an. Du hast mehrere Regionen, die unterschiedlich aussehen und wahrscheinlich auch unterschiedliche Formen haben, und möchtest mit diesen Regionen interagieren. Also wenn die Maus über einer dieser Regionen ist, soll sie sich einfärben, wenn es die Regel zulässt. Dieses Problem ist recht leicht zu lösen, denn es gibt die Möglichkeit einen Ray von der Camera aus in Richtung Mauszeiger (und darüber hinaus) zu senden. Suche mal in der Unity Scripting Hilfe nach Physics.Raycast. Dieses Beispiel sthet da etwas weiter unten: using UnityEngine; public class ExampleClass : MonoBehaviour { void Update() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, 100)) print("Hit something!"); } } In der Hilfe siehst du auch, dass mit diesem Raycast ganz viel Info zurück kommen kann, die dir bei der Auswertung helfen werden. Der Ansatz, dass du eine Grafik im Untergrund hast, und darüber unsichtbare Objekte für jede Region ist gut. Denn du musst ja irgendwie Grenzen schaffen. Also solltest du für jede Region ein 3D Objekt haben, was den Grenzverlauf der Region folgt, also z.B. wie Australien aussieht. Dieses Objekt bekommt einen Meshcollider und liegt genau über der entsprechenden Region. Ob nun dieses Objekt dann eine Farbe annimmt oder ob dafür dann ein Extra Grafikobjekt genutzt wird, ist ne Designfrage. Probiere einfach mal diverse Ansätze aus. Ich würde jetzt nicht den Farbcode des Untergrundes ermitteln wollen um somit zu erkennen auf welcher Region man ist. Das ist viel zu kompliziert und Fehleranfällig, denn wer weiß ob jedes Pixel in der Region wirklich die gleiche Farbe hat. Kompressionen können da schon mal probleme Verursachen. Was ich nicht so ganz verstehe. Willst du jetzt ein erhabenes3D Spielfeld haben, wo echte Berge zu erkennen sind? Oder ist es flach?
  29. 1 point
    Habe eigentich immer wonach ich gesucht habe ein Tutorial gefunden 🙃. Alllerdings sind viele davon auf Englisch, sollte man also etwas Englisch können. Als CC0 (Creative Commons) gekennzeichnete Werke dürfen frei genutzt, bearbeitet und auch für kommerzielle Zwecke verwendet werden ohne irgendwelche Credits. Das einzige was du nicht darfst, ist sie zu nehmen und sie z.B. im Asset-Store zu verkaufen. Kann ich gut nachvollziehen. Mit dem was man gerne macht auch noch Geld verdienen ist ja jedermanns Traum.
  30. 1 point
    Mein Tipp. Mache die Unity Tutorials durch, die enthalten sind. Dort bekommst du einen Einblick auf die komplexität des Programmierens und lernst schon etwas programmieren. Wichtig ist bei dem Plan ein solch großes Projekt zu machen, dass du den Aufwand in kleine Teile teilst. Wenn man das ganze umsetzen möchte wird man schnell frustriert, bei keineren Teilen hat man Erfolgserlebnisse, wenn diese klappen.
  31. 1 point
    Schön zu sehen das ihr am Ball bleibt! Die visuelle Darstellung vom Treffer des Gegners ist sehr gut dargestellt. Man spürt die Wucht förmlich.
  32. 1 point
    Der ist wirklich super geworden!
  33. 1 point
    Hallo! Ja, indem du dir Programmierkenntnisse aneignest, während du daran arbeitest. Schritt eins: Genau das überlegen. Es gibt keine festlegbare "gute" Reihenfolge dafür. Deshalb ist der erste Schritt immer, die Gesamtaufgabe in kleinere Aufgaben zu zerteilen. Ein Issue Tracking-System hilft dabei sehr. Repository-Dienste (Github, Gitlab, ...) haben so etwas normalerweise schon für dich parat, aber wenn du dich noch nicht mit so etwas beschäftigen willst, kannst du auch einfach mit Trello anfangen. Wofür Tutorials da sind. Womit wir wieder bei Frage 1 sind. Du darfst einfach nicht erwarten, dass du dir ein Spiel, das nicht komplett von der Stange sein soll, einfach zusammenklicken kannst. Darfst nur so-und-so viel Geld verdienen mit deinem Spiel, darüber musst du die Pro kaufen. Ansonsten nichts nennenswertes.
  34. 1 point
    Öh... habe schon mehrere Male etwas geschrieben, hab's dann aber wieder gelöscht, ohne es abzuschicken. Anstatt groß darüber nachzudenken, würde ich die Herangehensweise leicht ändern. public static int RandomWithSteps(int min, int max, int interval) { var range = max - min; var maxIntervalCount = range / interval; var intervalCount = Random.Range(0, maxIntervalCount + 1); return min + intervalCount * interval; }
  35. 1 point
    ScriptableObject brauchste nicht, du kannst eine Textur direkt als .asset-Datei speichern. AssetDatabase.CreateAsset(myTexture, "Assets/My Texture.asset"));
  36. 1 point
    Es klingt zumindest logisch nicht ständig eine längere Suche durchzuführen. Vor allem wenn das eigentlich nicht zwingend so sein muss. In der Dokumentation schreibt Unity nur "For performance reasons, it is recommended to not use this function every frame". https://docs.unity3d.com/ScriptReference/GameObject.Find.html Ich arbeite aktuell an einem Lernprojekt und musste bisher kein einziges mal die Find Funktion nutzen. War bisher nicht nötig. Über ScriptableObjects und das Event System lässt sich das alles schön referenzieren bzw. Objekte miteinander kommunizieren. Übrigens nochmal danke für dein Architektur Repo! Ist sehr nützlich.
  37. 1 point
    Das ist interessant! Ich mache durchaus regen Gebrauch von Invoke. Hat die Methode mit dem String als Methodenname irgendein oder wieso haben die Unity Entwickler das nicht bisher verbessert wenn es doch offenbar ohne großen Aufwand besser geht?
  38. 1 point
    Editor ist klar - Scripts für den Editor haben im Build nix zu suchen, also kommen sie nicht in dieselbe Assembly. Plugins und Standard Assets kannst du benutzen, um bestimmte Dinge vor anderen kompiliert zu haben. Ich kann mich gerade nicht daran erinnern, in welchen Fällen das sinnvoll ist, aber ich meine, es gab welche. Prinzipiell wird das mit den Ordnern aber auch zunehmend überflüssig, da wir jetzt Assembly Definitions haben - Die sind wesentlich besser für denselben Zweck geeignet. Bis das mit den Ordnern abgeschafft ist, bleibt es ein Überbleibsel.
  39. 1 point
    Was hältst du davon, ein GameObject zu haben, das sich einfach nur nach der Gravitation ausrichtet, und diesem Objekt die Spielfigur unterzuordnen - diese dreht sich dann relativ zu ihrem Parent?
  40. 1 point
    Wahrscheinlich bewegst du die Kugel nicht über die FixedTime sondern in der Update. Dadurch ist das Ganze nicht mehr synchron. Wenn du Rigidbodys bewegst, dann immer in der FixedUpdate und auch nur mit physikalischen Befehlen um die Physik im Spiel synchron zu halten und richtig berechnen zu lassen. Es sollte schon reichen, wenn du die Interpolation der Rigidbodies auf Interpolate stellst, um das Zittern zu umgehen. Warum hast du denn bei der Kugel die Schwerkraft an? Man sieht im hinteren Bereich des Films, dass die Kugel selbst am Zittern ist, also scheinbar die Schwerkraft gegen dein Bewegungsscript arbeitet.
  41. 1 point
    Um das Problem zu lösen, kannst Du z.B. das Singleton Pattern nutzen. In deiner Sprite Klasse deklarierst Du eine statische Referenz auf sich selbst und setzt diese beim Start. Dann kannst Du von überall auf die eine Instanz zugreifen, ohne statische Dinge zu nutzen, bis auf die Referenz zum Objekt selbst. Beispiel //achtung: pseudo code, nicht funktionsfähig! :D //das hier ist in deiner sprite klasse private static DeineKlasse instance; public static DeineKlasse Instance { get { return instance; } } void Awake() { //hier kann man noch prüfen, ob das singleton schon existiert, aber wir gehen mal davon aus, dass du es nur einmal in der szene hast ;) instance = this; } [SerializeField] private Sprite[] sprites; public Sprite MinimapSpriteIcon(int icon) { return sprites[icon]; } //... irgendeine klasse deinSprite = DeineKlasse.Instance.MinimapSpriteIcon(1)
  42. 1 point
    Uff... das kann man aber leicht falsch verstehen. Instantiate kopiert ein GameObject oder ein ScriptableObject. Es gibt zwei Besonderheiten: Man kann eine Komponente übergeben. In diesem Fall wird das GameObject kopiert, auf dem die Komponente liegt. Es wird eine Referenz auf die Kopie dessen zurückgegeben, was übergeben wurde. Übergibt man also z.B. eine BoxCollider-Komponente, wird das GameObject kopiert, zu dem es gehört, und es wird eine Referenz auf die BoxCollider-Komponente der Kopie zurückgegeben. Um aber mal auf die Schreibweise der Frage einzugehen: Die ist schlicht veraltet. Man braucht schon lange nicht mehr auf ein GameObject zu casten, wenn man ein GameObject reingesteckt hat.
  43. 1 point
    Eine gute Entscheidung. Wollte auch noch was in Richtung 3D Modellierung sagen. Mein Surface damals war glaub 12.5 Zoll. Ich bin ja nicht zart besaited. Aber wenn du darauf arbeiten möchtest, ist das auf dauer sehr anstrengend und man wird schnell müde. So gings mir zumindest. Was ich mir allerdings gut vorstellen kann, wäre ein 17 Zoller. Aber das schränkt natürlich wieder in Puncto Mobilität ein.
  44. 1 point
    Moin, eventuell hilft das Beispiel hier weiter, ein anderer out of the box Weg ist mir nicht bekannt. https://github.com/hallidev/UnityWASAPILoopbackAudio
  45. 1 point
    Hallo, ich glaube da fehlt noch das eulerAngles nach rotation Quaternion.Euler(shotSpawnGun.rotation.eulerAngles.x, shotSpawnGun.rotation.eulerAngles.y, shotSpawnGun.rotation.eulerAngles.z)
  46. 1 point
    https://github.com/JamesNK/Newtonsoft.Json kann ich empfehlen, wenn auch nicht vergleichsweise. Hab's als erstes ausprobiert und hatte danach nicht das Bedürfnis, weiterzusuchen Aber Unitys JSONUtility ist schön einfach zu bedienen - bleib also dabei, bis es anfängt, damit nicht mehr zu gehen.
  47. 1 point
    Super hat funktioniert. Wieder etwas dazu gelernt, ich Danke dir!
  48. 1 point
    Dann werd ich demnächst wohl mal ein bischen damit rumexperimentieren Dankeschön! Jetzt mal ehrlich, in diesem Gespräch hab ich mehr gelernt als in meinem ganzen studium XD
  49. 1 point
    Warum dein Video einen Rotstich hat, kann ich nicht sagen. Vielleicht mag Unity dein Videoformat nicht. Wie ist es denn kodiert? Der Videoplayer ist auch nichts anderes als der Audioplayer, wenn es darum geht Ereignisse abzufragen. Du könntest dem Videoplayer also ein Script geben in dem du dann eine Referenz zum Videoplayer bildest. using UnityEngine.Video; using UnityEngine.SceneManagement; public class videoSteuerung : MonoBehaviour { VideoPlayer myVideo; void Awake () { myVideo = GetComponent<VideoPlayer>(); } Und dann in der Update einfach : if (!myVideo.isPlaying) { SceneManager.LoadScene(1); }
  50. 1 point
    @Denni173: Wenn zwischen 2 Frames mehr Weg zurück gelegt wird, als das Objekt lang ist (bzw. soviel Weg, dassder eine Collider komplett in den anderen eintaucht), dann tunnelt das bewegte Objekt den Collider und wird nicht aufgehalten. Also im Frame davor war es noch knapp for dem anderen Objekt und im Frame danach ist es schon dahinter (oder mittendrin). Bewegt man das Objekt über die Physik, dann wird das ja auch über die Physikzeit gesteuert und die Kollision wird viel besser ausgewertet. Aber auch dann, wird irgendwann der Tunneleffekt eintreten. Aber eben erst viel später. Ob der Collider statisch ist oder nicht, ist total egal. Zum Verständnis hab ich hier ein Tutorial:

Announcements

Hy, wir programmieren für dich Apps(Android & iOS):

Weiterleitung zum Entwickler "daubit"



×
×
  • Create New...