Jump to content
Unity Insider Forum

Snapshot von einem Sprite in einem 2D Projekt erstellen


minuschki

Recommended Posts

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);
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 )

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

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);

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...