该功能说明:当ngui使用的是Constrained/ConstrainedOnMobiles时,其中的组件在窗口大小发生变化时,组件本身的绘制大小也会按照比例发生变化。在此时如果因为需求要求,需要其中一个组件不会受其影响(即)绘制大小不变,就需要本文所说的功能。
代码环境:
unity:version5.3.4.f1
ngui:NGUI Next-Gen UI 3.9.4b (Oct 07, 2015)
IDE:Microsoft visual studio Community 2015
UIRoot中相关代码和部分简要说明:
public enum Scaling
{
Flexible, //组件尽量以原大小绘制
Constrained, //窗口大小发生变化时,组件本身的绘制大小也会按照比例发生变化
ConstrainedOnMobiles, //用在移动端,功能类似Constrained
}
UIRoot本身scale的获得,请注意,它是受activeHeight直接影响的
/// <summary>
/// Immediately update the root's scale. Call this function after changing the min/max/manual height values.
/// </summary>
public void UpdateScale (bool updateAnchors = true)
{
if (mTrans != null)
{
float calcActiveHeight = activeHeight;
if (calcActiveHeight > 0f)
{
float size = 2f / calcActiveHeight; //顺便说下,这个数值就是uiroot的scale为什么总是一个很小很小的值的原因。
Vector3 ls = mTrans.localScale;
if (!(Mathf.Abs(ls.x - size) <= float.Epsilon) ||
!(Mathf.Abs(ls.y - size) <= float.Epsilon) ||
!(Mathf.Abs(ls.z - size) <= float.Epsilon))
{
mTrans.localScale = new Vector3(size, size, size);
if (updateAnchors) BroadcastMessage("UpdateAnchors");
}
}
}
}
功能实现:
注意到上述UIRoot的scale获得方式,而普通的组件是它的子节点,其在UIRoot的scale发生变化时,如果想保持本身的绘制大小不变,就是要设法抵消掉UIRoot本身的scale变化大小。
int width = Screen.width;
int height = Screen.height;
UIRoot uiRoot = uiRect.root; //uiRect需要固定大小的组件。顺便说下UIRect其实是ngui中大部分可显示组件的基类。
float scale = 1.0f * (float)uiRoot.activeHeight / (float)height;
if (!(Mathf.Equals(uiRect.cachedTransform.localScale.x, scale) && Mathf.Equals(uiRect.cachedTransform.localScale.y, scale) && Mathf.Equals(uiRect.cachedTransform.localScale.z, scale)))
{
uiRect.cachedTransform.localScale = new Vector3(scale, scale, scale);
}