I’m trying to render a sprite inside the Editor using Graphics.DrawTexture(). I have a simple script with just a single public var pointing to a prefab (GameObject). Now I would like to see a preview of the sprite inside the Editor even if the prefab has not been actually instantiated. To do so I’m using OnDrawGizmos in the following way:
public class PrefabLink : MonoBehaviour
{
public GameObject Prefab;
private void OnDrawGizmos()
{
if (Prefab == null)
return;
var spriteRenderer = Prefab.GetComponent<SpriteRenderer>();
if (spriteRenderer == null)
return;
var spriteRect = new Rect(transform.position, spriteRenderer.bounds.size);
var spriteTexture = spriteRenderer.sprite.texture;
Graphics.DrawTexture(spriteRect, spriteTexture);
}
}
The result is weird. The sprite is actually rendered but I have the following issues:
1 - The sprite is flipped vertically
2 - The position is snapped to integer units. For example if the GameObject’s X coord is 4.7f the Sprite will be renderered at X = 5.0f (same for Y)
I suppose it’s the projection matrix that is causing the above but I’m not certain.
** Update **
Updated the script to support ‘Multiple’ Sprite Mode.
I think I found a solution to the problem. The following modified version of my previous script will correctly draw a textured quad using GL functions:
public class PrefabLink : MonoBehaviour
{
public GameObject Prefab;
private static Material m_Material;
private void OnDrawGizmos()
{
if (m_Material == null)
m_Material = new Material(Shader.Find("Sprites/Default"));
if (Prefab == null)
return;
var spriteRenderer = Prefab.GetComponent<SpriteRenderer>();
if (spriteRenderer == null)
return;
var sprite = spriteRenderer.sprite;
var xyMin = Camera.current.WorldToScreenPoint(transform.position + sprite.bounds.min);
var xyMax = Camera.current.WorldToScreenPoint(transform.position + sprite.bounds.max);
var texW = sprite.texture.width;
var texH = sprite.texture.height;
var uvMin = new Vector2(sprite.rect.min.x / texW, sprite.rect.min.y / texH);
var uvMax = new Vector2(sprite.rect.max.x / texW, sprite.rect.max.y / texH);
var invU = spriteRenderer.flipX;
var invV = spriteRenderer.flipY;
GL.PushMatrix();
GL.LoadPixelMatrix();
m_Material.mainTexture = sprite.texture;
m_Material.SetPass(0);
GL.Begin(GL.QUADS);
GL.MultiTexCoord(0, new Vector3(invU ? uvMax.x : uvMin.x, invV ? uvMax.y : uvMin.y, 0));
GL.Vertex3(xyMin.x, xyMin.y, 0);
GL.MultiTexCoord(0, new Vector3(invU ? uvMax.x : uvMin.x, invV ? uvMin.y : uvMax.y, 0));
GL.Vertex3(xyMin.x, xyMax.y, 0);
GL.MultiTexCoord(0, new Vector3(invU ? uvMin.x : uvMax.x, invV ? uvMin.y : uvMax.y, 0));
GL.Vertex3(xyMax.x, xyMax.y, 0);
GL.MultiTexCoord(0, new Vector3(invU ? uvMin.x : uvMax.x, invV ? uvMax.y : uvMin.y, 0));
GL.Vertex3(xyMax.x, xyMin.y, 0);
GL.End();
GL.PopMatrix();
}
}
Please don’t pointlessly necro a thread, it’s against the Unity Community Code of Conduct . You can just as easily press the Like button on their post instead of Replying.