Jump to content
Unity Insider Forum

malzbie

Moderators
  • Posts

    5,501
  • Joined

  • Last visited

  • Days Won

    419

Everything posted by malzbie

  1. Dein Problem könnte sein, dass ein Destroy nicht sofort passiert, sondern erst nach ablauf des Update-Loops. Du zerstörst also den letzten Level, welcher aber bis zum Ende des Loops noch da ist, instanzierst einen neuen Level, hast jetzt also 2 Level gleichzeitig drin, suchst nach deinen Punkten, die jetzt 2 Mal drin sind, und findest die alten, schon gefundenen, Punkte. Jetzt erst wird der alte Level aus der Szene raus genommen und deine gefundenen Punkte sind weg. Was dir helfen könnte, wäre ein DestroyImmediate. Das wird aber ausdrücklich nicht empfohlen! https://docs.unity3d.com/ScriptReference/Object.DestroyImmediate.html Suchen die Punkte doch einfach mal im LateUpdate und guck ob dann alles in Ordnung ist.
  2. Mal ein anderer Ansatz. Du nutzt ja LookAt für die Ausrichtung. Was spricht dagegen, dass du dem "Ziel", zu dem sich die Rakete ja ausrichten soll, einfach einen Offset hinzufügst. Je weiter weg vom Ziel, desto größer kann der Offset sein. Dafür könntest du dann den Sinus nutzen. Also: Position des Ziels abfragen, Entfernung zum Ziel ermitteln, dann dieser Position auf der X-Achse, Y-Achse oder beiden über den Sinus einen Offset hinzufügen. Der Ausschlag des Offsets, ist abhängig von der Entfernung und wird immer kleiner, je näher du kommst. Die nun neu berechnete Position nutzt du als LookAt Target. Somit würde die Rakete zu Beginn recht stark schlingern und sich beim näher kommen immer mehr fokusieren. Sollte die Rakete an dem Ziel vorbei fliegen, würde sie sich weiterhin in Richtung Ziel (+Offset) ausrichten. Ich habe in meinem Spiel Cavatus ja auch zielsuchende Raketen drin, die eine gewisse Trägheit haben. Sie richten sich dem Ziel aus, aber eben nicht augenblicklich, sondern langsam. Dafür wird ständig ein Zwischenziel berechnet. Da könntest du ansetzen und den Sinus mit einbauen. Den Codeschnipsel kann ich dir ja mal anhängen: // das alles findet in der FixedUpdate statt myRigid.AddRelativeForce(0, 0, force * Time.deltaTime); // es wird dauernd in eigene Z-Richtung beschleunigt if (Player != null ) { Vector3 targetDirection = Player.transform.position - transform.position; // hier berechne ich die Richtung wo es hin gehen soll float step = rotationSpeed * Time.deltaTime; // hier berechne ich einen Winkel, den sich die Rakete pro Sekunde drehen darf Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, step, 0.0f); // hier berechne ich ein neues Ziel, das ein Stück in Richtung des echten Ziels zeigt transform.rotation = Quaternion.LookRotation(newDirection); // in diese neue Richtung drehe ich mich nun } Ach so: Meine Raketen haben während des Fluges ( solange sie Treibstoff haben) die Gravity ausgeschaltet und einen recht hohen Drag, der die Rakete nicht unendlich beschleunigen lässt. Ja, ich nutze auch in der FixedUpdate die DeltaTime. Somit sind die Werte, die ich einstelle, immer pro Sekunde.
  3. Man kann in unity alles machen. Man hat sogar mehrere Möglichkeiten. Für den Anfang ist hier mal ein Link zum Inputsystem von Unity: https://docs.unity3d.com/ScriptReference/Input.html Unity hat zwar seit einiger Zeit ein neues Inputsystem, aber das ist nicht ganz so einfach zu verstehen, wie das Alte. Und da du anfängst, gehe ich jetzt einfach mal auf das alte System ein. Also, du willst einen einzelnen Schuss bei einem Tastendruck abfeuern. Das geht z.B. mit : if(Input.GetKeyDown(KeyCode.T)){ // kugel instanzieren und nach oben/vorne fliegen lassen } Es gibt Input.GetKey(), Input.GetKeyDown() und Input.GetKeyUp() . Bei GetKey ohen Up oder Down, wird der Tastendruck ständig ausgewertet. Also so lange du die Taste drückst, würde eine Abfrage dieser Taste true ergeben. Bei Input.GetKeyDown() wird nur dieser eine Moment ein true ergeben, bei dem Die Taste runter gedrückt wird. Also in letzten Update-Zyklus war die Taste noch nicht gedrückt, jetzt ist sie es aber. Intern wird also der Wechsel von false auf true überprüft und das passiert nur ein einziges Frame über. Bei Input.GetKeyUp() wird das gehenlassen der Taste ausgewertet. Also eben war sie noch gedrückt, jetzt nicht mehr. Mit diesen drei Abfragen kannst du viele nette Dinge machen. Mit GetKeyDown machste z.B. einen Einzelschuss wie bei einer Pistole. Mit GetKey hättest du ein Dauerfeuer wie bei einem Laser. Mit GetKeyUp könntest du einen Bogen simulieren, bei dem du den Pfeil erst abschießt, wenn du gehen lässt. Ja und mit der Kombination aller 3 Möglichkeiten könntest du eine aufladbare Waffe mit Down starten, sie so lange aufladen wie du drückst und dann beim Up abfeuern. Beispiel : if(Input.GetKeyDown(KeyCode.T)){ // starte Aufladung und starte dafür einen Sound // die Variable "ladung" bekommt einen Grundwert } if(Input.GetKey(KeyCode.T)){ // zeige Fadenkreuz und Ladebalken an. //Die Variable "ladung" wird erhöht. } if(Input.GetKeyUp(KeyCode.T)){ // schieße Energie ab. // Stoppe den Lade-Sound und spiele einen Schuss-Sound ab. // Instanziere ein Geschoss und übergib ihm die Ladung. }
  4. Da bleibt dir wahrscheinlich nichts anderes übrig, als die Grafiken zu zerstückeln und die einzelnen Elemente auf unterschiedliche Ebenen zu legen. Beim oberen Objekt würde ich 4 Teile draus machen. Die Lauffläche (Rechteckig bis zum unteren grünen Saum), die Stirnwand (nur das Grün bis zu den Wölbungen rechts und links) und die Wölbungen selbst. Bei den Rampen würde ich die Grafiken einfach verdoppeln und übereinander legen. Die vordere Grafik ist ab den grauen Steinen (also nach hinten hin) transparent.
  5. Also wörtlich übersetzt sagt dir Unity, dass die Timestamp Werte nicht wie erwartet sind und dass das Video höchstwahrscheinlich nicht richtig abgespielt wird. Wenn ich es richtig sehe, müsste die Meldung gelb sein und nicht rot. Also könnte das Video trotzdem laufen. Wie auch immer. Beim Umwandeln nach H.264 ist etwas schief gelaufen. Es könnte sein, dass Handbreak noch ein paar Einstellungsmöglichkeiten hat, die du probieren kannst. Es kann aber auch sein, dass man nur schlecht oder gar nicht von H.265 nach H.264 umwandeln kann. Es ist ja oft so, dass neuere Versionen irgendwelche Datenformate nicht zurück gewandelt werden könne, weil in ihnen Infos drin sind, die bei alten Formaten einfach nicht berücksichtigt werden. Ich würde an deiner Stelle mal ein Videobearbeitungsprogramm wie z.B. Premiere versuchen. Solche Programme müssten in der Lage sein alles zu wandeln bzw neu zu erstellen. Wenn aber das VR an sich eine Sache ist, die in H.264 nicht existiert, dann wird's nix! Versuch macht kluch!
  6. Wenn du in Unity bist, haut er die Daten immer in den Unity\UnityEditor Bereich rein. Wenn du ein Build von deinem Spiel machst und das Spiel spielst, dann wird der oben genannte Speicherort verwendet. Das verwenden der 2 unterschiedlichen Ort ist also normal. PlayerPrefs. DeleteAll() sollte trotzdem in beiden Bereichen funktionieren. Unity setzt aber selber noch einige Playerprefs-Daten in die Ordner rein. Ob diese Daten mit DeleteAll() auch gelöscht würden, kann ich nicht sagen.
  7. Die einzige Referenz, die du nicht haben kannst, kann ja nur das UI Text Element sein. Hast du denn das Textelement im Inspector auch in den Slot rein gezogen? Warum machst du eigentlich ein neues Thema auf und antwortest nicht im alten Bereich? Alle, die das hier lesen und den anderen Thread nicht gelesen haben, wissen gar nicht worum es geht.
  8. Der gaaanz einfache Weg ist: ZahlText.text= ""+Summe; Einfach so tun, als wäre es ein String, wass du mit den 2 Anführungszeichen hinkriegst und dann + Summe zu schreiben. Est wird dann aus dem leeren String und der Summe ein Kompletter String gemacht. Du kannst auch sowas machen: ZahlText.text= "Die Zahl lautet: "+Summe+" und ist ganz schön groß!";
  9. Das kommt immer ganz drauf an. Cavatus ist momentan nicht der Burner, weil ich anfangs den Preis doch zu hoch gesetzt hatte. Außerdem war mein Veröffentlichungszeitpunkt nicht gut. Da kamen viele große neue Spiele auf den Markt und der Wintersale stand an. Interesse ist da, was ich an der Wishlist und den Downloads der Demo sehen kann. Aber da sie nicht kaufen, ist der Preis wohl immer noch über der Grenze, was man für solch ein Genre bezahlen will. Liegt auch an der momentanen Lage. Bei vielen ist das Geld doch knapper als vor einem Jahr. Meine Pinball Collection läuft, obwohl schon 5 Jahre draußen, deutlich besser. Aber auch von der kann man nicht leben. Das hat MiniJob Charakter. Man kann aber durchaus gutes Geld verdienen, wenn man ein Spiel erschaffen hat, welches den Zeitgeist trifft. Dorfromantik ist so ein Game. Die Jungs hatten vorher schon mal was veröffentlicht, was gefloppt war. Dorfromantik hat aber gezogen und hat sich weit über 500.000 mal verkauft. (Genaue Zahlen hab ich auch nicht) Die Jungs sind also Millionäre geworden. Du siehst, man kann! Die Wahrscheinlichkeit ist aber gering. Das Problem ist doch, dass die großen Konzeren nach ganz kurzer Zeit ein Spiel so stark rabattieren, dass man als kleiner Inide Entwickler dagegen einfach nicht ankommt. Ich habe das vorletzte NeedForSpeed im Sommer für rund 5€ gekauft. 5€!!! Was willst du da für dein Spiel nehmen? Wenn es nicht herausragend künstlerisch ist, musst du es verramschen und schon ist der geplante Verdienst dahin. Denn entweder du verkaufst einige Games für ganz kleines Geld oder du verkaufst ganz wenige Games für einen angemessenen Preis. Tja, soll ich dir Raten bei Steam zu verkaufen? Keine Ahnung. Die Plattform ist gut und hat eine riesen Reichweite. Die Konkurrenz ist aber auch riesig. Wenn du selber nicht der Meinung bist, dass es sich verkaufen wird, dann kannst du dir die Mühe eigentlich sparen. Wenn du aber langfristig etwas aufbauen willst, dann solltest du Steam schon nutzen. Jedes Maß an Bekanntheit ist gut!
  10. Anystate ist immer dann gut, wenn du unbedingt eine Animation ändern musst, egal wo der Animator gerade rum macht. Bei den UI Buttons ist das z.B. immer über Anystate gelöst. Da soll ja ein Button sofort animiert werden, sobald die Maus da drüber ist oder geklickt wird. Interessant wird Anystate dann auch, wenn du mit mehreren Layern arbeites, also zusätzliche Teilanimationen zu den Grundanimationen hinzu mischt. Z.B. wenn ein Player wärend des Laufens von einer Kugel getroffen wird und diesen Hit sofort mit einer Animation darstellen soll. Ich habe früher, als es noch keine Trigger gab, auch alles mit boolschen Typen gelöst. Der Vorteil dabei ist, dass die Variable immer wieder im Code gesetzt werden kann, weil sie ja true oder false ist. Und wenn sie true ist, bleibt sie true, egal wie oft du die nochmal true setzt. Nur, dann musst du die auch irgendwie zurück setzen. Problematisch wird es dann, wenn eine Animation nur einmal angestupst werden soll. Dann musst du entweder im Code nach kurzer Zeit das Dingen wieder auf false setzen, oder aber du baust dir ein Event in die Animationen ein, über den dann in eine Methode gesprungen wird die das Rücksetzen tut. Da ist der Trigger natürlich viel besser, weil er sich selber zurücksetzt. Du hast also 2 unterschiedliche Arten den Animator zu bestücken. Beispiel für einen Player der von Idle zu Walk und wieder zurück zu Idle animiert werden soll: Bei der boolschen Art gehst du in die geloopte Walkanimation rein, sobald die Variable true ist. Dort bleibt der Animator dann bis diese Variable wieder false ist. Idle -(wenn true) -> walk -(wenn false) -> Idle Bei der Trigger Art brauchst du 2 Variablen. Wenn der Trigger Walk kommt, gehts in die Walk, wenn Trigger Idle kommt gehts zurück in die Idle. Idle -(trigger walk) -> walk -(trigger idle) -> idle Für hin und zurück brauchst du also doppelt so viele Parameter. Du kannst den Trigger Idle aber auch bei anderen States nutzen. Der Player hat ja vielleicht ganz viel Tätigkeiten, die alle mit dem Trigger Idle beendet werden können. Ich persönlich vermische die Arten und nutze alles was für meine Zwecke gut ist. Im Entwicklungsprozess wird dann auch germe mal umgestellt, weil ein anderer Weg dann doch praktischer ist. So ist das! Man kann selten zu Beginn sagen was der richtige Weg sein wird. Du wirst deinen Weg finden!
  11. Hi! Anystate ist für dein Vorhaben nicht gut. Anystate bedeutet ja, dass über diesen Pfad eine Animation gestartet werden soll, egal welche Animation gerade ausgeführt wird. Das würde z.B. Sinn machen, wenn in die Idle Animation gesprungen werden soll. Also egal, ob man gerade läuft, geht, tanzt oder schießt. Man kann zwar auch beim Anystate mehrere Bedingungen verknüpfen, aber eigentlich sind Animationen ja fortlaufend, so wie bei dir. Man muss sich ja erst hinsetzen, bevor man sitzen tut. Und wenn man dann sitzt, kann man nicht sofort laufen, denn man muss zuerste wieder aufstehen. Also sind die Transitions meistens von einer Animation zur nächsten, wie in einer Kette, aufgebaut. Dann ist es wichtig den richtigen Parametertyp zu wählen. Man kann zwar fast immer boolsche Typen nehmen, aber die muss man dann auch immer wieder zurücksetzen. Ein guter Weg ist es die boolschen Typen als obersten Zustand zu nutzen. Z.B. wenn du bei der Bewegung zwischen laufend, gehend oder hockend unterscheidest. Oder aber du hast unterschiedliche Animationsbereiche, je nachdem welche Waffe oder welches Werkzeug dein Player in der Hand hat. Du kannst das natürlich so machen, wie es dir am besten gefällt. Ob Trigger oder bool. Beide haben Vor- und Nachteile. Wenn du von Anystate her kommst, bietet sich der Trigger-Typ an. Den setzt man einmalig und er setzt sich selbst zurück. Steht also nicht dauernd an wie eine bool. Wenn du nur eine Bool nutzen willst, kannst du nicht von Anystate gehen, dann muss die Transition von einer anderen Animation wie z.B. die Idle Animation her kommen, weil eben sonst genau das passiert, was du da erlebst. Wenn Trigger "hinsetzen" gesetzt wurde oder die Bool "sitzen" true ist, wird die Hinsetzen-Animation abgespielt. Von dieser Animation geht es automatisch, also nach Ablauf der Animationszeit, zur Sitzen-Animation. Also stellst du bei der Transition "Has Exittime" an und stellst den Wert auf 1. Die Sitzen-Animation ist dann wahrscheinlich auf loop gestellt, die über eine andere Bedingung beendet wird. Hier dann "HasExittime" ausschalten. Wenn dann die Bool "sitzen" auf false geschaltet wird oder der Trigger "aufstehen" gesetzt wurde geht es zur Aufsteh-Animation, die wieder abläuft und automatisch zur Idle Animation geht.
  12. Ja.... ich habe das nicht richtig abgeschrieben, Aber weisst ja wie es wirklich heisst. Nämlich so wie in dem Zitat. Wenn jemand einen Codevorschlag postet, so wie ich das getan habe, dann reicht es nicht ihn einfach zu kopieren. Du muss schon mitdenken, denn ich habe den Code nicht getestet. Ich habe dir einfach eine Möglichkeit gezeigt und deswegen dazu geschrieben ": Du schaffst das!
  13. Erstmal zum While: Sobald die Schleife ausgeführt wird ( weil canJump true ist), wird gleich darunter abgefragt, ob canJump true ist. Und wenn ja ( ist ja, sonst wären wir nicht in der Schleife), dann wird es sofort auf false gesetzt. Somit ist die Schleife unnütz, denn sie wird immer nach einem Durchlauf beendet. In diesem Bereich "setzt" du die Velocity fürs Springen. Gleichzeitig setzt du die Bewegungs Velocity auf 0. Soll das so sein, dass er beim Springen nur senkrecht nach oben hüpft? In der FixedUpdate fragst du den Joystick ab und "setzt" wieder eine Velocity. Diesmal bekommt die x Achse einen wert und die Y Achse wird 0 ! Wird der Joystick nicht bewegt, dann setzt du beide Achsen auf 0, denn genau das bedeutet Vector2.zero. Solltest du gerade die Velocity fürs Springen gesetzt haben, wird sie hier auf 0 gesetzt. Egal ob du den Joystick bewegt hast oder nicht. Am Besten du setzt eine Vector2 Variable mit den RB Velocities die er gerade hat und änderst dann diese Variable auf der entsprechenden Achse ab. Dann nutzt du die veränderte Variable und übergibst sie dem RB. So etwa: void FixedUpdate(){ Vector2 isVelocity = rb.velocity; // Hilfsvarable mit Werten vom rb füllen if(movementJoystick.joysticVex.x !=0){ // wenn was am Joystick passiert dann... isVelocity.x = movementJoystick.x * playerSpeed; //nur den x-Wert der Variable überschreiben } if(buttonHeldDown && canJump){ // wenn der Button gedruckt ist und ich auch hüpfen darf... isVelocity.y = jumpForce; // nur den y-Wert der Variable überschreiben canJump= false; } rb.velocity= isVelocity; // der RB bekommt jetzt die neuen Werte komplett übergeben. Wurde kein Wert überschrieben, bekommt er die ausgelesenen Werte zurück } FixedUpdate und Update laufen zu unterschiedlichen Zyklen ab. Die Update macht das bei jedem Frame und die Fixed Update nach einer eingestellten Zeit. Das ist also so gut wie niemals zur selben Zeit. Man sollte alle Dinge die einen RB betreffen, egal ob du die Velocity setzt oder die Force addierst, in der FixedUpdate machen, damit das Ganze synchron mit allen anderen physikalischen Dingen wie Collidern oder Triggern oder der Schwerkraft passiert. Deswegen hab ich dir in meinem Beispiel alles in die FixedUpdate gepackt.
  14. Das große Problem am "Programmieren lernen mit Unity" ist, dass du dabei 2 Dinge lernen musst/willst. Das Eine ist das Programmieren selbst. Also quasi eine Sprache zu erlernen. Aber eben nicht nur die Vokabeln sondern auch die richtige Anwendung. Das Andere ist die Besonderheit in Unity, die Objekte, Module und Funktionen zu steuern und Informationen über sie abzufragen. Wenn man sich Tutorials für Unity anschaut, dann wird mehr oder weniger das Können der Programmiersprache vorraus gesetzt und es geht meist nur um die Besonderheiten in Unity. Diese sind zwar alle mit der Programmiersprache verzahnt, aber sie sind eben Obendrauf! Wenn man das Programmieren nicht verstanden hat, kommt man mit den Besonderheiten in Unity nicht weit. Deswegen würde ich empfehlen entweder erstmal nur die Grundlagen des Programmierens zu lernen (unabhängig von Unity). Oder aber mit Unity zusammen, aber dann (egal ob das Projekt einem gefällt oder nicht) nach jedem Schritt zu schauen, ob man verstanden hat was da passiert. Einfach mal eine ähnliches Szenario aufbauen und das Gelernte gleich anwenden. Auch wenn es erst einmal sinnlos erscheint. Schritt für Schritt! Aber das musst du machen! Es einfach nur abtippen um dann zu sehen, dass es bei dir genauso funktioniert reicht nicht. Du musst es zerlegen und analysieren. Es wird dann bestimmt irgendwann Klick machen. Und dann ist alles klar! Es wird immer Dinge geben, die du erst mal nicht verstehst. Aber du wirst mit jedem Mal schneller zur Lösung kommen. Und dann kannst du das Wissen auf alles was du willst anwenden. Du bist bestimmt nicht dumm. Es hat einfach nur noch nicht "klick" gemacht!
  15. Hast du es mal mit .localBounds probiert? https://docs.unity3d.com/ScriptReference/Renderer-localBounds.html
  16. Schau dir deine Grafik von ganz oben an. Da hast du 0° als gerade nach oben. Willst du jetzt vor und zurück drehen, geht's einmal ins Positive und einmal ins Negative. Wäre der Grundwinkel jetzt nicht 0° sondern 180°, dann würde es niemals zu einem negativen Winkel kommen und alles ist viel leichter zu bewerkstelligen. das ist alles. Aber naürlich nicht auf alle Gegebenheiten anzuwenden.
  17. Mit Zufall meinte ich, dass es wegen den internen Dingen andere Winkel bei auslesen sind. Nicht deine Zufallswerte. Ich würde dir nicht abraten. Wenn's funktioniert, dann funktionierts! Bei Quaternions bin ich raus!
  18. Ja, das ist so ein Problem. Wenn du transform.Rotate nutzt dann rotiert er um die Werte, die du ihm übergibst. Das ist einfach, weil du nicht wissen musst, welche Werte vorher da waren. Ist aber blöd, wenn man das wo anders setzen will. Da intern die Quaternions genommen werden, die den sogenannten Gimbal Lock unterbinden, können theoretisch alle 3 Achsen verändert werden, obwohl du nur über die X Achse drehen wolltest. Versuch mal deine Umgebung so umzubauen, dass du keine negativen Winkel hast. Du fängst also nicht bei 0 an, sondern bei 180. Deine Endwerte wären dann 20° und 340°. Und immer wenn durch Zufall der Wert negativ sein sollte, addierst du einfach 360° drauf. Jetzt nutzt du auch nicht Rotate, sondern setzt einfach die neuen Werte, so wie du es willst. Außerdem solltest du in der Update immer die Time.deltaTime als Multiplikator für Bewegungen und Drehungen nutzen, damit es auf allen Rechnern und mit allen Framerates gleich schnell abläuft. Also: Dreh dein Dingen so, dass oben jetzt nicht mehr 0° sondern 180° ist. Das Folgende passiert jetzt in der Update, also jedes Frame. Die Variablen sind lokal in der Update deklariert. Du kannst die natürlich auch oben deklarieren. Zuerst lokale Winkel auslesen und und einer Vector3 Variable übergeben. - Vector3 theRotation = transform.localEulerAngles; Sollte theRotation.x negativ sein, dann addiere gleich 360° dazu. Wenn sie über 360° ist, ziehst du halt 360° ab. Dann den Speed mit der deltaTime und einem frei einstellbaren Faktor mutiplizieren. Du musst dir überlegen, wieviele Grad/Sekunde gedreht werden sollen. Nehmen wir mal maximal 20°/Sekunde an. - float speed=Input.GetAxis("Horizontal")*Time.deltaTime*20; Dann den neuen Winkel einklemmen dem x der Vector3 Variable übergeben - theRotation.x= Mathf.Clamp(theRotation.x+speed, wmin,wmax); Dann dem Transform übergeben. - transform.localEulerAngles = theRotation; Das zufällige Setzen per Maus machste genauso, nur ohne den Speed mit einzubauen. Also auslesen, dem theRotation.x einen Zufallswert geben und alles wieder dem Transform übergeben. Transform.Rotate ist auch nichts anderes als ein Setzen von Werten. Das passiert nur intern und du brauchst dich nicht um die vorigen Werte kümmern. Dadurch verlierst du aber auch Kontrolle, deswegen mach es mal so, wie ich geschrieben habe. Ich habe das aus dem Kopf da hin geklatscht! Können also Fehler drin sein. Du weißt aber jetzt was ich meine.
  19. Nicht schlecht! Das Einzige was ich jetzt etwas übertrieben fand, sind die Holzfässer die aus einer recht schmalen Flinte raus kommen. Ist nicht schlimm, aber vielleicht könnte man das etwas logischer gestalten. Ansonsten top!
  20. Willkommen! Nachschlagewerke sind immer gut. Der Carsten Seifert war vor einigen Jahren auch hier im Forum unterwegs (zur Zeit von Unity 5). Viel Spaß bei uns.
  21. Also ich sehe da 2 Wege. Eintweder du gehst davon aus, dass alle Objekte zu Beginn in der obersten Ebene sind, oder sie sind zu Beginn in der untersten Ebene. Es ist ja eine Frage der Verortung. Also wie und wo können Sprites übereinander liegen. Geht es da nur um eine Art Inventory, dann ist es ja leicht zu wissen, welche Sprites an welcher Position liegen. Und wenn sie dann gestackt würden, dann müsste(n) das(die) Sprite(s) im Layer jeweils eins nach unten. Immer nur das Sprite im obersten Layer kann angeklickt werden. Das wäre einfach für den Test und ginge ohne Liste. Wird das oberste Sprite aufgehoben, dann müssten alle da drunterliegenden eine Ebene höher im Layer. Das wäre ein kleiner Befehl (event) für alle Sprites im entsprechenden Fach. Ist es aber irgendwie in einer Spielewelt, wo zufälligerwiese Sprites voreinander liegen würden, dann wird das schon schwieriger, denn jetzt musst du es irgenwie schaffen, diesen Haufen zu gruppieren. Da sehe ich klare Vorteile bei einer oder mehreren Listen, die immer dann da sind, wenn es zu Anhäufungen von Sprites kommt. Was ich aber noch wichtig fände, ist die Tatsache, dass man nicht unendlich viele SortingLayer anlegen muss. Man braucht vielleicht 3 für das Stacken. Das oberste Sprite soll natürlich immer oben gezeichnet sein. Das da drunter dann auch so, dass es optisch direkt unter dem Obersten liegt. Aber alle weiteren Sprites des Stacks können gemeinsam im untersten Layer liege. Ist vollkommen egal, wann welches gezeichnet wird. Nur musst du dann intern wieder eine Liste haben, die die richtige Reihenfolge für alle Sprites darstellt. Und dann ist es wirklich gut, wenn in der Liste das Oberste gelöscht würde und alle anderen nachrutschen. Die jetzt obersten 2 Sprites verschieben sich um einen Layer, fürs optische, und alle weiteren bleiben im untersten Layer. Der Test, welches Sprite denn anklickbar ist, ist ja ganz einfach über die Liste zu ermitteln.
  22. Das müsste eigentlich mit dem Spriterenderer zu machen sein. Der hat nämlich Sorting Layer. Die kann man im Code auslesen und auch setzen. Du musst also den aufnehmbaren Sprites sagen, dass sie in dem obersten Layer sind. Nur Sprites aus diesem Layer können aufgenommen werden. Der Layer ist ja bekannt und den kann man ja beim Versuch eines Drags abfragen. Jetzt musst du nur irgendwie hin kriegen, dass ein Sprite es merkt, dass ein anderes auf ihm drauf positioniert wurde und sich dann selbstständig in einen tieferen Layer schiebt. Genauso muss erkannt werden, dass ein Sprite von obendrauf jetzt weg ist und man selbst jetzt oben liegt.
  23. Da bieten sich die Trigger an. Du brauchst also einen oder mehrere Collider, die über der Wiese liegen. Denen gibst du einen Tag, z.B. Grass und stellst den/die Collider auf Trigger. Wenn dein Player da rein läuft, werden Triggerevents gestartet. Die kannst du im Code nutzen. Das OnTgriggerEnter() Event wäre dann dafür da, zu sagen, dass du ab jetzt auf dem Grass bist. Beim verlassen des Triggers, würde OnTriggerExit() aufgerufen werden, was dir sagt, dass du das Gras wieder verlassen hast. https://docs.unity3d.com/ScriptReference/Collider.html Schau beim Link und scroll runter zu den Messages. Da findest du alles Nötige.
×
×
  • Create New...