Jump to content
Unity Insider Forum

Sascha

Administrators
  • Posts

    13,280
  • Joined

  • Last visited

  • Days Won

    738

Everything posted by Sascha

  1. H├Ą? Du bist also auf 2022.1 gewesen, dann hab ich geschrieben dass die aktuelle LTS 2021.3 ist und du so "okay dann geh ich auf 2020.3"? ­čĄö Hab mal nachgeschaut, d├╝rfte da unter Window > Rendering > Lighting sein.
  2. 2020.3.30 ist in der Tat wirklich nicht die neuste Version Aber aktuell genug, um damit zu arbeiten. Lightmapping ausschalten wenn es nicht gebraucht wird sollte da reichen.
  3. Ja, kann man. Man sollte so oder so Unity Hub benutzen, und damit geht es ganz einfach. Unter "Installs" die gew├╝nschte Version installieren und dann unter "Projects" in der Zeile des Projekts die Version umstellen.
  4. Das wichtige ist, dass eine Schleife immer entweder von sich aus beenden kann oder nicht blockiert. Diese Schleife wird immer irgendwie zu Ende gehen: int a = ...; int b = ...; while (a < b) { a++; } Der Rumpf der Schleife (alles zwischen den { }) enth├Ąlt eine Zeile, die fr├╝her oder sp├Ąter die Bedingung der Schleife falsifizieren wird; dann bricht die Schleife ab. Es kann sofort sein, nach zehn Durchl├Ąufen oder nach einer Million. Aber eben nicht endlos. Diese Schleife blockiert nicht: while (enabled) { yield return null; } Am yield-Statement erkennt man, dass sie vermutlich in einer Coroutine steckt. Sie wartet also in jedem Schleifendurchlauf einen Frame. Und obwohl innerhalb der Schleife nie enabled auf false gesetzt wird, ist das hier keine Endlosschleife, da sie nicht blockiert, sondern nach jedem Durchlauf das Programm einen Frame weiter laufen l├Ąsst. Au├čerdem kann nat├╝rlich in diesem Frame von anderswo enabled auf false gesetzt werden. Deine letzte Schleife blockiert (sie ist nicht in einer Coroutine oder macht sonstige Warte-Dinge) und hat keine M├Âglichkeit, von sich aus zu beenden. Sollte die Bedingung in der Schleife !LObstaclesToSpawn[index].activeInHierarchy zuf├Ąlligerweise initial false sein, dann kann es in einem sp├Ąteren Durchlauf auch nicht mehr true werden, da in diesem Fall in der Schleife nichts mehr passiert. Wenn deine Schleife tats├Ąchlich warten soll, bis diese Bedinung eintrifft, dann brauchst du da noch den entsprechenden Befehl in der Schleife, einen Frame zu warten. Also yield return null;. while(true) { if (!LObstaclesToSpawn[index].activeInHierarchy) { GQuestionPart.SetActive(true); gameObject.SetActive(false); break; } yield return null; } Allerdings kannst du dir das unsaubere while (true) da auch direkt raus machen, schlie├člich hast du ja schon eine Schleifenbedingung: while(LObstaclesToSpawn[index].activeInHierarchy) { yield return null; } GQuestionPart.SetActive(true); gameObject.SetActive(false); oder, falls du es ein bisschen h├╝bscher haben willst: yield return new WaitUntil(() => !LObstaclesToSpawn[index].activeInHierarchy); GQuestionPart.SetActive(true); gameObject.SetActive(false);
  5. Moin! Naja, offenbar ist eine deiner while-Schleifen am Dauerlaufen. Ich tippe auf die ganz am Ende, denn wenn beim ersten Versuch die Bedingung nicht zutrifft, dann tu sie es auch nie mehr. while(true) gilt halt nicht ohne Grund in den allermeisten F├Ąllen als schlechter Stil.
  6. Was du ansonsten auch machen kannst, ist ein ScriptableObject in das AssetBundle zu packen, das die anderen Assets in einer Liste hat, und dann diese Liste verwenden.
  7. Also ist deine Szene irgendwie kaputt gegangen? In dem Fall w├Ąre eine NullReferenceException keine ├ťberraschung - Objekte, die von anderen Objekten gebraucht werden, fehlen. Die anderen Objekte sind dann "unzufrieden", dass die referenzierten Objekte weg sind. So "Knopf X ├Âffnet T├╝r Y" + "T├╝r Y ist weg" = "Knopf X wei├č nicht, was er tun soll". Warum deine Szene kaputt ist, kann ich nicht sagen. Vielleicht vergessen zu speichern, vielleicht irgendein Plugin installiert, das Mumpitz macht. F├╝r solche F├Ąlle ist Versionierung ganz praktisch, aber das muss man auch erstmal lernen. Du musst jetzt jedenfalls deine Szene reparieren. Du hast irgendwo eine "Grid"-Komponente, die ein "ShapeStorage" referenziert. Diese Referenz (das, was du im Inspektor einstellst), ist kaputt. Eventuell, weil dein ShapeStorage-Objekt weg ist.
  8. Moin, was genau hei├čt denn bitte Ist da ...Code weg? Ansonsten kann man dir bei einem Fehler, den dein Code wirft, nicht helfen, wenn du den Code nicht postest.
  9. Ich hab nicht direkt Erfahrung mit der Kombination WebGL + Asset Bundles, aber da h├Âre ich zum ersten Mal von. Daten dekomprimieren ist nichts, was JavaScript nicht k├Ânnen sollte. Aber wie gesagt... da kann ich mich irren. Du darfst halt die Gr├Â├če unkomprimierter Dateien nicht untersch├Ątzen. Versuch nochmal, Komprimierung zum Laufen zu kriegen.
  10. Moin! BuildAssetBundleOptions.UncompressedAssetBundle Hmm...
  11. Du benutzt wirklich 2022.1.6? Hoffentlich nicht... Du solltest nicht unbedingt mit bleeding edge (Betaversion, die eine Menge Bugs enthalten kann) arbeiten, sondern dir eine LTS (stabilere Version) runterladen. Das w├Ąre aktuell 2021.3.5. Kommt halt drauf an, ob dein Standard-Anf├Ąnger-Spiel Lightmaps haben soll. Hier gibt's was zu lesen: https://docs.unity3d.com/Manual/Lightmappers.html Kurz gesagt: Anstatt eine gewisse Menge an Rechenleistung durchgehend daf├╝r zu verbraten, dass das Licht in der Szene berechnet wird, kann man Licht auch statisch auf seine Oberfl├Ąchen backen. Dann wird halt einfach ein roter Fleck fest auf deinen Boden gepinselt, anstatt dass das rote Licht die ganze Zeit durch Lichtberechnungen da ankommt. Wenn deine Szene sich darauf verl├Ąsst, dass eine Lightmap da ist, diese aber fehlt oder irgendwie nicht geladen werden kann, dann sieht das Licht entsprechend komisch aus. Ausschalten sollte je nach Version in den Lighting Settings (Edit > Project Settings > Lighting) gehen.
  12. ├ľh... ich w├╝rde jetzt einfach mal raten und sagen: Die Priorit├Ąt lag auf dem Setup im Editor, damit Designer da sch├Ân alles anlegen k├Ânnen. Deshalb packt man ja auch nicht mehr einen Haufen Komponenten auf die Kamera, sondern erstellt PostProcessing-Profile, die man Volumen zuweist. Damit man situationsabh├Ąngig PostProcessing einstellen kann. Dass bei so einem System dann die API etwas komplexer wird und man definieren muss, wo genau man bestimmte ├änderungen haben will (weil es ja nicht mehr mehr nur ein globales PostProcessing gibt), wundert mich wenig.
  13. Benutzt du eine aktuelle oder eher eine veraltete Unity-Version? Was f├╝r einen Lightmapper hast du aktiv? Mit welchen Einstellungen? URP oder HDRP an? Das klingt halt sehr danach, dass dein Lightmapper komische Dinge (nicht) macht. Wenn du den Lightmapper gar nicht aktiv benutzt, schalte ihn einfach aus.
  14. Moin! Vermutlich nur mit der obsoleten BuildAssetBundle-Methode. Wozu brauchst du denn die Reihenfolge? Im Notfall kannst du den Dingern ja Namen mit nem Index geben und die danach laden.
  15. Was meinst du mit "offen"? Wenn eine Szene nicht "offen" ist, sieht man sie doch sowieso nicht? ­čĄö Oder meinst du "offen" in dem Moment, wo du buildest?
  16. ├ľh, klar, generell geht das. Ob das jetzt so richtig w├Ąre, wei├č ich aus dem Kopf nicht. Du wirst aber vielleicht auch noch ein Attribut ├╝ber das Array packen m├╝ssen.
  17. Es ist auf jeden Fall gut, Strings zu vermeiden, weil man die Nachteile einsieht... "weil Sascha das sagt" ist aber kein sehr guter Grund Viel Erfolg, und nie zu wenige Fragen stellen
  18. Verstehe, ist nachvollziehbar Theoretisch geht das auch, aber du machst es dir damit schwerer als es sein muss. Arrays sind eher f├╝r gleichartige Elemente da. Also auch semantisch. Obwohl du da vier Strings hast, sind das ja eine Frage und drei Antworten. Nene, ein Array ist schon gut, aber ein eindimensionales. Da packst du dann z.B. Structs rein. public struct Question { public string word; public string correct; public string wrong1; public string wrong2; } public Question[] questions; Ist jetzt nur ein ganz stumpfes Beispiel, aber du siehst, wie es deinen XML-Code genau wiederspiegelt. Statt einer Tabelle ohne ├ťberschriften hast du jetzt eine Liste von Fragen (wobei jede "Frage" aus deinen vier Strings besteht). Geht alles. Letztenedes sind auch XML- (oder Json- oder Yaml-)Dateien nur Textdateien mit einem bestimmten Format drin. Ob du dieses Format selber erstellst oder ein Standardformat wie diese drei nimmst, gibt sich nicht viel.
  19. Also komm, ein Minimum an M├╝he darfst du dir mit deinem Post schon geben.
  20. Das macht das Vorhaben es definitiv um einiges realistischer. In dem Fall brauchst du keine Netzwerkbibliothek wie Mirror, sondern einfach nur HTTP(s)-Abfragen. Die kannst du mit UnityWebRequest senden. Das schaut man sich einmal an und dann l├Ąuft das. Herausforderungen sind dann eher, ein vern├╝nftiges Anfrageprotokoll zu designen und das Backend zu schreiben. Vielleicht kann man unter hinreichend starkem Drogeneinfluss tats├Ąchlich einen Unity-Prozess hinter den Webserver schnallen, aber... ich w├╝rde dringend davon abraten Insbesondere, da du gar kein Echtzeit brauchst. Dann bringt ein Unity-Prozess ├╝berhaupt keinen Mehrwert. Einfach ein ganz normales Backend mit einer beliebigen Webserver-Sprache/-Software bauen und gut is. F├╝r Echtzeit-Multiplayer. Wie gesagt, ohne Echtzeit ist ein mit Unity erstellter Build auf dem Server v├Âllig am Ziel vorbei.
  21. @Michael S. Wenn dir die Nebenunterhaltung zwischen MaZy und mir das Lesen schwerer macht sag Bescheid; ich trenne die Beitr├Ąge dann aus dem Thema heraus Dass da Code generiert wird? Ist eine der verf├╝gbaren Modi, der inzwischen immerhin nicht mehr der ist, der im ersten Tutorial empfohlen wird. Stattdessen kann man auch SendMessage (meh), C#-Events oder - mein Favorit - SO-Referenzen nutzen, um zu definieren, von welcher InputAction wir gerade reden. Als das neue InputSystem-Paket gerade neu raus war, war der einzige oder zumindest der erste empfohlene Weg, C#-Code generieren zu lassen und dann statisch darauf zuzugreifen. Das war das erste, was einem gezeigt wurde, und danach hab ich das Paket nicht weiter angeschaut damals. Danke! Leider wird's gef├╝hlt von meiner Seite aus dabei bleiben. Ist aber immerhin modular mit Transport Layer und Serialization Engine... und halt Open Source. Wenn da also jemand Potential sieht und es weiterf├╝hren will... Klingt sehr interessant! Hast du da einen sp├╝rbaren Performance-Unterschied?
  22. Naja, falsche Grundideen gibt's eher selten. Eher so "nicht richtig umgesetzt" und/oder "Overkill" und... "Underkill"? Du wei├čt schon MVC ist meiner Meinung nach f├╝r "normale" Projekte ganz schnell Overkill. Ich hab das auf der Arbeit, weil wir alle zwei Wochen ein Update raushauen und der Kram von oben bis unten gnadenlos testbar sein soll. Da greifen so viele Zahnr├Ąder ineinander und in jedem Sprint wird die H├Ąlfte der Zahnr├Ąder in irgendeiner Weise angefasst. Wenn wir uns da auf Augenma├č verlassen w├╝rden, w├Ąre das Spiel das reinste Bugfest. Wenn du aber ein, zwei Jahre an einem Spiel arbeitest, es danach ver├Âffentlichen und dann noch eine Weile maintainen (Bugfix-Patches, vielleicht hin und wieder eine Erweiterung) willst, dann sieht die Kosten-Nutzen-Rechnung gleich ganz anders aus. MVC ist dazu da, Logik, Daten und Anzeige/Input voneinander zu trennen. Haupts├Ąchlich, damit du beim (automatisierten) Testen schnell sehen kannst, wo in diesen drei Bereichen der Fehler liegt. Es kann aber durchaus sein, dass dein Code nicht sonderlich komplex oder volatil ist. In diesem Fall bedeutet MVC Mehraufwand, der beim Bugfixen aber kaum Mehrwert liefert. Wenn du aber MVC durchziehen willst, musst du dir Gedanken machen, welche Objekttypen wozu geh├Âren. Hauptsache, es ist getrennt. Du kannst Model-MonoBehaviours neben Controller-MonoBehaviours und View-MonoBehaviours haben. Du kannst aber auch MonoBehaviours ausschlie├člich als Views benutzen und Models und Controller anders bauen. ScriptableObjects f├╝r Models zu benutzen kann durchaus sinnvoll sein, wenn deine Datenschicht eine recht statische Struktur hat. Wenn du z.B. eine Soda-GlobalVariable f├╝r die HP des Spielers nutzt, dann ist ja sozusagen Teil eines Models. Auch wenn es etwas un├╝blich ist, ein Model in mehrere Objekte aufzuteilen. Aber bei einem simplen 2D-Plattformer reicht so etwas vielleicht. Sobald es etwas komplexer wird, stehst du halt vor dem Problem, das du j├╝ngst bemerkt hast. ScriptableObjects geben dir nix, wenn du sie zur Laufzeit erzeugst. Wenn deine Daten dynamisch zur Laufzeit entstehen, musst du deine Models entweder direkt auf die Objekte packen, die sie betreffen - also gibt's Model-MonoBehaviours - oder du baust deine Models komplett getrennt von der Unity-Welt. Daf├╝r baust du stinknormale C#-Klassen. Wenn du dich fragst, wo ├╝berhaupt der Einstiegspunkt f├╝r Programme ist, die gar nicht so Unity-zentrisch sind... Du kannst da entweder selber etwas initialisieren, z.B. mit [RuntimeInitializeOnLoadMethod], oder du nutzt etwas bereits existierendes wie Zenject. Keine Ahnung, ob dir diese Antwort ├╝berhaupt hilft, aber dieses noch: Mache dir immer Gedanken, warum du bestimmte Dinge machst. So etwas wie "ich habe im Hinterkopf, dass MVC sauberer ist" schadet dir sehr schnell viel mehr, als es hilft. "Das schien" klingt danach, dass du die Vorteile deines Ansatzes in deinem Projekt nicht wirklich bemerkst. Und wenn du den Unterschied nicht wirklich sehen kannst, dann liegt das vermutlich daran, dass nicht wirklich einer da ist. Au├čer dem st├Ąndigen Mehraufwand, wenn du dich fragst, wie du ein bestimmtes Konzept in deine dir selbst auferlegte Struktur reinpressen kannst.
  23. Dir muss nur bewusst sein, dass diese Kombination quasi nicht machbar ist. Du solltest das Projekt also auf jeden Fall locker angehen. Sei nicht ├╝berrascht, wenn es einige Monate, wenn nicht Jahre, dauert, bis da irgendetwas spielbares bei rumkommt. Was du dir da vorgenommen hast, ist alles andere als ein Anf├Ąngerprojekt. MMOs sind so ungef├Ąhr das schwierigste, was man sich vornehmen kann. Aber davon abgesehen hier ein bisschen Wissen, einfach mal hingeworfen. Multiplayer != Multiplayer Du musst erstmal zwischen Echtzeit-Multiplayer und asynchronem Multiplayer unterschieden. Echtzeit ist, wenn die Spieler sich gegenseitig beim Spielen sehen. Echtzeit-Strategie, Shooter, (MMO)RPGs, sowas. F├╝r Echtzeit brauchst du eine Networking-Bibliothek wie Mirror, Photon, Fishnet und dergleichen. Diese Bibliotheken senden durchgehend Daten zwischen den Clients hin und her. Oft ├╝ber einen Server, mit dem alle verbunden sind, oder alternativ "fast direkt" untereinander (Peer to Peer / P2P). Wenn du in deinem Spiel Echtzeit brauchst, dann musst du dich in eine solche Bibliothek einarbeiten, und allein das ist schon kein Anf├Ąngerthema mehr. Da bringst du hoffentlich schon eine gewisse Menge Erfahrung mit Spiele-Entwicklung im Allgemeinen mit. Nicht jedes Spiel braucht aber Echtzeit-Unterst├╝tzung. Bei z.B. einem City Builder ist kein st├Ąndiger Austausch n├Âtig. Weder zwischen Clients, noch mit dem Server. Hier sendet das Spiel einfach nur Anfragen an den Server und kriegt ggf. Antworten zur├╝ck. So wie dein Browser Anfragen schickt und dann z.B. eine Webseite zur├╝ck kriegt. H├Âchstwahrscheinlich sogar mit genau demselben Protokoll (HTTP(s)). Da schickst du dann "ich baue Geb├Ąude 123 an Stelle X, Y" und der Server antwortet "jo, passt". Zwischen diesen Anfragen herrscht dann auch gerne Funkstille. Backend-Server Wenn du jetzt eine persistente, sich ver├Ąndernde Welt haben willst (und wenn diese auch nur aus Inventaren der Spieler best├╝nde), dann brauchst du noch ein Backend. Also ein Extra-Programm, das zus├Ątzlich zum eigentlichen Spiel geschrieben werden muss. Dieses Programm hat dann eine Datenbankanbindung, damit in dieser Datenbank die Daten der Welt gespeichert werden k├Ânnen. Nur, wenn du ein Spiel wie CS1.6 hast, wo nach eine Runde alle disconnecten und danach nichts mehr von der Runde gespeichert ist, dann braucht man so etwas nicht. Wenn du also ein Spiel haben willst, wo mehrere Spieler sich gegenseitig in Echtzeit beim Spielen sehen und das in einer persistenten Welt, die sich ver├Ąndern kann - dann musst du Echtzeit-Networking, HTTP-Abfragen (am besten mit sowas wie REST), Datenbanken und nat├╝rlich den ganzen Spiele-Basiskram beherrschen. Der Begriff "MMO" impliziert dabei noch eine hohe Spielerzahl, sodass du gro├če Datenmengen und reichhaltigen Informationsaustausch hast. Du musst da also Performance optimieren und brauchbare Datenstrukturen aufsetzen k├Ânnen. Weil da einfach fast alles zusammenkommt, was man ├╝berhaupt ├╝ber Spiele-Entwicklung wissen kann, sind MMOs einfach die K├Ânigsklasse. Wenn du das aber durchziehen willst, und sei es nur zum Lernen, dann schau dir eine der hier genannten Echtzeit-Bibliotheken an und dazu noch UnityWebRequest f├╝r HTTP-Anfragen. F├╝r den Backend-Server kannst du nehmen, was du willst. PHP ist so lala - man kann schon alles damit vern├╝nftig machen, aber als Anf├Ąnger gibt es kaum eine Sprache, mit der man so leicht Fehler machen kann wie mit PHP. Um ├╝berhaupt erstmal irgendetwas zu haben, ist es aber sehr sch├Ân schnell und einfach.
  24. Moin! Woher wei├č ein 3D-Objekt, welches Pixel der Textur wo hin geh├Ârt? Die Antwortet lautet "UV-Map"! Ist eine vorhanden, hat jeder Punkt (Vertex) eines 3D-Modells noch eine entsprechende 2D-Koordinate, die auf die Textur gelegt wird. So hast du die Dreiecke, aus denen dein 3D-Modell besteht, noch einmal flach auf deine Textur gelegt, quasi als Schnittmuster. Dann werden die Teile aus der Textur sozusagen ausgeschnitten und auf das 3D-Modell geklebt. Fehlt die UV-Map, dann wird f├╝r alle Koordinaten 0,0 angenommen. Es wird also ├╝berall auf das Objekt das untere linke Pixel der Textur geklebt. Deshalb sind Objekte ohne UV-Map, die einen Shader nutzen, der eine UV-Map br├Ąuchte, einfarbig. Lange Rede, kurzer Sinn: Deine Objekte haben keine UV-Map.
  25. ├ľh... geht es dann einfach nur darum, dass du nicht 100 Felder in einer Klasse haben willst, sondern lieber 10 Felder, wo jeweils 10 Felder hinterstecken? Dann nimm Structs, w├╝rde ich sagen. Alternativ Klassen, je nach dem, ob du Referenzsemantik brauchst.
×
×
  • Create New...