Jump to content
Unity Insider Forum

Thariel

Members
  • Content count

    434
  • Joined

  • Last visited

  • Days Won

    13

Everything posted by Thariel

  1. Hi Wenn der Spieler die Karte öffnet, soll er immer schön zentriert sein. Dazu hab ich eine Funktion gemacht. Diese wird beim öffnen der Karte aufgerufen und ist auch über einen Schaltfläche aufrufbar. Jedoch funktioniert es nie auf Anhieb, sondern immer erst beim zweiten Versuch. Ich muss also die Karte 2x hintereinander öffnen, damit die Position korrekt gesetzt wird. Wie ihr seht ist bei der Position im RectTransform immer etwas merkwürdig, entweder bei X oder Y. Hab schon Canvas.ForceUpdateCanvases() und LayoutRebuilder.ForceRebuildLayoutImmediate() ausprobiert. public void CmdCenterPlayer() { float x = Mathf.Floor(PlayerController.singleton.transform.position.x / 4.0F); float y = Mathf.Floor(PlayerController.singleton.transform.position.z / 4.0F); rectContent.anchoredPosition = new Vector2(-x * 50, -y * 50); //50=map tile size } Wer weis warum das so ist? Solche unlogischen Dinge machen mich echt nervös! 😡 PS: Das ganze befindet sich in einem ScrollView und das GameObjekt im Inspector ist das Content-Objekt vom ScrollView.
  2. Der Wert ist schon aktuell, es ist die direkte Position vom Player und diese siehst du auch auf der Karte (gelber Pfeil). Habe das Problem aber jetzt gelöst: Hab einfach das ganze umgebaut und verwende jetzt kein ScrollView mehr, sondern einfach ein Image mit Maske. Sieht jetzt immer noch alles genau gleich aus, aber kein ScrollView, das rein pfuscht. Danke
  3. Macht leider keinen Unterschied! Komisch ist auch, dass manchmal X korrekt aktualisiert wird und machnmal Y, aber nie beide auf Anhieb korrekt... Hast du noch eine andere Idee?
  4. Hi Ich hab in der Update() Funktion einfach ein SetActive() Toggle eingebaut: if(Input.GetKeyDown(KeyCode.M)) { goWindow.SetActive(!goWindow.activeInHierarchy); CmdCenterPlayer(); }
  5. Hey! Eine komische Frage, was? Es geht um Patreon, eine Webseite um Spenden für sein Projekt zu sammeln und die Spender dafür zu belohnen. Ich frage mich, ob man einer limitierten Anzahl von Let's Players früheren Zugang zum Spiel geben könnte und nur diese das Spiel Streamen dürften. Sie hätten den Vorteil, dass sie exklusiven Content erstellen dürften und ihr Kanal damit wächst und würden dafür zu den Entwicklungskosten beitragen. Win-Win für beide. Aber könnte ich so ein exklusives Recht auf YT durchsetzen und Videos löschen lassen, die jemand hoch lädt, ohne dafür berechtigt zu sein?
  6. Hi Mache gerade ein Level Editor (Runtime) und Zeichne mit der Maus den Boden, welcher aus einzelnen Tiles besteht. Danach drücke ich ein Button, um die Wände zu generieren. Das Problem: Unity scheint nur eine bestimmte Anzahl an Instazierungen zu vollführen. Immer wieder fehlen völlig willkürlich Wände. Wenn die den Button ganz oft nacheinander klicke, füllen sie die fehlenden Teile langsam. Hab danach eine Coroutine gemacht und weiter experimentiert. Wenn ich jetzt zum Beispiel den "Alle Wände Erstellen"-Button klicke, funktioniert es nur mit einem massenhaften Spam von Coroutines: Die erste ruft in allen Boden Tiles die Funktion "Wände erstellen" auf und jeder Boden hat wiederum eine Coroutine, welcher die Wände erstellt. Und das schlimmste am ganzen: Ich muss in jeder Schleife ein yield return new WaitForFixedUpdate() aufrufen und in der Haupt-Coroutine gleich 5x hintereinander, damit sie erst weiter macht, wenn der aktuelle Boden fertig ist. Alles sehr langsam und unelegant, aber nur so wird das Level zuverlässig aufgebaut. Hat jemand eine Idee, wie das viel besser geht?
  7. Jetzt funktioniert es. Weiss zwar nicht warum genau, aber nach dieser Änderung funktioniert alles perfekt, auch ohne Coroutine. Das Funktioniert NICHT: GameObject go = Instantiate(goPillarPrefab, transform.position, Quaternion.identity); Quaternion lookRotation = Quaternion.LookRotation(direction, transform.up); lookRotation *= Quaternion.Euler(0, 45, 0); //damit die zelle um 90° winkel ist go.transform.rotation = lookRotation; Das FUNKTIONIERT: Quaternion lookRotation = Quaternion.LookRotation(direction, transform.up); lookRotation *= Quaternion.Euler(0, 45, 0); //damit die zelle um 90° winkel ist GameObject go = Instantiate(goPillarPrefab, transform.position, lookRotation); Einfach die Rotation vorher berechnen und bei Instantiate() direkt übergeben.
  8. Thariel

    begrenzte drehung des Spielers

    Vielleicht machst du Waypoints und berechnest immer die Richtung vom Kanu zum nächsten Waypoint und Clampst Kamera/Spieler/Kanu im Winkel... falls ich das richtig verstanden habe 🤔
  9. Leute, jetzt mal ernsthaft! Was passiert da? 😱 Nachdem ich ein Bode-Tile gebaut habe, ruft dieses Script alle Boden-Tiles in der Umgebung auf, um Wände und Pfosten zu aktualisieren: LayerMask mask = LayerMask.GetMask("Level"); Collider[] cols = Physics.OverlapBox(goGhost.transform.position, new Vector3(4, 4, 4), Quaternion.identity, mask); foreach(Collider col in cols) { if (col.transform.gameObject.tag == "Floor") { col.transform.gameObject.GetComponent<DesignerObject>().UpdateWalls(); col.transform.gameObject.GetComponent<DesignerObject>().UpdatePillars(); } } Wie Wände werden generiert, aber es entsteht nur ein Pfosten: Dieses Script generiert die Pfosten: List<Vector3[]> points = new List<Vector3[]>(); //um on OnDrawGizmos() zu zeichnen, was genau passiert public void UpdatePillars() { List<Vector3> directions = new List<Vector3>() { transform.forward + transform.right, transform.forward + -transform.right, -transform.forward + transform.right, -transform.forward + -transform.right }; int round = 0; foreach (Vector3 direction in directions) { Debug.Log("Round " + round + " with direction " + direction + " is starting..."); Vector3 myCenterPoint = transform.position + new Vector3(0, 2, 0); Vector3 myCornerPoint = myCenterPoint + (direction * 2); points.Add(new Vector3[] {myCenterPoint, myCornerPoint }); int pillarCount = 0; int wallCount = 0; GameObject goPillar = null; LayerMask mask = LayerMask.GetMask("Level"); Collider[] cols = Physics.OverlapSphere(myCornerPoint, 0.5F, mask); foreach (Collider col in cols) { Debug.Log("Round " + round + ": Collider found: " + col.transform.gameObject.name); if (col.transform.gameObject.tag == "Wall") wallCount++; if (col.transform.gameObject.tag == "Pillar") { pillarCount++; goPillar = col.transform.gameObject; } } if (wallCount == 0 && pillarCount > 0) { Debug.Log("Round " + round + ": Destroy Pillar"); Destroy(goPillar); } if (wallCount > 0 && pillarCount == 0) { GameObject go = Instantiate(goPillarPrefab, transform.position, Quaternion.identity); Quaternion lookRotation = Quaternion.LookRotation(direction, transform.up); lookRotation *= Quaternion.Euler(0, 45, 0); //damit die zelle um 90° winkel ist go.transform.rotation = lookRotation; go.transform.SetParent(transform.parent); go.name = goPillarPrefab.name; Debug.Log("Round " + round + ": Pillar Created."); } Debug.Log("Round " + round + " finished."); round++; } } Ich zeichne auch genau auf, WO OverlapSphere() wirkt und auch die Richtung und die Colliders sind ersichtlich (alle haben korrekten Layer + Tag): private void OnDrawGizmosSelected() { foreach (Vector3[] point in points) { Gizmos.DrawLine(point[0], point[1]); Gizmos.DrawSphere(point[1], 0.5F); } } Aber die Konsole gibt völlig unterwartete Ausgaben: In der ersten "direction" findet es 4 Wände, in der zweiten WIEDER 4 Wände UND ein Pfosten und dann aber nichts mehr... Versteh ich nicht 🤔
  10. Es ist schon ein Grid System. Habe verschiedene Systeme ausprobiert auch deine Variante mir einem Array, das generieren von Wänden ist damit natürlich einfacher, aber mein System hat andere Vorteile. Aber ist ein anderes Thema. Ist es so, dass nach einem Instantiate() direkt in der nächsten Zeile schon Physik Abfragen durchgeführt werden können oder ist das GameObjekt erst im nächsten Frame da? Hab mal ein Video zum besseren Verständnis gemacht.
  11. Da dann poste ich den Code doch mal. Aber nicht lachen, ist noch ein Prototyp Das Script mit dieser Funktion befindet sich auf jedem Boden-Tile. public void UpdateWalls() { List<Vector3> directions = new List<Vector3>() { transform.forward, -transform.forward, transform.right, -transform.right }; foreach (Vector3 direction in directions) { Vector3 myCenterPoint = transform.position + new Vector3(0, 2, 0); Vector3 yourCenterPoint = myCenterPoint + (direction * 4); bool neighbourCellHasFloor = false; LayerMask mask = LayerMask.GetMask("Level"); RaycastHit hit; if (Physics.Linecast(yourCenterPoint, yourCenterPoint + new Vector3(0, -4, 0), out hit, mask)) { if (hit.transform.gameObject.tag == "Floor") neighbourCellHasFloor = true; } bool isWall = false; GameObject goWall = null; if (Physics.Linecast(myCenterPoint, yourCenterPoint, out hit, mask)) { if (hit.transform.gameObject.tag == "Wall") { isWall = true; goWall = hit.transform.gameObject; } } if (neighbourCellHasFloor && isWall) Destroy(goWall); if (!neighbourCellHasFloor && !isWall) { GameObject go = Instantiate(goWallPrefab, transform.position + positionOffset, Quaternion.identity * Quaternion.Euler(rotationOffset)); go.transform.rotation = Quaternion.LookRotation(direction, transform.up); go.transform.SetParent(transform.parent); go.name = goWallPrefab.name; } } } Und diese Coroutine ruft die Funktion auf jedem Boden-Tile auf: //gos = alle boden tiles IEnumerator GenerateWalls(GameObject[] gos) { foreach (GameObject go in gos) { go.GetComponent<DesignerObject>().UpdateWalls(); //yield return new WaitForFixedUpdate(); yield return null; } yield return null; }
  12. Hi Ich frage mich schon die ganze Zeit, wie in LoG die Kameraeinstellung so funktioniert: Man sieht viel auf einmal (Boden und beide Seiten der Wand). Das Feld ist recht klein und die Kamera recht nah an der Wand. Man sieht fast keine Perspektivische Verzerrung. In Unity bekomme ich so eine Kamera einfach nicht hin, ausser ich mache das Feld absurd gross, oder ändere die Perspektive bis zur völligen Verzerrung. Wie könnte das gemacht sein? Hier ein Video:
  13. Hey malzbie! Echt super, wie du dir Mühe gemacht hast! Vielen Dank Ich hab 4x4 Felder und dafür aber 1.9m Distanz statt 1.4 und FoV 60. Ich werde aber sicher genau die selben Werte und auch Feldgrösser ausprobieren wie du ermittelt hast. Du scheinst es genau getroffen zu haben
  14. Vielen Dank, dass du dir die Mühe gemacht hast! Du hast Recht, wenn man die Kamera nach hinten setzt, funktioniert das schon viel besser. Bin mit den Werten FoV, Neigung, Höhe und Position Offset zur Mitte am experimentieren. Habe es aber noch nicht so hinbekommen, wie in Grimrock. Schau mal deine Szene an... Wenn jetzt ein Gegner auf dem gegenüber liegenden Feld steht, ist die Distanz schon absurd gross für ein Kampf und deine Kamera ist auch sehr tief am Boden. In Grimrock wirkt das alles irgendwie ganz anders.
  15. Schau mal wie das bei mir aussieht bei 110. Alles ist total verzerrt. Der Pfosten scheint Rechteckig und alles sieht unangenehm aus, auch die Steuerung. Das mit der Kamera leicht nach hinten zu setzen habe ich schon probiert. Dann sieht man zwar mehr Wand, aber die Rotation ist dann merkwürdig. In Legend of Grimrock sieht die Rotation nicht so aus, als wäre die Kamera nicht in der Mitte des Feldes...
  16. Hi Ich habe viele NPC's und diese haben verschiedene Aktivitäten, die sie ausüben können. Der eine geht zum Beispiel an Wände und hämmert mit einem Hammer daran rum. Jetzt möchte ich, dass bei jedem Hammerschlag, ein passender Sound abgespielt wird. Bis jetzt hab ich das bei einfacheren Sachen immer mit einem Timer gemacht. Hab auch gehört, dass man Animation Events machen könnte. Gibt es noch andere Möglichkeiten? Weil die Animationen sind ziemlich lang und die oben genannten Möglichkeiten scheinen mir etwas zu langwierig...
  17. Aber ich könnte auch ein kleines Script schreiben, das die Animation abspielt und ich drücke bei jedem "Hammerschlag" ein Button im Inspector. Dann speichert es jeweils die Zeit in einer List<float> und spielt es dann getimert ab... 🤨
  18. Thariel

    Berufliche Zukunft

    Ich hab dir auch ein Ratschlag. Entweder findest du ihn total albern oder er wird dir sehr weiter helfen... ist eher ein spiritueller Ratschlag, hilft mir aber immer wieder sehr, die richtige Entscheidungen zu treffen. Vor allem wenn es darum geht, Lebensentscheidungen zu treffen wo auch Angst eine Rolle spielt (tauge ich dazu / schaff ich das überhaupt / bin ich nicht zu alt dafür / was werden nur die anderen Leute über mich denken / ... /). Nimm dir ein Moment Zeit und stell dir vor, wie du 80 Jahre alt bist und auf dem Sterbebett liegst. Stell dir vor, wie du jetzt an diesen Moment hier denkst. Was würde sich dein 80-jähriges ICH wünschen, wie du dich jetzt entschieden hast? Mutig oder ängstlich? Was wäre schlimmer, wenn du etwas Probiert hast, das klappt oder auch nicht oder einfach nichts gemacht hättest, nur weil dich nicht sicher bist, ob du dazu taugst? So wie du das beschreibst könnte man meinen, dass du bei einer Umschulung alles bisherige gelernte vergessen würdest, das ist aber nicht so! Und wenn es wirklich nicht klappt, machst du eben wieder was anderes und es fällt vielleicht eine gute Geschichte ab! Am schlimmsten ist es, wenn du mal bereust, nichts versucht zu haben. Entweder du GEWINNST oder du LERNST.
  19. Thariel

    Mathematische Frage

    Hi Ich habe eine mathematische Frage und weiss gerade nicht, wie ich das am besten Löse und weiss auch nicht, nach welchem Begriff ich suchen könnte. Im Spiel kann man Fischfallen bauen. Eine Falle fängt 10 Fische pro Tag. Wenn man zwei fallen direkt nebeneinander baut, fängt man aber natürlich nicht 20 Fische, weil die Menge an Fisch im Ozean begrenzt sind. Eine Falle hat eine Effektifität von 100%. Zwei Fallen nebeneinander eine Effektivität von 66% (100/1.5). Die Effektivität nimmt mit der Distanz aber wieder zu. Ab 30m Distanz, ist die Effektivität wieder 100% (100/1). Also Distanz: 0<---------------------------------------->30 Effektivität: 1.5<---------------------------------------->1 Das heisst, bei einer Distanz von 15m. wäre die Effektivität beider Fallen bei 80% (100/1.25) und würden zusammen 16 Fische fangen, statt 20. Meine Fragen: Wie nennt man diese Art von Berechnung, wonach müsste ich suchen? Gibt es dafür in Unity oder C# eine Funktion? Wie berechne ich das genau, dass ich die Effektivität erhalte, wenn ich die Distanz kenne? Danke schon mal
  20. Thariel

    Mathematische Frage

    Ja genau 🤣 Habs jetzt so ähnlich gemacht: float effLoss = (distance / 30.0F) * 0.5F; effLoss = 0.5-effLoss; effLoss++; //jetzt ist effLoss zwischen 1-1.5 in Relation zu den 0-30m Danke nochmals
  21. Thariel

    Mathematische Frage

    Es ist keine Kurve, sondern Linear/Proportional. Schaue mir das mal an, aber ich glaube Log/Log10 fällt schon mal weg. Distanz 0 = Effektivität 1.5 //Alle Zwischenschritte Distanz 15 = Effektivität 1.25 //Alle Zwischenschritte Distanz 30 = Effektivität 1 EDIT: Ich glaube ich habs jetzt raus!
  22. Thariel

    Laptop anforderungen für unity?

    Hi Unity läuft fast überall. Es kommt darauf an, was du mit Unity machst und wie gross dein Projekt ist. Ich empfehle unbedingt mindestens 8GB Ram, mit 4 kommst du nicht weit. Ehrlich gesagt, würde ich dir grundsätzlich von einem Labtop abraten, ausser du brauchst das Labtop wirklich fürs Studium oder die Schule (weil du es dort benutzen musst). Selbst dann würde ich so schnell wie möglich trotzdem noch ein PC zulegen. Ich denke aber schon, dass du auf deinem Labtop Unity kennen lernen kannst und einiges schon ausprobieren kannst.
  23. Hi Suche eine elegante Lösung für folgendes Problem (schwierig zu erklären): Der Spieler kann viele verschiedene Strukturen bauen und jede Struktur hat ein eigenes Script mit einer eigenen Logik (AnimalTrap.cs, Campfire.cs, ...). Jede Struktur hat auch ein passendes UI Fenster, das geöffnet wird, wenn der Spieler [E] drückt (WndAnimalTrap.cs, WndCampfire.cs, ...). Die UI Fenster haben verschiedene Slots, in die der Spieler Items vom Inventar setzen kann. Dies ist immer das selbe Script (SlotScript.cs). Die Haupt-Scripte mit der Logik (AnimalTrap.cs, Campfire.cs, ...) nutzen diese Items. Das Problem: Wenn ein Spieler ein Item vom Inventar auf ein Slot zieht, enthält der Slot das Item. Das Item wird also zerstört, wenn der Spieler das Fenster wieder schliesst, es muss aber vorhanden bleiben, weil das Haupt-Script mit der Logik (AnimalTrap.cs, Campfire.cs, ...) das Item verwendet (z.B. in AnimalTrap.cs wird ein Item als Köder benutzt), auch wenn das Fenster geschlossen wurde. Das Item soll aber auch vom Haupt-Script verwendet werden, wenn das Fenster geöffnet ist. Also: AnimalTrap.cs existiert immer und liegt auf dem GameObject. WndAnimalTrap.cs existiert nur, wenn das Fenster geöffnet ist. SlotItem.cs ist ein child von WndAnimalTrap.cs und kann mit einem Item (Köder) beladen werden. [AnimalTrap.cs] <--[Item baitItem]-->[WndAnimalTrap.cs]<--[Item baitItem]-->[SlotScript.cs] AnimalTrap.cs und SlotItem.cs müssen aber gleichzeitig auf das Item (baitItem) zugreifen können. AnimalTrap.cs berechnet dauernd die Haltbarkeit des Köders und wie viel TIere gefangen werden, EGAL ob das Fenster geöffnet ist oder nicht. Am einfachsten wäre es, wenn ich beim öffnen des Fenster einfach das Item mit ref übergeben könnte und SlotItem.cs ändert dann direkt das Item in AnimalTrap.cs, aber das geht ja leider nicht (.net v4.0 unterstützt das nicht). Versteht jemand, was ich meine? Ist etwas schwer zu erklären und mir fällt wirklich keine "elegante" Lösung ein. PS: Oder ganz einfach erklärt, SlotScript.cs soll eine variable in einem anderen Script manipulieren, ohne dass es dieses kennt. Erst beim erstellen kann dieses Scipt irgendwie übergeben werden.
×