UGTK / Toolkit / Ui Module / Raw Image Preserve Aspect Completed
Raw Image Preserve Aspect
Summary
Mn_RawImagePreserveAspect is a RawImage subclass that gives it the Preserve Aspect toggle
Unity only ships on Image. It letterboxes the texture inside the RectTransform — without touching
the RectTransform itself — while still honouring uvRect and supporting SetNativeSize().
It is what you need whenever the texture is not an imported sprite: a RenderTexture, a webcam
feed, a downloaded image, a Texture2D built in code. Those all have to go through RawImage, and
RawImage stretches by default.
Content
Modules Dependencies
None on the UGTK side. It only relies on Unity UI (UnityEngine.UI.RawImage).
Setup
Drop the RawImage prefab under a Canvas — a RectTransform already carrying
Mn_RawImagePreserveAspect with Preserve Aspect on:
Or add the component from UI ▸ Raw Image (Preserve Aspect). On an existing RawImage you cannot
just add the component — it is a RawImage — so remove the old one and add this instead, then
re-assign the texture.
How To Use
- Assign Texture as on any RawImage.
- Preserve Aspect (on by default): the texture is fitted inside the rect with letterboxing (black bars top/bottom or left/right, depending on which side is in excess). Turn it off and it stretches to fill, exactly like a stock RawImage.
- UV Rect keeps working: cropping and tiling behave as usual, applied to the fitted quad.
- Set Native Size() resizes the RectTransform to the texture's pixel size, like
Imagedoes.
var raw = GetComponent<Mn_RawImagePreserveAspect>();
raw.texture = myRenderTexture;
raw.preserveAspect = true; // rebuilds the mesh straight away
raw.SetNativeSize(); // RectTransform = texture pixel size
Good to know:
- The RectTransform never moves. The fit happens in the generated mesh, so layout groups, anchors and any sibling UI keep working on the full rect. The "empty" band is just not drawn — it is transparent, not black: put a background Image behind it if you want visible bars.
- The raycast target is still the whole rect. Clicks in the letterboxed band are captured by this graphic even though nothing is drawn there. Turn Raycast Target off, or shrink the rect, if the band must be click-through.
SetNativeSize()collapses the anchors (anchorMax = anchorMin) before resizing, exactly likeImage.SetNativeSizedoes: a stretched RawImage stops being stretched after calling it.- A RenderTexture that changes size re-fits by itself at the next mesh rebuild, but changing
texturefrom code does not always mark the vertices dirty: callSetVerticesDirty()if you see a stale fit. - With no texture assigned the component draws a plain quad on the whole rect, tinted with
color— the usual RawImage placeholder.
Testing Scene
Open Debug/RawImagePreserveAspectSceneTest.unity: the same texture is shown in rects of different
proportions, with and without Preserve Aspect, so the letterboxing is immediately visible.
Technical Info
| Path | Content |
|---|---|
Scripts/Runtime/Mn_RawImagePreserveAspect.cs |
The component: OnPopulateMesh override that builds the fitted quad, GetDrawingDimensions (min-fit letterbox), SetNativeSize override |
Prefabs/RawImage.prefab |
RawImage with the component already attached |
Debug/RawImagePreserveAspectSceneTest.unity |
Test scene |
API: preserveAspect (bool property, rebuilds the mesh on change), SetNativeSize(), plus
everything inherited from RawImage (texture, uvRect, color, material, …).
The maths: from the rect ratio and the texture ratio, the wider of the two dimensions is padded by
(excess / 2) on both sides — the same min-fit Image uses, which is why the two components look
identical side by side.
© 2026 Marcello De Bonis. All rights reserved
Depends on 0
- Standalone: no other module required.
Used by 1
Measured from the repository: code references (asmdef) plus prefab and asset GUIDs. Importing this module alone brings in 0 modules in total.
UGTKengine within an engine


