using UnityEngine;
[ExecuteInEditMode]
[AddComponentMenu("NGUI/MyExtensions/Aspect Stretch")]
public class UIAspectStretch : MonoBehaviour
{
public enum Style
{
None,
BasedOnWidth,
BasedOnHeight,
BasedOnLongest,
BasedOnShortest
}
public Camera uiCamera = null;
public UIWidget widgetContainer = null;
public UIPanel panelContainer = null;
public Style style = Style.None;
public Vector2 relativeSize = Vector2.one;
Transform mTrans;
UIRoot mRoot;
Animation mAnim;
Vector2 mOriginalWidgetSize = Vector2.one;
void Awake () { mAnim = animation; }
void Start ()
{
if (uiCamera == null) uiCamera = NGUITools.FindCameraForLayer(gameObject.layer);
mRoot = NGUITools.FindInParents<UIRoot>(gameObject);
}
void Update ()
{
if (mAnim != null && mAnim.isPlaying) return;
if (style != Style.None)
{
// We need to get the widget we'll be scaling
UIWidget widget = GetComponentInChildren<UIWidget>();
if(widget)
{
if (mTrans == null) mTrans = transform;
// Get the widget's original size, from which we can calculate its desired aspect ratio.
// This is expensive and messy, but I don't see any other way :(
if(mOriginalWidgetSize == Vector2.one)
{
widget.MakePixelPerfect();
mOriginalWidgetSize = widget.cachedTransform.localScale;
}
// Get the rect that represents the area we want to stretch relative to
if (panelContainer != null)
{
if (panelContainer.clipping == UIDrawCall.Clipping.None)
{
// Panel has no clipping -- just use the screen's dimensions
rect.xMin = -Screen.width * 0.5f;
rect.yMin = -Screen.height * 0.5f;
rect.xMax = -rect.xMin;
rect.yMax = -rect.yMin;
}
else
{
// Panel has clipping -- use it as the rect
Vector4 pos = panelContainer.clipRange;
rect.x = pos.x - (pos.z * 0.5f);
rect.y = pos.y - (pos.w * 0.5f);
rect.width = pos.z;
rect.height = pos.w;
}
}
else if (widgetContainer != null)
{
// Widget is used -- use its bounds as the container's bounds
Transform t = widgetContainer.cachedTransform;
Vector3 ls = t.localScale;
Vector3 lp = t.localPosition;
Vector3 size = widgetContainer.relativeSize;
Vector3 offset = widgetContainer.pivotOffset;
offset.y -= 1f;
offset.x *= (widgetContainer.relativeSize.x * ls.x);
offset.y *= (widgetContainer.relativeSize.y * ls.y);
rect.x = lp.x + offset.x;
rect.y = lp.y + offset.y;
rect.width = size.x * ls.x;
rect.height = size.y * ls.y;
}
else if (uiCamera != null)
{
rect = uiCamera.pixelRect;
}
else return;
float rectWidth = rect.width;
float rectHeight = rect.height;
if (mRoot != null && !mRoot.automatic && rectHeight > 1f)
{
float scale = mRoot.manualHeight / rectHeight;
rectWidth *= scale;
rectHeight *= scale;
}
Vector3 localScale = mTrans.localScale;
// Apply the stretch style. This is what differentiates UIAspectStretch from UIStretch
Style myStyle = style;
if(myStyle == Style.BasedOnLongest)
{
myStyle = (rectWidth > rectHeight) ? Style.BasedOnWidth : Style.BasedOnHeight;
}
else if (myStyle == Style.BasedOnShortest)
{
myStyle = (rectWidth < rectHeight) ? Style.BasedOnWidth : Style.BasedOnHeight;
}
if(myStyle == Style.BasedOnWidth)
{
localScale.x = relativeSize.x * rectWidth;
localScale.y = localScale.x * (mOriginalWidgetSize.y / mOriginalWidgetSize.x);
}
else if (myStyle == Style.BasedOnHeight)
{
localScale.y = relativeSize.y * rectHeight;
localScale.x = localScale.y * (mOriginalWidgetSize.x / mOriginalWidgetSize.y);
}
if (mTrans.localScale != localScale) mTrans.localScale = localScale;
}
}
}
}