Jump to content
Unity Insider Forum

Leaderboard


Popular Content

Showing content with the highest reputation since 03/01/2019 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. 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/
  3. 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.
  4. 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.
  5. 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.
  6. 1 point
    Ich habe mir das gerade mal bei mir angeschaut. Da ist das so ähnlich. Laut Dokumentation ist im Other bereich das hier drin: Wenn du den Profiler mal pausierst und fährst dann mal mit der Maus im CPU Usage Fenster zu den Spitzen, dann kannst du unten in der Timeline sehen, dass die Zeit fürs Warten drauf geht. Du wirst beim Profiler und bei den Other Threads diverse Semaphore.WaitForSignal Bereiche sehen, die viele Millisekunden lang sind. Um die zusehen musst du aber mal Deep Profile anschalten. Da bekommst du viel mehr Infos. Mach dir um Other ersteinmal keinen Kopf. Um zu sehen, wie deine Framerate außerhalb des Editors ist, musst du dein Spiel einfach mal builden und dann gucken, wieviele FPS wirklich im Normalbetrieb erreicht werden. Ich gehe davon aus, dass du ähnliche Werte wie im Editor ohne Other sehen wirst. Und immer daran denken: Das ist eh nur auf deinem System so! Mit deiner Grafikkarte und deinem Prozessor. Du musst sowieso später mal auf unterschiedlichen Rechnern testen und dann evtl. optimieren.
  7. 1 point
    Nein! Es werden immer erst alle Awakes durchlaufen und dann die Starts. Welches Script aber damit anfängt, ist zufällig, wenn du es in der Sript Order nicht manuell festgelegt hast. Das bezieht sich aber nur auf die Scripts, die gleichzeitig erwachen. Also die, die schon zu Beginn in der Szene sind. Die Scripts, die nachher erst in die Szene geschmissen werden, z.B. beim Instanzieren von Gameobjects, machen es dann sobald sie erwachen. Da ist es egal was die alten Scripts gerade machen. Und nochwas: Ist ein Script zu Beginn deaktiviert, wird trotzdem die Awake ausgeführt! Die Start wird jedoch erst beim Aktivieren des Scripts ausgeführt.
  8. 1 point
    Na, dann kann ich ja zu schreiben aufhören @Kojote Geht auch so: var spawnPosition = transform.position + transform.TransformDirection(localOffset);
  9. 1 point
    Ich kann @Tyroonis nur zustimmen und ebenfalls Git + Bitbucket empfehlen.
  10. 1 point
    Das problem ist das du die Objekte nicht in der rechten Ecke verankert hast, sondern höstwahrscheinlich in derlinken oder so. Schau dir mal https://docs.unity3d.com/Manual/UIBasicLayout.html an.
  11. 1 point
    Herzlich willkommen. 😎
  12. 1 point
    Hallo, Herzlich willkommen.🙂 Ich war vorher auch mit 3DGamestudio A4 bis A8 unterwegs. 3DGamestudio ist halt Programmier--intensiver. Bei C# vermisse ich meine heiß geliebten Globalen Variablen von C, auf die man ja von überall zugreifen konnte, die Pointer-Arithmetic allerdings nicht.😉 In diesem sinne viel Erfolg mit Unity Gruß Jog
  13. 1 point
  14. 1 point
    Also ich hab mir dein Model runtergeladen und per .fbx (mit !EXPERIMENTAL ! Apply Transform) exportiert(Blender 2.8) und in Unity geöffnet.Hatte kein Probleme als ich die Bones verändert habe (Rotation und Transform). Was möchtest du den mit dem Model machen? Weil animieren kann man wunderbar in Blender.
  15. 1 point
    Ich probiere da nicht so viel mit unterschiedlichen Programmen rum. Ich selber nurtze nur Cinema4D und 3D Coat ( Cinema kostet viel, 3D Coat kostet etwas). Aber so ein Objekt geht mit allen 3D Programmen und natürlich auch in Blender. Blender ist nicht sehr einsteigerfreundlich, das sitimmt. Aber es es kann wirklich alles! Und das für ohne Geld! Ich wette mit dir, dass Blender eine Möglichkeit hat, dass du eine Scheibe, oder einen Zylinder erstellen kannst, die/der eben nur 6 Ecken hat. Und normalerweise sollte dann auch gleich eine UV Map erstellt werden, dass du da dann einfach eine Textur drauf legen kannst, die ohne Verzerrung dargestellt wird. Da musst du dann einfach mal ein paar Tutorials schauen, um mit Blender warm zu werden. Aber das ist echt nichts Schlimmes. Du musst sowieso die Grundlagen von 3D Objekterstellungen lernen, wenn du alleine ein Spiel erstelen willst. Es sei denn, du hast einen, der das für dich macht. Aber wer hat schon einen, der etwas für einen macht, wann man es braucht.
  16. 1 point
    Das ist nicht skalieren was du da machst Du erstellst lediglich ein neues kleineres Bild mit dem Ausschnitt eines grösseren. Schau dir mal Texture2D.Resize an, war aber mit dem Ergebnis nie wirklich zufrieden. Wenn du etwas recherchierst findest du auch viele Snippets die du nutzen kannst. Aber eigentlich brauchst du das Bild ja nicht zu skalieren, du kannst es einfach im Image kleiner darstellen und wenn du ein Aspect Ratio Fitter hinzufügst, hast du alles was du brauchst
  17. 1 point
    @Kojote Guten Morgen und danke für deine Rückmeldung. Die Meldung ist noch ziemlich aktuell, ja. Ich konnte jedoch einen Weg finden, meine Idee umzusetzen. Was ich nun gemacht habe ist folgendes: ich habe zunächst einmal den Rendermode vom Canvas von Screen Space Overlay auf World Space gesetzt und direkt über meinem Spielfeld positioniert, so dass die Kamera das exakte Erscheinungsbild wie oben rendert. Da meine UI Elemente nun in der Gamewelt existieren, können sie also auch auf Collider Events und Trigger reagieren. Ich habe meinem UI Handkarten Prefab also einen Box Collider und einen Rigidbody hinzugefügt. Wenn ich nun die OnDrag-Funktion benutze und meine Karten auf dem World Canvas bewege, kann ich die Box Collider vom Spielfeld ansprechen und von dort aus OnTriggerEnter, etc. ausführen. Ich habe es nun so eingefädelt, dass... sobald ich mein UI Element dragge, ein Bool auf true gesetzt wird, um erstmal zu signalisieren: "Okay, wir draggen gerade!" - sofern dies gegeben ist und ich mich im Trigger vom Spielfeld befinde und meine linke Maustaste loslasse (die ja noch gedrückt ist, da ich am draggen bin), instantiate ich meine 3D Variante der Karte an einer von mir bestimmten Position.. gibt 3 Felder, einfach 3 Transforms die quasi Spawnpunkte sind. Deine Lösung hört sich jedoch auch interessant an! Vielleicht spiele ich damit auch mal rum. Danke erstmal, dass du überhaupt was geschrieben hast 🙂
  18. 1 point
    Am besten ist es, wenn du die Ursache für das Leerzeichen behebst, aber ansonsten (oder auch einfach zur Sicherheit) hilft dir " meinString ".Trim()
  19. 1 point
    @Jomnitech Ne, muss er nicht. Die Textkomponente eines UI Elementes ist ein Sting . @Kojote Dass du dich weiter entwickeln willst ist toll! Aber du gehst da komplett falsch ran! Du gehst davon aus, dass dein If Statement nicht funktioniert. Wieso denn? Hast du denn einfach mal mit nem Print oder nem Debug.Log dir etwas ausgeben lassen? Sowas wie: if (string.IsNullOrEmpty(TMPPlayerNameText.text)) { print("Textfeld ist leer oder null"); return; } else{ print(TMPPlayerNameText.text + " lautet der Inhalt"); } Ich denke nicht. Genauso hättest du auch einfach ersteinmal die ganz normale Abfrage (die du kennst und verstehst), so wie ich sie dir gepostet hatte, nutzen können. Da hättest du erkennen können, ob sich im Verhalten etwas ändert oder ob vielleicht bei beiden das Gleiche passiert. Gäbe es da eine Veränderung, könntest du sagen, dass dein If Statement nicht funktioniert. Aber so vermutest du es einfach. Fazit: Dein If Statement funktioniert. Du wirst ein anderes Problem haben! Es könnte sein dass dein Textelement gar nicht im Code bekannt ist ( dann hättest du aber ne Fehlermeldung auf die du reagieren solltest) oder aber du startest dein Spiel von woanders, ohne dass die Abfrage überhaupt relevanz hat, oder oder oder... Wenn du also denkst, dass irgendetwas Neues nicht funktioniert, dann separiere das Problem und teste es einfach mal in einer leeren Szene mit einem kleinen Test Code oder lass dir einfach mal die Werte ausgeben, die das Neue dir bringt ( das geht auch in dem Projekt). Dann wirst du dich weiterbilden, denn dann wirst du verstehen was da passiert und ob das neue überhaupt ein Problem darstellt.
  20. 1 point
    Ich würde ja nicht in "per tick", sondern pro Sekunde arbeiten wollen. Tust du ja mit damageIncreasePerTick auch. Was dein Problem angeht, verstehe ich nicht ganz, was du da machen willst... oder wo das Problem ist. Wenn dein damagePerTick sich ändern soll, ändere ihn. Wenn dein damageIncreasePerTick sich ändern soll... ändere ihn! public void EatSomething() { damagePerSecond = 0f; damageIncreasePerSecond = initialDamageIncreasePerSecond; }
  21. 1 point
    Das war jetzt auch eher der saubere Weg. Mit einem public Feld geht das natürlich auch. Ich würde das ganze eher so machen, damit man von außen nicht ausversehen im Code den Wert verändert. Aber super, dass du damit zurechtkommst. [CreateAssetMenu(menuName = "My Game Assets/Animal Data")] public class AnimalData : ScriptableObject { [SerializeField] private string animalName = "Animal Name"; [SerializeField] private int meatValue; //öffentliches Property public int MeatValue { get { return meatValue; } } }
  22. 1 point
    Ja. Habe nur das Bedürfnis, auf die einzelnen = hinzuweisen... die machen das ganze etwas... sagen wir: mindestens schlecht lesbar.
  23. 1 point
    Nur ein paar Anregungen: Tiere kannst du mMn problemlos despawnen, wenn der Spieler z.B. weiter als x Meter entfernt ist und das vielleicht noch über eine Dauer von x Minuten Für das spawnen von Tieren und prüfen, ob diese schon oder noch da sind bzw. leben, brauchst du keinen Collider. Du packst dir einfach Referenzen in eine Liste oder so und kannst jederzeit abfragen, ob dein Tier schon oder noch lebt. Hierfür bekommt jedes Tier eine Eigenschaft Health. Wenn diese 0 ist, ist das Tier tot. Prozentualen Kram kannst du mit https://docs.unity3d.com/ScriptReference/Random.html machen Das mit der Entfernung messen kann komplexer werden. Aber grundsätzlich kannst du das Distanz messen für Spawner auf verschiedenen Frames ausführen und/oder erst pro Areal (1km² z.B.) prüfen, ob der Spieler darin ist und dann nur darin alle Prüfungen pro Spawner machen oder oder oder, nicht ganz trivial.
  24. 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!
  25. 1 point
    Microsoft hat für .NET core 3 einen neuen JSON serializer Entwickelt https://docs.microsoft.com/en-us/dotnet/api/system.text.json?view=netcore-3.0 und soll in ASP.NET core 3 newtonsoft JSON ersetzen, ist schneller und weniger GC behaftet. Wird mal Zeit dass .NET core in Unity einzughält, wäre auch um einiges schneller als Mono. .NET 5 soll am ende eh Mono, .NET CORE vereinen.
  26. 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.
  27. 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.
  28. 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
  29. 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!
  30. 1 point
    Willkommen! Schön, dass du uns gefunden hast.
  31. 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.
  32. 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.
  33. 1 point
    Frag einfach drauflos!
  34. 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?🤯).
  35. 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!
  36. 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.
  37. 1 point
    Schöne klare Icons! Gefallen mir.
  38. 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?
  39. 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.
  40. 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.
  41. 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
  42. 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.
  43. 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.
  44. 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?
  45. 1 point
    Nein, das kann man auch mit einem Konstruktor sicherstellen. Nein, sowas gibt's bei C# nicht ...solange du es nicht drauf anlegst Der Unterschied ist wirklich die Referenzsemantik. Nimm diesen Code, wie er bei Unity recht häufig vorkommt: transform.position = target.position; Transform.position ist ein Vector3, und das ist ein struct. Der Vektor, also die drei Zahlen, werden rüberkopiert. Wenn du nach dieser Zeile transform.position änderst, dann bewegt sich eben das Objekt, zu dem das Script gehört - das als "target" referenzierte Objekt aber natürlich nicht. Wäre Vector3 eine Klasse, dann wäre die position von "target" ein Objekt, und "target.position" würde dieses Objekt referenzieren. Die obige Zeile bewirkt, dass diese Referenz kopiert wird. Danach zeigen sowohl "transform.position" als auch "target.position" auf dieselben drei Zahlen im Speicher. Und wenn du diese drei Zahlen änderst z.B. durch: transform.position.x = 10; Dann würde die neue X-Position für beide Objekte gelten, da sie beide dieselbe (geänderte) Zahl benutzen. Tatsache ist, dass diese Zeile nicht mal kompiliert, und das hängt eben genau mit dieser potentiellen Verwirrung zusammen. Das ist eben der Unterschied zwischen Werten. Wenn ich durch ein Bonus-Item so viele Punkte erhalte, dass ich mit dir gleichauf bin, haben wir denselben Wert bei der Punktzahl. Kriege ich danach Punkte, heißt das nicht, dass du dann auch Punkte kriegst. Wenn wir aber zum Verkehrsamt laufen und du eintragen lässt, dass dein Auto jetzt auch mein Auto ist, dann kann ich danach nicht mein Auto blau färben, ohne dass dein Auto danach auch blau ist - weil's eben dasselbe Auto ist, und Autos Objekte sind und keine Werte.
  46. 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.
  47. 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?
  48. 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.
  49. 1 point
    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.
  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...