Impossible to draw a texture in sceneView with GUI functions

Hello there!
I can’t seem to find a way to draw a texture in the sceneView without any constraint in return.

At first, I tried GUI.DrawTexture, however, the texture gets clipped to the top right half of the SceneView (Exact same issue as described here strange results with GUI.DrawTexture() in the editor scene)

Then, I tried Gizmos.DrawGUITexture, which snaps my textures to units of 1. And of course, Gizmos.DrawGUITexture does not take in account Gizmos.matrix.

So I am stuck, cause my drawing texture needs are quite precise, and would require something like a 0.44 x 0.25 size in world coordinates image displayed in the scene view, but I couldn’t find any solution for that.

The only solution I came up with is following Xarbrough’s idea on Draw texture in editor with size less than a single unit, to instantiate planes that are hidden and not saved.

But this somehow feels wrong. It would be nice to have some updated method to do so.

Thank you for reading.

Ive had a bit of luck with this editor script

Cannot get it to expose the target image though.

Maybe tomorrow. Or you can seal the deal. Good luck!

using UnityEditor;
using UnityEditor.Overlays;
using UnityEngine;
using UnityEngine.UIElements;

[Overlay(typeof(SceneView), "Target Image Overlay")]
public class TargetImageOverlay : Overlay
{
    public Texture2D targetImage;
    public float xOffset = 0f;
    public float yOffset = 0f;

    public override VisualElement CreatePanelContent()
    {
        var root = new VisualElement();
        var image = new Image { image = targetImage };

        // Set the position of the image
        image.style.left = xOffset;
        image.style.top = yOffset;

        root.Add(image);
        return root;
    }

    [MenuItem("Window/Target Image Overlay")]
    public static void ShowTargetImageOverlay()
    {
        var overlay = new TargetImageOverlay();
        SceneView.AddOverlayToActiveView(overlay);
    }

    // Example usage:
    // In the Unity editor, go to Window > Target Image Overlay to display the overlay.
    // You can then adjust the targetImage, xOffset, and yOffset variables in the Inspector to customize the overlay.
}

Have you tried perhaps Handles.Begin/EndGUI? Unity - Scripting API: Handles.BeginGUI

Not a computer with Unity to test this myself, but this is where I’d start.

to cbiluk:
I need to display a lot of images, here is how looks my current result (I am working on a timeline for a cinematic system so my artists can edit the cinematic easily):


It doesn’t seem really feasible to use an instance of EditorWindow for all of them right? Especially because the artists are about to add all the emotes to the characters which will add a lot of previews

to spiney199:
I tried Handles.BeginGUI / EndGUI, and I also tried GUI.BeginClip/EndClip, in my case, when I tried, they both made all the pictures disappear. Maybe I used them wrong though.

In the end, I just instantiated actual gameobjects in the scene, added a sprite renderer to them, and set their hideflags to HideAndDontSave.
I also implemented a pooling system to make the system efficient and allow for refreshing all images multiple times per second.

If people want to see the functions I use for my images:

private void HandleClearAllImages()
{
    if (_data._sceneImages == null)
        _data._sceneImages = new List<SpriteRenderer>();
    for (int i = 0; i < _data._sceneImages.Count; i++)
    {
        if (_data._sceneImages[i] == null) { continue; }
        _data._pooledSceneImages.Add(_data._sceneImages[i]);
        _data._pooledSceneImages[i].gameObject.SetActive(false);
    }
    for (int i = _data._pooledSceneImages.Count - 1; i >= 0; i--)
    {
        if (_data._pooledSceneImages[i] == null)
            _data._pooledSceneImages.RemoveAt(i);
    }
    _data._sceneImages.Clear();
}
private void CreateImage(Vector2 position, Vector2 size, Sprite sprite, Color color, int? sortingOrder = null)
{
    SpriteRenderer sr;
    GameObject gob;
    if (_data._pooledSceneImages.Count > 0)
    {
        sr = _data._pooledSceneImages.Pop();
        gob = sr.gameObject;
        gob.SetActive(true);
    }
    else
    {
        gob = new GameObject("img");
        sr = gob.AddComponent<SpriteRenderer>();
    }
    
    sr.sprite = sprite;
    sr.color = color;
    sr.sortingOrder = sortingOrder != null ? sortingOrder.Value : _imgSortingOrder++;

    gob.hideFlags = HideFlags.HideAndDontSave;

    gob.transform.localScale = Vector3.one * size;
    gob.transform.position = position;

    gob.transform.position += sr.bounds.size.y * Vector3.up * 0.5f;

    _data._sceneImages.Add(sr);
    EditorUtility.SetDirty(_data);
}
1 Like

Why do you want to display such a timeline editor inside the sceneview? The sceneview is meant to view the “scene”. So you just augment your timeline into the sceneview? This can work but would be quite unusual. Things like such a custom timeline is usually done in a separate EditorWindow.

Just for reference you may want to have a look at my UVViewer I made years ago. It does a lot if IMGUI drawing both in the editor window as well as in the sceneview as I overlay the triangles of the selected object in the sceneview.

It’s a single script file, but when you import and use it, it will create two shaders and materials in the resources folder used for drawing (Lines_Colored_Blended and Lines_Colored_Blended_Depth).

I don’t specifically do textured drawing inside the sceneview. If you need textured quads or triangles you have to specify texture coordinates for each vertex. I quickly searched through the Unity reference repository and found some Unity internal code that actually draws textured quads “manually”.

Though when messing around with immediate mode drawing you have to be aware of the current GL state. You always have a viewport, modelview matrix.

I agree, the “intended” way is to do it inside of a separate editor window.
However, I’ve been implementing utility editor buttons inside of the scene view on this new project, more as an excuse to explore different ways to do things, and I must say, this is the first time my editor tools give such a clean and neat feeling.
It also makes it easy for any member of my team that is not a “technical” user to jump around and use the tools.
In the end, my timeline works fine as it is right now, but thanks for sharing your code, maybe next time I won’t bother with printing images on the SceneView