Jump to content
Unity Insider Forum

Leaderboard


Popular Content

Showing content with the highest reputation since 09/20/2020 in Posts

  1. 2 points
    Ich verstehe zwar die Situation nur sehr wenig, aber das klingt, als wärst du an dem Punkt angelangt, wo "ich habe mit Unity programmieren gelernt" seine Nachteile mit sich bringt. Wenn du anfängst, irgendein Programm mit Java oder so zu schreiben, dann hast du erstmal keine Szene, in der du Objekte hast, die magisch geladen werden, sobald das Programm startet. Selbst bei einer Fenster-Anwendung, wo du heutzutage auch einfach klickibunti deine Knöpfe platzieren kannst, schmeißt du keine Datenhalter-Objekte auf deine UI-Elemente oder so. Dass, zumindest bei weniger komplexen Projekten, 95% deiner Klassen Komponenten sind, die du dann auf GameObjects ziehst, ist schon eine Besonderheit in der Software-Welt. Und man gewöhnt sich ein bisschen sehr daran Es kann, wenn ich deine Situation jetzt überhaupt richtig gesehen habe, sinnvoll sein, Unity mal links liegen zu lassen und mal etwas ganz anderes anzufassen. Java mit BlueJ ist super zum lernen imo, einfach mal Python (sind wieder ne neue Spachen, aber kann trotzdem helfen... oder gerade deswegen), oder halt eine Konsolen-/Fenster-Anwendung mit C#. Wie gesagt, ich blicke die Situation nicht so ganz... ich nenne einfach mal ein paar Dinge, die du so kannst. GameObjects in deiner Szene, die Komponenten haben, in denen Daten stehen. Das ist dann sinvoll, wenn die Daten auch Teil deiner Szene sein sollen. Welcher Schalter öffnet welche Tür? Welche Farbe hat das Licht? Wo spawnen Gegner? Wie viel Schaden macht dieser Bereich? ScriptableObject in den Assets. ScriptableObjects sind unheimlich wichtig, wenn die Projekte anfangen, etwas komplexer zu werden. Man kann auch andere Dinge damit tun, aber die wohl wichtigste Anwendung ist, dass man sie in die Assets erzeugen kann. Sie sind ganz normale Objekte mit serialisierbaren Feldern (also wie bei Komponenten, dass man die Werte im Editor einstellen kann und sie dann gemerkt werden), die in diesem Fall aber nicht in deiner Szene existieren, sondern außerhalb, so wie deine Sounds, 3D-Modelle und Texturen, die überall im Projekt verwendet werden können. Klassisches und imo sehr gutes Beispiel für ScriptableObjects sind Item-Arten in einem RPG. Denk z.B. an Pokémon. Du hast ein Inventar, das als eine Liste von Items daherkommt. Das Inventar soll in jeder Szene funktionieren, und die Items als Prefabs zu definieren wäre doof, weil du eigentlich keine GameObjects in der Szene haben willst, nur damit sie in der Liste auftauchen. Und die Transform-Komponente ist auch überflüssig. Also machst du einfach eine ScriptableObject-Klasse (hier hast du eine Vorlage) und schmeißt da deine Felder rein: Item-Name, Wert beim Verkaufen, Referenz auf ein Sprite, um es im UI anzuzeigen, vielleicht noch eine Beschreibung. Dann kannst du im Editor im Asset-Fenster Rechtsklicken, Create, und deine ScriptableObject-Klasse taucht da auf. Dann erstellt du da mehrere Items und kannst die in deine Szene ziehen, um sie zu referenzieren (so, wie du z.B. ein AudioClip auf deine AudioSource ziehst). Wenn du also z.B. eine Schatztruhe hast, kannst eine Schatztruhe-Komponente machen, die ein Item-Feld hat, wo du dann das Item reinziehst, was aus der Kiste rauskommen soll. In deinem Fall kannst du deine Genres als lauter ScriptableObjects machen, vielleicht noch eine weitere SO-Klasse, die eine Liste der Genres enthält, oder du packst gleich alle Genres direkt in die Liste (so wie es jetzt scheinbar ist). Die Entscheidung sollte danach gehen, ob du auf die Genres einzeln zugreifen willst. Auch hier müsstest du erstmal ein Feld in deinen Komponenten deklarieren, in das du dann ein SO reinziehen kannst. Diese Variante ist also dann sinnvoll, wenn du mehrere mögliche Objekte (z.B. Genre-Listen) haben willst und dann im Editor durch Reinziehen entscheiden kannst, welches davon deine Komponente benutzen soll. ScriptableObject sollte man so oder so mal ansehen, auch wenn das hier am Ende nicht die beste Lösung sein sollte. Stinknormale Objekte, die nix mit Unity ab Hut haben. Du kannst auch einfach Objekte erzeuge, ohne, dass der Editor die jemals zu Gesicht bekommt. Wenn du im Inspektor Dinge eintragen können willst, ist das natürlich eher weniger die richtige Variante. Wenn du Objekte hast, die zur Laufzeit generiert werden, wie z.B. eine Waffe in Borderlands mit den zufällig gewählten Eigenschaften, dann willst du dafür evtl. ScriptableObjects benutzen um die möglichen Parameter zu definieren (z.B. Waffe "Grüne Pistole", hat Schaden zwischen 3 und 5, kann eines von folgenden Visieren haben, etc.), aber der Waffendrop selbst wäre dann ein ganz normales Objekt, das du mit new erzeugst. Zusätzlich zu diesen Varianten muss man sich die Frage stellen, wo man überall Referenzen zu den Objekte aufbewahrt. Du kannst z.B. Objekte jeder dieser Varianten statisch referenzieren. Statisch (weiß nicht, ob du "static" schon verinnerlicht hast) bedeutet, dass der Ort fest innerhalb des Programms definiert ist. Wenn du also z.B. eine statische Variable in deine Klasse packst, dann ist es egal, wie viele Instanzen dieser Klasse du hast - die statische Variable existiert nur einmalig in der Klasse selbst. Während du bei nicht statischen Dingen immer angeben musst, von welchem der Instanzen jetzt die Rede ist (ist ja klar - du musst ja definieren, welches deiner Lichter jetzt rot werden soll), musst du das bei statischen Dingen nicht, und so entfällt der Arbeitsschritt, das Objekt irgendwie herauszusuchen (wie du es z.B. durch dein Feld machst, in das du deine Genres ziehst). Statische Dinge sind entsprechend nur dann sinnvoll, wenn du absolut sicher bist, dass du das Ding nur einmalig brauchst. Wenn du sicher bist, dass du nur exakt eine Genre-Datenbank brauchst, dann kannst du diese irgendwo statisch deponieren und von überall aus drauf zugreifen, ohne noch zusätzlich zu spezifizieren, wo das Ding überhaupt ist. Sieht dann z.B. so aus: // Die Klase selbst muss nicht statisch sein, aber es verhindert hier, dass wir Instanzen hiervon erstellen. // Wir wollen ja nur EINE Datenbank haben, und das ist hier die Klasse selbst. public static class GenreDatabase { public static Genredetails[] GenreList; } Damit kannst du jetzt von überall schreiben: foreach (var genre in GenreDatabase.GenreList) oder wie auch immer du mit dem Array arbeiten willst. Der Punkt ist: Du schreibst "Klassenname.Variablenname" und fertig. Die große Frage, und da wird jetzt halt einfach Fortgeschritten, ist: Wie bekommst du deine Daten in die statische Welt? Und da gibt's in Unity mehrere Varianten, aber leider einfach keine, die ich als optimal ansehen würde. Du kannst deine Genres z.B. alle im Code definieren: public static class GenreDatabase { public static Genredetails[] GenreList; [RuntimeInitializeOnLoadMethod] private static void Initialize() { GenreList = new Genredetails[] { new GenreDetails { genreName = "Foo", genreEXP = 10f, // ... }, new GenreDetails { //... }, // ... } } } Das Attribut RuntimeInitializeOnLoadMethod ist hervorragend. Es macht ganz simpel, dass diese Methode einmalig direkt am Anfang des Spiels ausgeführt wird, völlig egal, was für eine Szene du hast oder was da drinsteckt. (Nebenbei: Ein statischer Konstruktor ginge hier auch, aber mit dem Attribut ist man immer auf der sicheren Seite.) Ist natürlich irgendwie hässlich, solcherlei Daten hart im Code zu definieren. Weil Unitys neues Input-System das auch so macht, finde ich das auch ein bisschen käsig. Alternativ könnte man ein ScriptableObject mit allen Genres drin machen und das einmalig am Anfang laden in einem statischen Feld referenzieren. Dafür muss man halt irgendwie definieren, wo dieses SO überhaupt liegt. Dafür bietet sich Resources.Load an, auch wenn ich das Ding ja immer gerne vermeide. public static Genredetails[] GenreList; [RuntimeInitializeOnLoadMethod] private static void Initialize() { GenreList = Resources.Load<GenreListScriptableObject>("Name der Datei hier").GenreList; } Hier ist wieder das übliche Problem, dass wenn die SO-Datei irgendwie minimal anders heißt oder verschoben wird, erstmal der Code nicht mehr das tut, was er soll. Eine dritte Variante wäre, ein GameObject in einer Szene zu haben, das dasselbe macht, nur halt ohne Resources.Load, sondern indem man das SO da reinzieht. Da ist halt der Käse dran, dass der Code wieder nicht funktioniert, wenn man im Play Mode eine andere Szene startet und das Objekt da nicht da ist. So... das war jetzt ne Menge Text. Tut mir auch leid, dich damit so zu bombardieren, und vor allem, dass da nicht mal "die richtige" Lösung drin steckt. Aber Tatsache ist: Du bist mit dieser Frage ganz eindeutig aus dem Noobschutz-Areal draußen. Die Stützräder sind ab, das Tempolimit aufgehoben. Jetzt geht's ans Eingemachte! Da wird es leider immer häufiger vorkommen, dass du Vor- und Nachteile verschiedener Wege analysieren und verstehen musst, um dann einen Weg zu finden, der am wenigsten doof für dich ist. Und du wirst dich immer wieder schlecht entscheiden, die Konsequenzen oft erst Monate später bemerken und einen besseren Weg erst Jahre später entdecken. Willkommen im Club!
  2. 1 point
    Hallo, ich habe mit dem ersten vor etwa 3 Monaten begonnen und fand das für den Einstieg ganz gut. Es wird auch ein kurzer Einstieg in C# vermittelt, aber nicht sonderlich tief. Für den Einstieg aber auch ausreichend. Ich hab das Buch aber nicht komplett durchgelesen, als ich die Grundsätze glaubte verstanden zu haben, habe ich ein paar youtube-guides angesehen und inzwischen hilft mir oft auch google, die docs von unity oder dieses Forum. Die beiden anderen kenne ich leider nicht. Für welches auch immer Du Dich entscheidest: Viel Spaß!
  3. 1 point
    Hallo, Ich kann das Buch von @Carsten in der 2 Auflage nur empfehlen, hat mir beim Umstieg von C auf C# sehr geholfen.Es wird auch Hintergrundwissen vermittelt. Es werden alle Themen sehr gut mit Beispielen behandelt. Es ist zwar nicht mehr so aktuell aber ich benutze es immer noch bei Problemen zum nachschlagen. !Das ist nur meine Persönliche Meinung und soll in Keinster weise Werbung sein! Gruß Jog
  4. 1 point
    @Carsten war hier im Forum aktiv, auch wenn ich länger nichts mehr von ihm gelesen habe - das ist richtig Ansonsten kann ich zu den Büchern leider nicht viel sagen. Bücher 2 und 3 sind beide für Unity 5, das ist jetzt schon ein paar Jährchen her. Sehr vieles ist immer noch richtig, aber da ich den Inhalt der Bücher nicht unbedingt auswendig kenne, weiß ich nicht, wie viel Probleme du mit den fünf Jahre alten Büchern haben wirst. Die offiziellen Ressourcen unter Unity Learn sind nicht schlecht, da kann man auch immer reinschauen. So oder so ist es auch nicht schlecht, mehrere Quellen zu haben. Sobald man den absoluten Anfängerbereich verlässt, wird nämlich auch eine breite Perspektive wichtig.
  5. 1 point
    Juhu, neuer Endgegner. Dieses mal in den Wolken des Jupiters. Special Thanks an @Jog für das Ende. Ergänzend zu den Credits der letzten Videos: Nun verwende ich auch zusätzlich Texturen von https://pixabay.com/de/
  6. 1 point
    Ok, habe es geöst. Ich kann bei der Render Texture einstellen, wie viel Pixel die haben soll. habe jetzt auf 1024x768 gestellt. Jetzt siehts schön aus Ich lasse das mal hier drin falls jemand mal das gleiche Problem haben sollte Viele Grüße Smirn
  7. 1 point
    Willst du echt das uralte Animationssystem nutzen und mit Animationsclips arbeiten? Das willst du nicht! Nutze den Animator Controller! https://docs.unity3d.com/ScriptReference/Animator.html https://docs.unity3d.com/Manual/Animator.html Es gibt unendlich viele Tutorials dazu im Netz und er ist auch leicht zu bedienen. Der Animator ist eine Komponente, die deinem Gameobject, welches irgendwas animieren will, hinzugefügt werden muss. Wie welche Animation abgespielt werden soll, stellst du im Animator ein. Dafür gibt es ein eigenes Fenster in dem du deine Animationen arrangierst und Mit Transitions verbindest. Die Transitions, also die Bedingungen um von einer Animation zur Nächsten zu gelangen, stellst du ganz einfach nach eigenen Wünschen ein. Du musst lediglich ein paar Parameter im Animator erzeugen, und sie vom Code aus ansprechen. Und wenn eine Animation gestoppt werden soll, dann hält sie eigentlich nicht an, sondern geht in eine andere Animation über. Also von einem State zum anderen. Ja und da reicht es schon aus, einen leeren State zu erstellen. Dafür musst du natürlich, eigentlich wie immer, ersteinmal den Animator bekannt machen, also eine Referenz bilden. public Animator myAnim; // Animator einfach hier rein ziehen Und im Code kannst du dann ganz leicht den Parametern im Animator gewisse Werte geben. myAnim.SetBool("walk",true); // oder myAnim.SetTrigger("stop"); Das sind jetzt nur Beispiele. Die Art des Parameters (trgger, bool, int, float) und dessen Namen musst du natürlich selber einstellen.
  8. 1 point
    Hmmm... Icons skalieren mit der Distanz zur Scene View-Kamera, solange "3D Icons" angeschaltet ist. Wenn du also weit von der Kamera weg bist, dann wird das Icon so klein, dass man es nicht mehr sieht. Da F immer versucht, alles ins Bild zu kriegen, und da das riesige Sichtfeld der Kamera dazugehört, zoomst du mit F auf einer Kamera sehr weit raus. Du kannst mal "3D Icons" ausmachen, dann siehst du das Kamera-Icon vermutlich. Oder, du gehst nah genug dran, was etwas fummelig sein kann... 3D-Welten auf 2D-Bildschirm und so.
  9. 1 point
    Es kommt jetzt ein wenig darauf an, welche Rendermethode du nutzt. Auf jeden Fall musst du deinem UI Canvas auf "World Space" im Rendermode einstellen. Jetzt ist die UI wie ein 3D Objekt im Raum. Du kannst sie wie jedes andere Objekt imRaum bewegen und auch ausrichten. Jetzt brauchst du eine 2. Kamera, die in der Culling Mask nur die UI drin hat. Die 2te Kamera ist der MainCamera untergeordnet, damit sie sich mit dreht und sollte auch das gleiche FOV haben, wie die erste Kamera. Wenn du das herkömmliche Rendermodell nutzt, dann müstest du eigentlich nur bei der Hauptkamera bei Cullingmask die UI raus nehmen und bei Depth die Kameras so einstellen, dass die UI Kamera eine höhere Depth hat, als die MainCamera. Nutzt du die neuen Renderpipelines, dann ist das etwas anders. Hier musst du die UI Camera beim RenderType auf Overlay einstellen. Bei der MainCamera musst du in dem neuen Bereich "Stack" jetzt die UI Kamera einfügen. Du hast also bei beiden Modellen eine neue Kamera drin, die immer in die selbe Richtung wie die Main Camera guckt. Die MainCamera rendert jetzt aber nichts mehr, was den Layer UI hat. Die neue Kamera rendert nur noch den UI Layer. Die neue Kamera liegt über der MainCamera, was du entweder über den Wert Depth einstellst, oder indem du ein Stack bei der MainCamera erstellst und dort die UI Camera einfügst. Je nach Rendermodell.
  10. 1 point
    So riesige Bilder kannst du nicht mal eben so einfügen. Spiele benutzen so große Texturen nicht 4k- oder gar 8k-Texturen sind der krasse Scheiß, aber 23k? Niemals. Unity skaliert Texturen standardmäßig auf 1024² runter. Das kann man in den Import Settings der Textur anpassen. Wenn du aber sowieso nur eine ständige Wiederholung hast, kannst du auch einfach ein Segment einfügen (also in deinem Fall eine Box) und dann im Material unter "Tiling" eine Wiederholung einstellen.
  11. 1 point
    Na gut... TestProject Woo.zip
  12. 1 point
    Los geht es mit dem Trade MVP... wie ihr euch vielleicht schon denken könnt soll dieses MVP das Trading System verdeutlichen... der akteulle Stand ist wie ihr sehr schon recht fortgeschritten .. es gibt Waren die ge- und verkauft werden können. Die Waren haben bereits Unterschiedliche Eigenschaften wie Preis, Gewicht und Volumen etc. Das Kernelement in meinem Trading System soll sein, das der Spieler mehr Möglichkeiten hat mit den NPCs zu handeln.. das bedeutet die Waren haben bestimmte Preise die aber vom Spieler modifiziert werden können. Macht der Spieler dem NPC ein besseresAngebot (bietet mehr Geld für eine ware) Steigt das ansehen bei dem NPC was später zu besseren / anderen Angeboten führen kann. Ist das Angebot des Spielers zu schlecht (weil er z.B. seinen Profit maximieren möchte) sinkt das Ansehen bei dem NPC und es kann passieren das der NPC das Angebot dann auch Ablehnt. Lehnt der NPC den handel 3 mal ab, scheitert der Handel und der NPC verweigert für eine gewissen Zeit jeden weiteren Handel mit dem Spieler. P.S. Offenbar funktionieren GIFs hier nicht dann eben videos ... TradeMVP_001.mov
  13. 1 point
    Das Problem bei einem Tag ist, dass es ein String ist. Also ein Wort, dass irgendwie geschrieben werden kann. Wenn der Tag "Player" heissen würde, du aber nach "player" suchst, dann wirst du ihn nicht finden, denn ein großes P ist nunmal anders als ein kleines p. Du bekommst auch beim Programmieren keinen Hinweis auf deinen Schreibfehler. Erst beim Testen des Spiels, wirst du dich wundern, dass der Code nichts macht und es kann recht lange dauern, bis du merkst, dass es einfach nur ein Schreibfehler war. Im Gegenasatz dazu ist eine Komponente, sobald sie einmal erstellt ist, bekannt. Sie wird dir beim programmieren schon in der richtigen Schreibweise vorgeschlagen. Komponenten kann man überall suchen, nicht nur in seinem eigenen Objekt. Du musst natürlich vorher erst einmal das Objekt selbst kennen um da drin dann die richtige Komponente zu suchen. Beim Triggern fragst du ja das andere Objekt ab. Die Variable "other" wird dabei mit dem eben getroffenen Collider bestückt. Und bei der Abfrage willst du wissen wie der Tag des anderen Objektes "other" denn heisst. Jetzt kannst du aber auch fragen, ob das andere Objekt "other" denn eine Komponente hat, die "Player" heisst. Zurück bekommst du bei beiden Abfragen true oder false. Beides ist also mehr oder weniger das Gleiche. Strings abzufragen ist immer so ein Problem, weil man sich schnell verschreiben kann und man den Fehler dann meistens nicht sofort erkennt. Wenn du z.B. mit dem Animator arbeitest, wirst du sehr schnell sehen, wie doof das ist, dass man über Strings die Animationen steuert. Mir passiert es ständig, dass ich mich entweder verschreibe oder nicht mehr weiss, wie ich den Parameter genannt hatte. Also immer wieder den Animator aufmachen und gucken was fürn Wort er denn jetzt nun haben will. Klar wenn es einmal geht, dann geht's. Aber es ist halt sehr fehleranfällig, wenn man mit Strings arbeitet. Deswegen schlägt Sascha vor nach Möglichkeit auf Tags zu verzichten und stattdessen nach Komponenten zu suchen.
  14. 1 point
    Lösche in einem leeren Projekt auch nochmal den Scenes-Ordner und importiere dann den Inhalt des Pakets. Joaa... der ist relativ sprechend. Da wüsste ich gar nicht, was ich kommentieren soll. Also, versteh mich nicht falsch: Der ist jetzt nicht zu simpel oder so, aber ich weiß nicht wo ich mit dem Kommentieren anfangen würde, und alles einmal komplett durchkommentieren werd ich eher nicht. Wie gesagt, fragen geht immer
  15. 1 point
    Du meinst, du kriegst das UnityPackage nicht in dein Projekt importiert? Oder wie? Naja, funktioniert ja. Ich denke, das schlimmste was passieren kann wäre, dass du halt irgendwann in Wochen, Monaten oder Jahren merkst, dass es nervig ist, damit weiter zu arbeiten. Ob es um Erweiterungen oder das Finden von Bugs geht. Aber dadurch lernt man dann ja auch. Es muss halt nicht alles beim ersten Versuch perfekt sein. Bei Anfängern nicht, bei Experten aber eben auch nicht. Deshalb ist es eher wichtig, sich die Vor- und Nachteile anzuschauen, die eine Lösung hat. Bei deiner Lösung würde mich stören, dass die Items halt auf einem GameObject definiert sind. Du kannst daraus ein Prefab machen und dieses Prefab unabhängig von deiner Szene bearbeiten. Dann muss das Prefab aber trotzdem immer irgendwo mindestens einmal sein, wenn du das Spiel testen willst, weil die Items sonst einfach nicht existieren. Dann fällt mir auf, dass du die Items nicht einzeln, sondern in einem Array definiert hast. Das heißt, dass du auch nur in Listenform auf deine Items zugreifen kannst (wie es der Shop tut) und ansonsten einen Index brauchst. Wenn du also eine Schatzkiste oder so haben willst, dann definierst du mit einer Nummer, welches Item sich darin verbirgt, und nicht über den Gegenstand selbst. Mich würde es auch beim Editieren nerven, dass alle Items in so einer dicken Liste drinstecken, die man dann mehrfach aufklappen muss, um etwas zu editieren. Abgesehen von ScriptableObjects fände ich da schon eine XML- oder Json-Datei besser, da kann man mit einem Text-Editor ran. Das problematischste daran ist das erste. Je komplexer das Projekt wird, umso wichtiger ist es, die Menge an möglichen Fehlerquellen klein und durchschaubar zu halten. Es geht also nicht nur darum, Fehler möglichst zu vermeiden, sondern auch darum, dass wenn ein Fehler auftritt, dieser leicht zu finden ist. Und da kommt "Code-Qualität" ins Spiel. Das sind so Eigenschaften wie Lesbarkeit, Robustheit (dass man für eine Änderung möglichst wenige Codestellen anfassen muss), Modularität (dass man z.B. einen Teil rausnehmen und austauschen kann, ohne dass gleich drei andere Systeme aufhören zu funktionieren) und weitere solcher Dinge. Wenn man da nicht so perfekt abschneidet, ist das halt nicht automatisch ein Beinbruch. Insbesondere, wenn die bessere Alternative noch nicht so einfach von der Hand geht. Am Ende ist es auch immer eine Frage des Scopes. Wenn du ein Gamejam-Spiel machst oder ganz klare Vorstellungen davon hast, wie groß dein Projekt wird - und dass es nicht besonders komplex wird - dann kannst du sowieso auch einfach dabei bleiben, was du jetzt hast. Wenn sich an dem System nicht mehr viel ändert (wobei man das gerne unterschätzt), dann macht's auch nicht viel. Wie gesagt, im schlimmsten Fall siehst du die Probleme dann irgendwann selber, was sowieso eine gute Sache ist. Denn viele Leute verstehen den Sinn an Code-Qualität nicht, weil sie nie selber "in den Abgrund geblickt" haben. Von daher liegt die Entscheidung bei dir. Ich kann dir sagen, wo Probleme sein können, und ich kann dir auch gerne Fragen zu meinem Code beantworten. Aber am Ende übernimmst du jetzt sozusagen selbst Verantwortung für deinen Code. Und alles so zu machen, wie ich es machen würde, ist vermutlich nicht immer die sinnvollste Entscheidung für dich.
  16. 1 point
    Referenzsemantik. Du kopierst ja nur die Referenz, nicht das Objekt (also das Array in diesem Fall). Ich meinte ja Was das aber auch bedeutet ist, dass wenn der Typ jetzt ne Brechstange rausholt und auf das Auto einprügelt, dass dann auch tatsächlich dein Auto leidet und nicht eine Kopie. Es gibt ja nach wie vor nur ein Array mit Inhalt. Wenn du also den Inhalt änderst, dann gilt das auch für jeden anderen "Betrachter" des Arrays, ist es egal, über welche Variable du auf das Array zugreifst. Hatte gerade Lust auf das Ding, hier meine Implementation: Inventory.unitypackage Ich hab das Inventar einfach komplett statisch gemacht und mit einem Dictionary implementiert. Dadurch ist die Anzahl nicht mehr Teil der SO-Klasse. Die SOs haben nur unveränderliche Propertys. Der Shop (andere Klasse als Inventar) greift darauf zu. Die verfügbaren Items sind mit je einem ScriptableObject gemacht. Alle SOs sind in den Shop reingezogen. So kann man mehrere Shops mit verschiedenen Waren machen.
  17. 1 point
    Nein, eher nicht. Geht zwar, ist aber nicht sinnvoll. ScriptableObjects sind dafür da, Daten zu beinhalten, die im Editor gesetzt werden und dann im Spiel überall verfügbar sind. Du würdest also einmalig per Hand im Editor ein SO anlegen, das Tennisschläger-Daten beschreibt: Name, wie er im Spiel angezeigt wird, das Bild, wie viel man beim Verkauf an Geld kriegt... solche Sachen. Was da genau alles drinsteht und was nicht, hängt vom Spielprinzip ab. Bei Pokémon wäre da an Klassen auch schon fast wieder Schluss. Denn der eine Pokéball und der andere sind komplett austauschbar. Da merkt sich das Spiel einfach einen oder mehrere Stacks von Bällen. Da wird dann das ScriptableObject referenziert um zu definieren, welches Item in welcher Zeile ist, und dann gibt's da ne Zahl obendrauf. Bei Borderlands ist das anders: Wenn da ein Gegner eine Waffe fallen lässt, dann ist die Waffe einzigartig. Die Einzelteile werden nach Vorgaben des Waffentyps (der wäre dann in einem SO) zufällig gerollt. Wenn du zweimal eine Conference Call einsammelst, dann hast du trotzdem zwei verschiedene Waffen. Hier willst du dann tatsächlich ein Objekt pro Gegenstand erzeugen. Aber dieses Objekt wäre dann kein ScriptableObject, sondern ein ganz normales C#-Objekt. Zur Laufzeit ScriptableObjects erstellen ist eine Option, die ich aber selten empfehlen würde. Siehe Pokémon-Vergleich. Da hast du einfach einen Eintrag in z.B. einer Liste oder einem Dictionary, der sagt, hier sind Objekte vom Typ X (Referenz auf ein SO) und so viele sind es. Bei Spielen, wo du ein Objekt pro Gegenstand erzeugst, weil die Gegenstände nicht austauschbar sind, brauchst du auch eher selten eine Zusammenfassung, wie viele du davon hast. Übrigens muss nicht einmal der Gegenstand selbst austauschbar sein, es kann auch eine Meta-Info sein wie die Postion des Items im Inventar. Wenn man an Diablo denkt, wo man seine Items selber in ein Grid einsortieren muss, da ist das dann schon wieder sinnvoll, selbst, wenn man zwei komplett gleiche Items da rein tut. Doch doch, das geht. Statt new benutzt man ScriptableObject.CreateInstance und fertig. Aber wie gesaqt, lohnt nicht. In dem Moment benutzt man nämlich keine der Eigenschaften mehr, die so ein ScriptableObject einem bietet, und dann kann man's auch lassen. Das ist so nicht ganz richtig. Wenn du ein SO in deinen Assets hast, dann verhält es sich auch wie ein Asset. Genau wie bei einem Material - wenn du Werte eines Assets änderst, dann bleiben diese Werte erhalten. Im Build ist das aber nicht mehr. Denn nur weil eine Änderung im Editor bleibt, bleibt sie noch nicht im Spiel. Ohne explizite Anweisung deinerseits merkt sich ein exportiertes Spiel nämlich gar nichts bis nach dem Beenden. Der Punkt ist aber trotzdem nicht ganz unwichtig. ScriptableObjects als Assets sind tatsächlich nicht ohne Weiteres gut für dynamische Dinge zu gebrauchen. Schließlich will man auch im Play Mode testen können, ohne sich alles mögliche dauerhaft zu verändern. Hier gibt es zwei Lösungswege. Man beschränkt sich auf komplett statische (also: unveränderlich, nicht "static") Daten in ScriptableObjects. Das klingt vielleicht etwas komisch, funktioniert aber sehr gut. Du würdest dann deine Genredetail-Klasse in zwei Klassen aufteilen. Die Dinge, die du im Editor einstellst und die unveränderlich sind, packst du in eine SO-Klasse, und die dynamischen Sachen in eine normale Klasse. Letztere kann dann das entsprechende ScriptableObject referenzieren. Du baust ein bisschen krasses Zeug in deine SO-Klasse, damit die Werte im Editor und die Wertem die sich zur Laufzeit ändern, nicht wirklich in denselben Variablen stehen. Mein dickstes Asset im Asset Store besteht aus ScriptableObjects, die genau das tun. Da kannst du dann mit dem ISerializationCallbackReceiver-Interface arbeiten, um die Werte nach dem Laden in andere Variablen rüberzukopieren, die dann anstelle der Felder benutzt werden, die der Editor dann speichert. Das richtig hübsch zu machen, ist aber recht heftig. Ohne weiteres Zutun kannst du dann nämlich z.B. die aktuellen Werte nicht mehr im Editor sehen. Variante 1 ist auf jeden Fall einfacher und, wenn man sich erstmal reingefuchst hat, auch weniger abschreckend. Das machst du mit ScriptableObjects quasi auch. Die MEnge an SOs, die du hast, stellen dann sozusagen deinen Datensatz dar. ScriptableObjects sind einfacher zu verwenden, weil du sie reinziehen kannst. Dafür wird's irgendwann bei großen (aber ich meine: großen) Datenmengen unhandlich, mit so vielen Dateien zu arbeiten. Eine klassische Datenbank (bzw. Daten-Datei... XML, Json oder so etwas) sind kompakter, und können außerdem ggf. leichter mit externen Programmen bearbeitet werden. SOs kannst du dafür direkt in Unity editieren. Alles Vor- und Nachteile. Du wirst aber keine hunderte SOs rumfliegen haben, denn du erstellst wie gesagt nicht für jeden Item-Drop ein neues. Kopieren ist nicht nötig! Arrays sind Objekte, das heißt, du kannst einfach die Referenz kopieren. Anstatt also dein Auto komplett nachzubauen, um jemandem zu zeigen wie es aussieht, sagst du einfach "da drüben steht es". Also ganz stumpf public static Gamedetails[] GamesList; public Gamedetails[] PreGamesList; private void Start() { GamesList = PreGamesList; } Das ist natürlich damit verbunden, dass du deine SOs gegen Änderungen abhärtest.
  18. 1 point
    Richtig erkannt static wird manchmal von Leuten, die es kennenlernen, als Allheilmittel verstanden, damit ein Ding auf irgendein anderes Ding komfortabel zugreifen kann. Dabei ist es nur ein Werkzeug von vielen und will (ausschließlich) an passenden Stellen verwendet werden. In Unity hat man mit static das Problem, dass der Editor damit irgendwie so gar nicht umgehen kann. Unity braucht immer ein Objekt, für das es Werte speichern kann. Wenn man sich Odin anschaut - das ist so ein krasses Ding das u.a. einfach Unitys Serialisierungs-Engine (das ist das Ding, was hier die Grenzen setzt, was man im Editor einstellen kann und was nicht) ersetzt, dann geht da schon noch was. Aber ich bin irgendwie kein großer Fan davon, meine Projekte so stark von Odin abhängig zu machen. Eine Sache würde ich gerne noch etwas genauer beschreiben: ScriptableObjects sind nicht zwangsläufig dafür da, pro Stück eine "Datenbank" zu beinhalten, wie s jetzt deine Komponente tut. Die Dinger sind eher ganz hervorragend dafür, jeder einen Datensatz (also quasi eine Zeile in einer Datenbank-Tabelle) darzustellen. Du machst also so etwas: [CreateAssetMenu(menuName = "Genre Details")] public class Genredetails : ScriptableObject { public string genreName; public float genreEXP; // ... und baust dir pro Genre in deinen Assets so ein Ding. Dann kannst du nämlich Relationen mit den Genres definieren, indem du sie irgendwo reinziehst. Um auf das Beispiel mit dem Inventar zurückzukommen: Da kannst du dann dein Item-ScriptableObject "Tennisschläger" in eine Schatzkiste in deiner Szene ziehen, um zu definieren, dass man eben einen Tennisschläger aus der Kiste zieht. Würde man ein ScriptableObject bauen, das alle Itemsorten des Spiels in einem Array beinhaltet, dann müsste man ja noch irgendwie spezifizieren, um das wievielte Item der Liste es geht. Und wenn sich da mal die Reihenfolge ändert - kabumm, alle Indizes kaputt. Ich empfehle also, das einfach mal zu versuchen. Selbst, wenn du am Ende doch einen anderen Weg besser findest. Lohnt sich alleine für den Lerneffekt. Jedes Genre ist durch ein einzelnes ScriptableObject repräsentiert. Das macht auch das Editieren einfacher, als sich durch so eine lange Liste zu wühlen und die aufzuklappen Da hast du dann sogar die Suchleiste für Assets zur Verfügung. Wenn du mal eine Liste von allen Genres brauchst, kannst du die immer noch anlegen. Aber in sehr vielen Fällen braucht man die gar nicht. Sehr oft will man einfach mit einem bestimmten Ding arbeiten, und dass es theoretisch noch x andere von der Sorte gibt, ist dann irrelevant. Die Schatzkiste muss halt auch nur wissen, was sie dem Spieler beim Öffnen gibt - nicht, was es sonst noch für Items gibt.
  19. 1 point
    Hey ho, ich versuch dir mal bei deinem Problem zu helfen und dir auch gleich Tipps zu geben, wie du dir am besten selber helfen kannst :). 1. Die Console enthält meistens die benötigten Informationen wenn etwas in Unity nicht funktioniert. Sie sagt dir meisten genau wo (Zeilennummer) und was fehlschlägt (NullReferenceException). Für uns wäre es wichtig, dass du die genaue Fehlermessage aus der Console in den Thread kopierst, so können wir dir schneller helfen. 2. Die Fehlermessage NullReferenceException: Object reference not set to an instance of an object ist eine sogenannte Laufzeitexception. Der Exceptiontyp (NullReferenceException) sagt dir auch meistens genau welche Art von Exception auftritt. In deinem Fall handelt es sich um eine NullReferenceException. Das bedeutet, dass ein Objekt zur Laufzeit nicht gefunden wurde. Das kann darauf schließen, dass ... - ... ein Objekt wurde nicht Initalisiert wurde - ... es zur Laufzeit auf null gesetzt wurde - ... es gelöscht wurde - ... es nicht gefunden werden konnte. Wenn man sich deine Bilder anschaut "können" 3 Objekte null sein: public GameObject StoneDisplay; //Zeigt die Anzahl an Steinen an public SteinLager mySteinLager; StoneDisplay.GetComponent<Text>().text Prüfe am besten ob die "public Variablen" auch zur Laufzeit im Inspector zugewiesen sind. Ich vermute aber das er im StoneDisplay keinen Text Element findet. Um das zu überprüfen könntest du ein try/catch Block verwenden oder ein if statement. if(StoneDisplay.GetComponent<Text>() != null){ StoneDisplay.GetComponent<Text>().text = "test"; } else { Debug.log("Error: StoneDisplay.GetComponent<Text>() is not existing"); } Gruß SimpleScript
  20. 1 point
    Oh du benutzt die selben Assets wie ich https://i.imgur.com/KcqYrEV.gifv Aber ich habe leider wenig Zeit für die Entwicklung derzeit.
  21. 1 point
    Heyo, ich hab hier nochmal eine Kleinigkeit für euch. Mit diesem Editorfenster könnt ihr Objekte in einer Szene oder Assets in eine Liste tun und per Klick wieder markieren. Mir ist es beim Arbeiten irgendwann auf den Keks gegangen, dass ich immer dieselben drei Assets bearbeitet habe und dafür jedes Mal entweder die Suchleiste bemüht habe oder mich durch die Ordner geklickt habe. Hiermit geht's schneller und angenehmer. Einfach das hier in einen Editor-Ordner in den Assets schmeißen und fertig. Unter "Window/Favorites" öffnet ihr das Ding. Lustige Features: Objekte, die in einer Szene sind, die geschlossen wird, bleiben in der Liste und werden auch wieder anklickbar, sobald die Szene wieder offen ist. Szenen haben direkt einen Öffnen-Button. Aktuelle Problemchen: Irgendwie gehen die GUIStyles manchmal flöten, dann sehen die Buttons doof aus. Wenn man das Fenster schließt, ist die Liste weg. Hab's noch nicht raus, wie ich das Fenster die Liste serialisieren kann, selbst wenn sie geschlossen wird.
  22. 1 point
    Wieder ist viel Zeit verstrichen, bis ich den nächsten Endgegner erstellt habe (nur Model, noch nicht programmiert). Level 3, Saturn: Die Flügel fahren erst später raus, sind also nicht von Anfang an zu sehen. Der lange Schwanz wird am Ende nach dem Player schlagen.
  23. 1 point
    Du hast es geschafft, die gestellte Frage geschickt zu umgehen Daher nochmal ganz explizit: Willst du, dass die Zahlen in der 3D-Szene an die Würfel gebunden sind? Als wären die Würfel Bildschirme, die etwas anzeigen? Dann könnte man die auch wegdrehen, etwa so: Oder willst du in Wirklichkeit einfach nur, dass eine Zahl über jedem Würfel zu sehen ist, die, genau wie Lebensanzeigen in vielen Top-Down-Spielen nichts mit dem Objekt zu tun haben außer ihrer Position? https://i.kinja-img.com/gawker-media/image/upload/t_original/bcjyblk1goennkdlu0rr.png Ich habe nämlich das Gefühl, dass du eigentlich letzteres willst, und in dem Fall ist die Herangehensweise mit den mehreren World Space-Canvas einfach schonmal komplett falsch. Stattdessen solltest du einen Screen Space-Canvas haben und den UI-Text-Komponenten ein Script geben, das ihre Position z.B. in LateUpdate in Abhängigkeit eines zuweisbaren Zielobjekts setzt. Dafür kannst du z.B. diese Klasse benutzen.
  24. 1 point
    Hallo, @Sascha Ich hab in so verstanden das sich der Text als Child Objekt des Cubes sich Mitbewegen soll. Das geht halt nur im Mode World Space. Aber du hast recht, alles nur spekulativ wenn man nicht genau weiß was er zu erreichen versucht. Gruß Jog
  25. 1 point
    Naja, das ist halt die Frage. Ich war mir beim Anfangspost halt nicht sicher, ob hier nicht doch von einem Screen Space Canvas die Rede ist. Oder aber sein sollte. Man kann ja auch Text in einem Screen Space Canvas so darstellen, dass er über Objekten der 3D-Welt liegt. Ist auch gar nicht mal so schwer. Von daher, @DerStefan, erzähl doch mal: Was genau versuchst du zu erreichen?
  26. 1 point
    Hallo, Wie @Sascha schon gesagt hat, muss man den Canvas Render Mode World Space benutzen. Beim Render Mode World Space wird der Canvas wie ein normales GameObject behandelt, das heißt man kann ihn skalieren, drehen und in der Szene platzieren, und ist somit nicht mehr an einer festen Bildschirmposition gebunden. Aber daran denken den Canvas-Parameter Event Camera die Kamera zuweisen die das Bild rendert, ansonsten kommt es zu Problemen. Screen Space - Overlay: Canvas nicht verschiebbar. Controls, Text nur verschiebbar. Screen Space - Camera: Canvas nicht verschiebbar. Controls, Text mit räumlicher Tiefe darstellbar. Gruß Jog
  27. 1 point
    Der Canvas ist auf World Space gestellt? Und das ist auch so gedacht, dass das UI in der 3D-Welt hockt und nicht als Overlay darüber?
  28. 1 point
    if (other.tag == "Player") if (other.GetComponent<Player>())
  29. 1 point
    Du hast was dummes gesagt. Er hat das dumm genannt. Du meinst, dass er "jeden Tag Dummheiten verbreite". Deine beleidigende Scheiße brauchen wir hier nicht, die kannst du unterm Aluhut lassen. Geh mal lieber gegen Corona-Maßnahmen demonstrieren.
  30. 1 point
    Diese Tablet wird auch mit dem nächsten Update 1.4 kommen. Beide haben eine Canvas schon mit dabei um eine UI zu bauen.
  31. 0 points
    void Update() { UpdateTextLaser(); UpdateTextRaketen(); UpdateTextMinen(); } Als hättest du mir meinen Code geklaut . Ich glaube auch nicht, dass dort der Fehler liegt...

Announcements

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

Weiterleitung zum Entwickler "daubit"



×
×
  • Create New...