Unity插件之NGUI学习(8)—— Table和NGUI尺寸转换为世界坐标系尺寸

依据 Unity插件之NGUI学习(2),创建一个UI Root,在UI Root下创建一个Texture作为背景图,并设置图片,在Wiget下调整大小;然后在UI Root下再创建一个Panel。


在Hierarchy窗体选中Panel,然后选择菜单Component->NGUI->Interaction->Table,查看Inspector窗体,在Panel的属性中添加了UITable。


Columns 表示每行有几个元素

Direction 表示超过每列的元素后加入元素的方向

Sorting 元素排序的方式

Hide Inactive 默认勾选,全部看不到的子节点在排列时被忽略

Padding x,y方向的间隔,这里的值是基于NGUI的


创建一个Level的Prefab,在Hierarchy窗体下,加入多个Level,然后选中Panel,在Inspector中,用鼠标右击UITable,并运行Execute,就能够在预览窗体看到排列好的Table界面了。



由于Panel在Inspector窗体的坐标是能够调整的,可是它的大小也是基于NGUI的,为了能使整个Tabel界面居中放置,我必须计算其大小,然后将调整整个Panel的位置。

这里遇到一个问题,Level是用UISprite创建的,所以获得的高度和宽度也是基于NGUI的,并不是是基于世界坐标系的,UITable的Padding也相同是。

问题的关键在于,全部的NGUI控件都是基于UIWidget的,所以从源代码入手,会发现:

public override Vector3[] worldCorners
{
get
{
Vector2 offset = pivotOffset;


float x0 = -offset.x * mWidth;
float y0 = -offset.y * mHeight;
float x1 = x0 + mWidth;
float y1 = y0 + mHeight;


Transform wt = cachedTransform;


mCorners[0] = wt.TransformPoint(x0, y0, 0f);
mCorners[1] = wt.TransformPoint(x0, y1, 0f);
mCorners[2] = wt.TransformPoint(x1, y1, 0f);
mCorners[3] = wt.TransformPoint(x1, y0, 0f);


return mCorners;
}
}

其坐标和尺寸都是通过Transform.TransformPoint()方法转换的——变换位置从自身坐标到世界坐标。好了,以下就是我创建的TableTest 脚本,是挂在Panel上面的。

using UnityEngine;
using System.Collections;


public class TableTest : MonoBehaviour {

private UISprite level;
private UITable table;
private float tableWidth, tableHeight;


// Use this for initialization
void Start () {
table = GetComponent<UITable>();
level = GetComponentInChildren<UISprite>();
int columns = table.columns;

// 计算Table的row
int count = transform.childCount;
int rows = count % columns == 0 ? count / columns : count / columns + 1;

// 计算Table的宽度和高度,基于NGUI也就是自身原本的尺寸
tableWidth = columns * (level.width + 2 * table.padding.x);
tableHeight = rows * (level.height + 2 * table.padding.y);
Debug.Log("level width=" + level.width + ", height=" + level.height);
Debug.Log("table width=" + tableWidth + ", height=" + tableHeight);

// 将Table的宽度高度转换到世界坐标系的偏移
Vector3 delta = transform.TransformPoint(new Vector3(-tableWidth / 2, tableHeight / 2, 0));
transform.Translate(delta);
}

// Update is called once per frame
void Update () {

}

}


这样再执行游戏的话,就能看到整个Table会居中在整个预览窗体。


posted @ 2015-01-20 16:04  mengfanrong  阅读(736)  评论(0编辑  收藏  举报