minuschki Posted January 1 Report Share Posted January 1 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); } Quote Link to comment Share on other sites More sharing options...
malzbie Posted January 3 Report Share Posted January 3 Hast du es mal mit .localBounds probiert?https://docs.unity3d.com/ScriptReference/Renderer-localBounds.html Quote Link to comment Share on other sites More sharing options...
minuschki Posted January 3 Author Report Share Posted January 3 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 ) Quote Link to comment Share on other sites More sharing options...
Sascha Posted January 3 Report Share Posted January 3 Klick mal oben links in der Doku auf die Versionsnummer: Da siehst du, dass localBounds erst seit Version 2021.2 existiert. Ich rate einfach mal und sage, du bist auf einer früheren Unity-Version? Quote Link to comment Share on other sites More sharing options...
minuschki Posted January 3 Author Report Share Posted January 3 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? Quote Link to comment Share on other sites More sharing options...
minuschki Posted January 4 Author Report Share Posted January 4 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); 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.