using UnityEngine;
using System.Collections;
/**
* Makes NGUI object or panel stick to an edge or corner of a "container"
*
* Usage:
* 1. attach to NGUI object or Panel that you want stick somewhere
* 2. attach container (when not set, Screen is used)
*
* NB! Right now it only works with containers that have pivot in top left corner.
* When using default NGUI panel, use UIPanelAutoSetCenter on panel to do that
* automatically.
*/
[ExecuteInEditMode]
public class UIStick : MonoBehaviour {
/// <summary>
/// The container.
/// </summary>
public Transform container;
/// <summary>
/// On which side of the container this element should stick to.
/// </summary>
public UIAnchor.Side side;
/// <summary>
/// when side is Top or Bottom, then should the object be horizontally centered?
/// when side is Left or Right, then should the object be vertically centered?
/// when side is Center, then this is not relevant
/// </summary>
public bool forceCenter = false;
public bool alterSizeInsteadOfPosition;
/// <summary>
/// The padding.
/// </summary>
public RectOffset padding;
void Update ()
{
Rect stickTo
= new Rect
(padding
.left, padding
.top,
Screen.width - padding.horizontal,
Screen.height - padding.vertical);
Vector2 pivotOffset
= new Vector2
(0f, 0f
);
// when no container is given, stick to screen edges
// otherwise stick to container
if(container != null)
{
UIPanel panel = container.GetComponent<UIPanel>();
// UIPanel is used as container
if(panel != null)
{
if(panel.clipping == UIDrawCall.Clipping.None) {
Debug.LogWarning("Container UIPanel has no clipping set. UIStick is not used.");
return;
}
stickTo.x = padding.left;
stickTo.y = padding.top;
stickTo.width = panel.clipRange[2] - padding.horizontal;
stickTo.height = panel.clipRange[3] - padding.vertical;
}
// NGUI object (size=gameobject.localScale) is used as container
else {
UISprite sprite = container.GetComponent<UISprite>();
if(sprite != null) {
pivotOffset = sprite.pivotOffset;
}
stickTo.x = container.localPosition.x + padding.left;
stickTo.y = container.localPosition.y + padding.top;
stickTo.width = container.localScale.x - padding.horizontal;
stickTo.height = container.localScale.y - padding.vertical;
}
}
// UIPanel is that needs to be moved around
UIPanel thisPanel = GetComponent<UIPanel>();
Vector2 newPos;
if(thisPanel != null)
{
if(thisPanel.clipping == UIDrawCall.Clipping.None) {
Debug.LogWarning("Space filling UIPanel has no clipping set. UIStick is not used.");
return;
}
Vector2 thisPanelSize
= new Vector2
(thisPanel
.clipRange[2], thisPanel
.clipRange[3]); newPos = GetContentPosition(stickTo, thisPanelSize, side, pivotOffset);
}
// NGUI object (size=gameobject.localScale) is that needs to be moved
else {
newPos = GetContentPosition(stickTo, transform.localScale, side, pivotOffset);
}
if(!forceCenter) {
// keep horizontal position when side is Top or Bottom
if(side == UIAnchor.Side.Top || side == UIAnchor.Side.Bottom) {
newPos.x = transform.localPosition.x;
}
// keep vertical position when side is Left or Right
if(side == UIAnchor.Side.Left || side == UIAnchor.Side.Right) {
newPos.y = transform.localPosition.y;
}
}
if(!alterSizeInsteadOfPosition)
{
transform
.localPosition = new Vector3
(newPos
.x, newPos
.y, transform
.localPosition.z); } else {
thisPanel
.clipRange = new Vector4
(thisPanel
.clipRange[0],
thisPanel.clipRange[1],
thisPanel.clipRange[2] + (newPos.x - transform.localPosition.x),
thisPanel.clipRange[3] + (newPos.y - transform.localPosition.y));
}
}
private static Vector2 GetContentPosition(Rect stickTo, Vector2 contentSize, UIAnchor.Side side, Vector2 pivotOffset)
{
Vector2 p = Vector2.zero;
// horizontal position
switch(side)
{
case UIAnchor.Side.BottomLeft:
case UIAnchor.Side.Left:
case UIAnchor.Side.TopLeft:
p.x = stickTo.x + (stickTo.width * pivotOffset.x);
break;
case UIAnchor.Side.Bottom:
case UIAnchor.Side.Center:
case UIAnchor.Side.Top:
p.x = 0.5f * (stickTo.x * 2 + stickTo.width - contentSize.x) + (stickTo.width * pivotOffset.x);
break;
case UIAnchor.Side.BottomRight:
case UIAnchor.Side.Right:
case UIAnchor.Side.TopRight:
p.x = (stickTo.x + stickTo.width - contentSize.x) + (stickTo.width * pivotOffset.x);
break;
}
// vertical orientation
switch(side)
{
case UIAnchor.Side.TopLeft:
case UIAnchor.Side.Top:
case UIAnchor.Side.TopRight:
p.y = -stickTo.y + (stickTo.height * pivotOffset.y);
break;
case UIAnchor.Side.Right:
case UIAnchor.Side.Center:
case UIAnchor.Side.Left:
p.y = -0.5f * (stickTo.height - contentSize.y) + (stickTo.height * pivotOffset.y) + stickTo.y;
break;
case UIAnchor.Side.BottomRight:
case UIAnchor.Side.Bottom:
case UIAnchor.Side.BottomLeft:
p.y = -(stickTo.y + stickTo.height - contentSize.y) + (stickTo.height * pivotOffset.y);
break;
}
return p;
}
}