Jump to content
Unity Insider Forum

minuschki

Members
  • Posts

    116
  • Joined

  • Last visited

  • Days Won

    3

minuschki last won the day on December 4 2022

minuschki had the most liked content!

1 Follower

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

minuschki's Achievements

Advanced Member

Advanced Member (3/3)

6

Reputation

  1. Danke für deine ausführliche und informative Antwort! Ich verstehe nun die Problematik. Komischerweise sind eine ganze Reihe von solchen Minigolf Tutorials in Youtube zu finden, aber nirgends wird auf das Problem hingewiesen. Ich könnte mir aber folgende Lösungsansätze vorstellen: Variante ohne Rigidbody • Könnte man nicht mit einem abwärtsgerichteten Ray laufend den Untergrund abtasten und die Kugel so im Radiusabstand über den Boden gleiten lassen. So nach dem Prinzip Hooverboard). Aus meiner Sicht wäre es so möglich, über Mulden und Hügel zu rollen und die Kugel könnte auch in ein Loch fallen. Allerdings müssten bei dieser Variante noch Berechnungen gemacht werden, welche die Kugel je nach Steigung abbremst, beschleunigt oder ablenkt. Eventuell wäre es dann sinnvoll, dazu den Contactpoint und den dazugehörenden Normal zu Hilfe zu nehmen. Keine Ahnung, ob das so machbar wäre. Variante mit Rigidbody • Ich habe noch ein Tool (Realtime CSG), welches boolsche Operationen erlaubt. So könnte ich eine grosse Plattform erzeugen und diese dann mit Vertiefungen, Erhebungen oder Löchern und Randbegrenzungen versehen. Allerdings hätte diese Variante nicht die Möglichkeit mit Einzelmodulen eine ganze Bahn runtime zu generieren. Welche Variante würdest du empfehlen?
  2. Hallo zusammen Ich möchte gerne ein Minigolf in 3D kreieren. Dafür nehme ich mehrere im Grundriss quadratische Elemente (z.B. standard Cubes) und ordne diese genau zu einer Bahn an. Nun gebe ich der Kugel mittels rb.AddForce(power * transform.forward, ForceMode.Impulse); einen Antrieb und sie rollt zügig über die Bahn. Obwohl die Elemente haargenau den gleichen Y-Wert haben, hüpft die Kugel nach einer Weile vom Boden weg. Bei grösserer Geschwindigkeit schiesst sie dann plötzlich wie eine Kanonenkugel in die Luft. Wie kann das sein? Der Boden ist doch topfeben. Wenn ich die Kugel anstatt über 20 aneinandergereihte Cuben, über einen einzelnen sehr langen Cube (Balken) rollen lasse, rollt diese perfekt auf dem Balken und hebt keinen Millimeter vom Boden ab. Wenn ich anstatt den Standard Cubes meine richtigen Minigolfelemente benutzte (diese haben dann einen Meshcollider) passiert eigentlich der gleiche Effekt und manchmal ist es sogar so, dass die Kugel beim Übertritt ins nächste Element komplett gestoppt wird, als wäre sie gegen eine durchsichtige Wand geprallt. Wie kann ich also erreichen, dass die Kugel sauber über die Fläche rollt und nicht plötzlich abhebt?
  3. Ich wollte nur noch mitteilen, dass es so geklappt hat! Die Startkoordinaten und die jeweiligen Bilddimensionen werden bei unterschiedlichen Monitorauflösungen neu berechnet! // Screensize der orthogonalen Kamera ist 6 // Kamera Units vertikal: Camerasize (6) * 2 = 12 Units werden von der Kamera vertikal erfasst // Kamera Units horizontal: 12 Units / 9 * 16 = 21.3333 Units werden von der Kamera horizontal erfasst float propX = 12f / 9 * 16 / sprite.GetComponent<SpriteRenderer> ().bounds.size.x; // Verhältnis von Screenbreite und Bildbreite float propY = 12f / sprite.GetComponent<SpriteRenderer> ().bounds.size.y; // Verhältnis von Screenhöhe und Bildhöhe int width = (int)(Screen.width / propX); int height = (int)(Screen.height / propY); int startX = (int)(Screen.width / 2 - width / 2); int startY = (int)(Screen.height / 2 - height / 2);
  4. Hallo Sascha Ja, das ist richtig! Ich habe eine frühere Version, kann aber nicht Updaten, da mein Betriebssystem eine Version über 2019 nicht unterstützt. Dann hätten wir mal den Weg über "localBounds" ausgeschlossen. Da ich eine orthogonale Kamera (Size 6) verwende und das Ganze ein 2D Projekt ist, sollte es doch dennoch möglich sein, die startX, startY, width und height Pixelwerte eines zentrierten 2D Sprites (Scale 0.2 für x und y) in unterschiedlichen Monitorauflösungen berechnen zu können! Mein Ansatz ist, die Units-Masse der Kamera ins Verhältnis zu den Sprite-Units zu setzen: Kamera Units vertikal: Camerasize (6) * 2 = 12 Units werden von der Kamera vertikal erfasst Kamera Units horizontal: 12 Units / 9 * 16 = 21.3333 Units werden von der Kamera horizontal erfasst Sprite Units vertikal: sprite.GetComponent<SpriteRenderer> ().bounds.size.y // 5.28 Units Sprite Units horizontal: sprite.GetComponent<SpriteRenderer> ().bounds.size.x // 9.366 Units Nun könnte man doch irgendwie aus diesem Startverhältnis jeweils die neuen Dimensionen und Eckpunkte des Sprites berechnen und so zu den korrekten Pixelwerten kommen oder sehe ich das komplett falsch?
  5. Hallo malzbie Danke erstmal für deine Antwort! Wenn ich das Script von deinem Link kopiere, erhalte ich direkt diese Fehlermeldung: Assets/DrawRendererBounds.cs(12,18): error CS1061: Type `UnityEngine.Renderer' does not contain a definition for `localBounds' and no extension method `localBounds' of type `UnityEngine.Renderer' could be found. Are you missing an assembly reference? Debug.Log (sprite.GetComponent<SpriteRenderer> ().bounds); // funktioniert, der Wert bleibt aber bei jeder Screengrösse gleich Debug.Log (sprite.GetComponent<SpriteRenderer> ().sprite.bounds); // funktioniert, der Wert bleibt aber bei jeder Screengrösse gleich Debug.Log (sprite.GetComponent<SpriteRenderer> ().localBounds); // funktioniert nicht, die Fehlermeldung wird ausgegeben Debug.Log (sprite.GetComponent<SpriteRenderer> ().sprite.localBounds); // funktioniert nicht, die Fehlermeldung wird ausgegeben Ist mir nicht klar, wieso das Originalskript nicht funktioniert. Ich kann es nicht einmal auf das Sprite ziehen. Nun bin ich aber noch auf diesen Hinweis gestossen: renderer.bounds returns the axis-aligned bounding box in world space coordinates. mesh.bounds returns the axis-aligned bounding box in local space coordinates. (Note. The new "sprite" type, there is no mesh. For a sprite, for local bounds GetComponent<SpriteRenderer>().sprite.bounds for world bounds, GetComponent<Renderer>().bounds )
  6. Hallo zusammen und ein gutes neues Jahr Ich habe auf dem Screen ein Bild platziert, welches aber kleiner ist als der gesamte Screen. Da die Originalgrösse eine Breite von 2048 Pixel hat, ist der Scale im Inspector auf 0.3 gesetzt. Das Bild zeigt eine Wiese mit einem Bauernhof. Darüber werden nun verschiedene andere Sprites gelegt, wie z.B. Personen, eine Kuh oder ein Schaf. Nun möchte ich gerne von der Situation einen Snapshot machen, aber nicht vom ganzen Screen, sondern nur präzise von der Grösse des Hintergrundbildes. Das Resultat sollte also ein randloses Bild mit Wiese, Gebäude und den positionierten Personen und Tieren zeigen. Nun zum Problem: Wie kann ich die genauen Parameter für startX, startY, width und height bestimmen? Ich habe versucht mit bounds.max.x oder bounds.size.x usw. die genauen Werte zu ermitteln, aber leider funktioniert das nicht so, wie ich es mir vorstelle. Je nachdem, ob ich das Projekt mit "Maximize On Play" oder in der kleinen Ansicht starte, erhalte ich unterschiedliche Resultate. Für Screen.width werden die Werte korrekt angezeigt, bound.size.x wird aber nicht skaliert und hat immer den gleichen Wert. So kann das ja nicht funktionieren. Das Resultat ist mal mit mehr und mal mit weniger Rand, aber nie genau den Ausschnitt, den ich möchte. Offensichtlich sind meine 4 Zeilen, wo die Parameter bestimmt werden, nicht korrekt! Könnt ihr mir da bitte auf die Sprünge helfen, wie man das richtig macht! public IEnumerator SnapShot() { yield return new WaitForEndOfFrame(); var startX = (int)(sprite.GetComponent<SpriteRenderer> ().bounds.max.x * 100); var startY = (int)(sprite.GetComponent<SpriteRenderer> ().bounds.max.y * 100); int width = Screen.width - startX * 2; int height = Screen.height - startY * 2; Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false); tex.ReadPixels(new Rect(startX, startY, width, height), 0, 0); tex.Apply(); Debug.Log("Start X : " + startX + " Start Y : " + startY); Debug.Log("Screen Width : " + Screen.width + " Screen Height : " + Screen.height); Debug.Log("Texture Width : " + width + " Texture Height : " + height); //Save the screenshot to disk byte[] byteArray = tex.EncodeToPNG(); string savePath = Application.persistentDataPath + "/ScreenshotSave.png"; System.IO.File.WriteAllBytes(savePath, byteArray); Debug.Log("Screenshot Path : " + savePath); Destroy(tex); }
  7. Hallo Sascha Zuerst dachte ich: Na du bist mir aber auch ein Spassvogel mit deiner kecken Antwort. Aber dann hat es bei mir langsam gedämmert und ich darf sagen, dass du wieder einmal goldrichtig lagst! Zwar konnte ich ToString("R") nicht innerhalb eines Vector3 benutzen aber als umgewandelter String hat es dann funktioniert: startPos = new List<Vector3>(); startPos.Add (Hip.transform.localPosition); string tt = startPos [0].ToString ("R"); Wahrscheinlich wäre es sogar klüger, gar nicht erst alle Positionen in einer Vector3 Liste zu sammeln und erst dann in einen String umzuwandeln, sondern die zu speichernden Positionen direkt mit transform.localPosition.ToString ("R") umzuwandeln und diese zu einem Sammelstring zusammenzufügen! Danke für deinen Denkanstoss!
  8. Und wieder ein kleines Problemchen. Ich speichere eine transform.localPosition (also Vector3 Daten) als string in eine Textdatei. Nach dem Einlesen eines gespeicherten Vector3 habe ich festgestellt, dass die Werte auf eine Stelle gerundet sind und nicht mehr dem ursprünglichen Wert exakt entsprechen. Der richtige Vector3 hat die folgenden Werte: new Vector3(0.0f, 1.036848f, -0.001028f) Gespeichert und wieder eingelesen werden aber folgenden Werte: new Vector3(0.0f, 1.0f, 0.0f) Debug.Log("Position: " + transform.localPosition); // ergibt (0.0f, 1.0f, 0.0f) Die Werte sind auf eine Stelle gerundet Debug.Log("Position: " + transform.localPosition.toString ("R")); // ergibt (0.0f, 1.036848f, -0.001028f) Diese Werte stimmen genau Wie kann man also die genauen Werte abspeichern, so dass beim erneuten Einlesen alle Kommastellen angezeigt werden? z.B. vec = new Vector3 (0.0f, 1.036848f, -0.001028f)
  9. @ malzbie Ich habe inzwischen die Drehung auf "transfom.localRotation =" umgebaut und das klappt soweit gut. Allerdings ist mir leider gar nicht klar, was genau gemeint ist mit: "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°." Ich hoffe sehr, dass damit ein Offset des Winkelwertes um 180 gemeint ist und nicht das physische Drehen der Objekte um 180°! Nehmen wir einmal an, es geht um ein menschliches Bein. Gesteckt im Stehen ist es bei 0°. Eine flexible Ballerina kann es wahrscheinlich ohne Probleme um 160° nach vorne beugen und vielleicht um -120° nach hinten biegen können. Wie würde man denn nun deine Idee an diesem Beispiel konkret anwenden?
  10. Hallo Jog Danke für deinen Beitrag! So wie ich das sehe, funktioniert der "AktuellerEulerWinkel" genau gleich, wie mein Winkelzähler "www", nämlich, dass der bestehende Wert erhört oder erniedrigt wird. Die Winkelangabe ist daher auch analog zum Inspektorwinkel. Mein Problem ist aber, dass ich irgendeine Rotation vor mir habe, deren Winkel ich zwar optisch im Inspektor ablesen kann, aber eben nicht auf Grund der vorliegenden Rotation einzeln berechnen kann. Marzbie hat mir einige Vorschläge gemacht, um das Problem zu lösen. Ich habe inzwischen die Drehung so umgesetzt, dass sie nicht mehr auf "transform.rotate" basiert, sondern durch "transform.localRotation =" direkt gesetzt wird. Der andere Vorschlag, die Objekte um 180° zu drehen, habe ich noch nicht verstanden!
  11. Ok, dann lasse ich die Finger von Quaternions, die scheinen mir sowieso zu komplex zu sein! Ich verfolge mal deine Vorschläge weiter! Danke!
  12. Hallo malzbie Vielen Dank für deine wertvollen Inputs! Ich denke, du hast mein Problem voll durchschaut und werde natürlich versuchen deine Ratschläge umzusetzen! "Und immer wenn durch Zufall der Wert negativ sein sollte, addierst du einfach 360° drauf." Tatsächlich handelt es sich aber nicht um einen Zufallswert, sondern um eine gespeicherte "transform.localRotation", die dem Objekt wieder als Quternion.Euler zugewiesen wird. Nun fehlt mir aber die Möglichkeit, die einzelnen Winkel auszulesen! P.s.: Ich bin heute Morgen noch auf dieses Script gestossen und habe es ausprobiert! Die Werte für den X Winkel werden korrekt berechnet, aber nur wenn Y und Z beide 0 sind. Ansonsten verschiebt sich der berechnete X Wert leider um ein paar Grad. Scheint eventuell ein Problem von "insrinsic" oder "extrinsic" zu sein. Wüsste aber nicht, wie man die Berechnung umbauen müsste, dass sie immer korrekte Winkel zurückgibt. Würdest du mir von dieser Methode abraten und auf jeden Fall deinen Lösungsvorschlag bevorzugen oder wäre das eventuell auch eine Lösung? Danke für deine Mühe if(Input.GetMouseButton(1)) { // Quaternion q = transform.localRotation; // var xWinkel = Mathf.Atan2(2.0f * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z) * Mathf.Rad2Deg; // var yWinkel = Mathf.Asin(-2.0f * (q.x * q.z - q. w* q.y)) * Mathf.Rad2Deg; // var zWinkel = Mathf.Atan2(2.0f * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z) * Mathf.Rad2Deg; // Debug.Log ("X Winkel = " + xWinkel + " Y Winkel = " + yWinkel + " Z Winkel = " + zWinkel); // This should fit for intrinsic tait-bryan rotation of xyz-order. For other rotation orders, // extrinsic and proper-euler rotations other conversions have to be used. Quaternion q = transform.localRotation; www = Mathf.Atan2(2.0f * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z) * Mathf.Rad2Deg; Debug.Log("Der berechnete X Winkel beträgt: " + www); }
  13. Hallo zusammen Ich brauche mal wieder eure Hilfe, da es mir unmöglich ist, ein Winkelproblem zu lösen! Folgende Problematik (siehe Bild): Ich ändere die Richtung eines Roboterarms mit Hilfe der Pfeiltasten. Die Rotation startet bei 0 und soll auf ein Maximum von 160 und ein Minimum von -120 beschränkt sein. Ich mach dies mittels einer float-Variabel www, welche sozusagen als Winkelzähler fungiert. www wird also durch die Pfeiltasten entweder schrittweise inkrementiert oder dekrementiert und solange der Wert innerhalb der Grenzen ist, wird dann das Teilstück des Roboterarms gedreht. Im anderen Fall setze ich Mathf.Clamp ein, um www in seinen Grenzen zu halten. Das funktioniert soweit alles gut! Der Arm dreht sich und stoppt jeweils bei -120 oder +160. Nun das eigentliche Problem: Angenommen, der Arm wird durch einen Zufallwert in eine neue Position gebracht, dann müsste ich den Winkel auslesen und dementsprechend den Zähler www neu setzen! Leider ist es aber so, dass der angezeigte Winkel im Inspektor und der Wert, den mir "transform.localRotation.eulerAngles.x" zurückgibt, sehr oft nicht identisch sind. Innerhalb -90 und +90 funktioniert "transform.localRotation.eulerAngles.x" eigentlich, aber nicht, wenn diese Werte überschritten werden. Dann werden für zwei unterschiedliche Winkel die gleichen Werte ausgegeben. Meine Recherchen haben ergeben, dass die ganze Problematik mit Quaternions zusammenhängt und dass man eben "transform.localRotation.eulerAngles.x" nicht benutzen soll, um den Rotationswinkel einer Achse zu ermitteln. Leider steht aber auch nirgends geschrieben, wie man es denn richtig machen soll, um den Winkel der x-Achse verlässlich zu erhalten. Ich habe viel rumprobiert und versucht mit Vector3.Angle das Problem zu lösen, habe es aber nicht hingekriegt. Also: Wie muss man vorgehen, um einen unbekannten Winkel der x-Achse exakt zu bestimmen? Besten Dank für eure Bemühungen! using System.Collections; using UnityEngine; public class Drehen : MonoBehaviour { public float speed; public float www; // Winkelzähler public float wmin = -120; public float wmax = 160; void Update () { speed = Input.GetAxis ("Horizontal"); www = www + speed; if (www > wmin && www < wmax) { transform.Rotate (speed, 0, 0); // nur rotieren, wenn die Grenzen eingehalten werden } else { www = Mathf.Clamp (www, wmin, wmax); } if (Input.GetMouseButton (1)) { float zufallwinkel = Random.Range (wmin, wmax); // Zufallswinkel setzen z.B. 150 // mit "transform.localRotation" die Rotation neu setzen und den Winkelzähler auf den neuen Wert setzen www = transform.localRotation.eulerAngles.x; // Das klappt nicht, weil die Variable zufallwinkel und transform.localRotation.eulerAngles.x oft nicht identisch sind } } }
  14. Hallo zusammen Ich habe über Youtube die Adobe-Seite Mixamo entdeckt, wo man kostenlos diverse Charaktere und eine recht grosse Anzahl an Animationen herunterladen und in Unity importieren kann. Das wäre alles wunderbar, wenn die Animationen dann auch fehlerfrei ablaufen würden - tun sie aber nicht! Zum Beispiel ist das linke Bein ungewöhnlich verbogen und macht aussergewöhnliche Bewegungen. Ebenfalls der linke Arm und die Finger der linken Hand verhalten sich komisch und zucken. Soweit ich das beurteilen kann, funktioniert die rechte Körperhälfte korrekt und die Fehler treten nur auf der linken Körperhälfte auf. Anscheinend haben auch andere ähnliche Probleme, wie man z.B. hier sehen kann: Ich habe mehrere Videos durchgesehen, aber keines hat bei mir funktioniert. In der Vorschau von Mixamo sieht alles normal aus. Auch in Blender werden die Animationen "Walking" und "Run" absolut korrekt abgespielt. In Unity ist der Rig des Charakters bereits auf humanoid umgestellt. Grundsätzlich laufen die Animationen, aber eben fehlerhaft. Weiss jemand von euch, warum die Fehler entstehen und wie man genau vorgehen muss, um diese zu beheben? So eine Step-by-step Anleitung wäre natürlich toll!
  15. Hallo zusammen Ich bin auf der Suche nach einer Möglichkeit, wie ich einen Pinsel mit transparentem Hintergrund (linke Bildhälfte: png mit Alpha) auf eine 2D Textur an verschiedene Positionen kopieren kann (rechte Bildhälfte). Also eine einfache Malfunktion. Die Umsetzung mit Ray usw. ist mir klar, so dass ich in der Lage wäre, bei gedrückter Maustaste die gewünschte Pinselposition zu ermitteln. Das Problem ist aber der eigentliche Kopiercode! Dabei muss die 2D Textur tatsächlich neu bemalt werden, also keine Lösung mit spawnen vom Pinsel-Prefab. Leider habe ich keinen Schimmer, wie man das bewerkstelligen könnte! Pseudocode: 1. Solange die Maustaste gedrückt ist 2. Kopiere den Pinsel an die Mausposition auf die 2D Textur 3. Wenn man die Transparenz (also Deckungsgrad des Pinsels) einstellen könnte, wäre natürlich super. Z.B.: Kopiere den Pinsel mit 20% Deckung. Kann mir bitte jemand zwei, drei Codezeilen liefern, wie der Kopiercode aussehen müsste! Besten Dank für eure Hilfe!
×
×
  • Create New...