替代NGUI UIWidget Anchor

NGUI中UIWidget提供了錨點(diǎn)Anchor選項(xiàng)谁鳍,可以方便地設(shè)置一個(gè)Widget相對(duì)于另一個(gè)Widget的位置和大小筹裕。

我用的Unity版本:3.5.6知押;NGUI版本:3.5.9
今天做項(xiàng)目時(shí)遇到一個(gè)問(wèn)題:在SceneA和SceneB中都有UIRoot淤刃,由于某些原因砸逊,我必須以LoadLevelAdditiveAsync的方式加載SceneB,并在進(jìn)入SceneB后銷毀SceneA赤屋。我們知道在一個(gè)場(chǎng)景下最多只能存在一個(gè)UIRoot立镶,但從SceneA跳轉(zhuǎn)到SceneB后,場(chǎng)景中同時(shí)存在了兩個(gè)UIRoot类早,這導(dǎo)致某些使用了Anchor的UI的位置和大小不正確(實(shí)測(cè)Unity Editor中不會(huì)出問(wèn)題媚媒,但在手機(jī)上基本都會(huì)出問(wèn)題)。

此時(shí)有兩種解決辦法:
1.在SceneA銷毀后再呈現(xiàn)SceneB涩僻,也就是不要用Additive的方式加載缭召,但由于我的項(xiàng)目中兩個(gè)Scene的耦合太高了(接的前人的盤(pán))栈顷,這么做會(huì)非常費(fèi)時(shí),老板一直在催版本嵌巷,沒(méi)時(shí)間重構(gòu)萄凤。
2.自己實(shí)現(xiàn)Anchor功能。

代碼很簡(jiǎn)單搪哪,大致思路如下:1.根據(jù)Target的位置和大小計(jì)算出Target的左右上下四個(gè)點(diǎn)坐標(biāo)(實(shí)際上只需要用到左tLeftBoardPos和下tBottomBoardPos)靡努;2.根據(jù)輸入的左右上下的偏移量,計(jì)算出當(dāng)前Widget的左右X坐標(biāo)(mLeftBoardX, mRightBoardX)和上下Y坐標(biāo)(mTopBoardY, mBottomBoardY)晓折;3.根據(jù)2求得的四個(gè)值計(jì)算當(dāng)前Widget的位置和大小惑朦。
需要注意的是:這里用的始終是世界坐標(biāo),且需要考慮UIRoot本身的縮放系數(shù)scaleRatio漓概。
==注:暫時(shí)沒(méi)有考慮Center的情況漾月,有需要了再加上。==
下面是具體實(shí)現(xiàn):
SimpleAnchor.cs

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(UIWidget))]
public class SimpleAnchor : MonoBehaviour
{
    public enum HorizPivot
    {
        Left,
        Right,
        Center
    }

    public enum VertPivot
    {
        Top,
        Bottom,
        Center
    }

    public Transform Target;
    public int Left;
    public HorizPivot LeftPivot;
    public int Right;
    public HorizPivot RightPivot;
    public int Bottom;
    public VertPivot BottomPivot;
    public int Top;
    public VertPivot TopPivot;


    void OnEnable()
    {
        if(!Target)return;
        UIWidget targetWidget = Target.GetComponent<UIWidget>();
        UIPanel targetPanel = Target.GetComponent<UIPanel>();
        if(!targetPanel && !targetWidget) return;
        if (targetWidget)
        {
            SetPosAndSize(targetWidget.transform.position, targetWidget.width, targetWidget.height);

        }
        else
        {
            SetPosAndSize(targetPanel.transform.position, (int)targetPanel.width, (int)targetPanel.height);

        }
    }

    void SetPosAndSize(Vector3 targetPos, int targetWidth, int targetHeight)
    {
        Debug.LogError("Target width: " + targetWidth);
        Debug.LogError("Target height: " + targetHeight);
        float scaleRatio = NGUITools.FindInParents<UIRoot>(transform).transform.localScale.x;
        Vector3 tLeftBoardPos = new Vector3(targetPos.x - scaleRatio * targetWidth / 2, targetPos.y, targetPos.z);
        Vector3 tRightBoardPos = new Vector3(targetPos.x + scaleRatio * targetWidth / 2, targetPos.y, targetPos.z);
        Vector3 tTopBoardPos = new Vector3(targetPos.x, targetPos.y + scaleRatio * targetHeight / 2, targetPos.z);
        Vector3 tBottomBoardPos = new Vector3(targetPos.x, targetPos.y - scaleRatio * targetHeight / 2, targetPos.z);

        float mLeftBoardX = 0;
        if (LeftPivot == HorizPivot.Left)
        {
            mLeftBoardX = tLeftBoardPos.x + scaleRatio * Left;
        }
        else if (LeftPivot == HorizPivot.Right)
        {
            mLeftBoardX = tLeftBoardPos.x + scaleRatio * (targetWidth + Left);
        }

        float mRightBoardX = 0;
        if (RightPivot == HorizPivot.Left)
        {
            mRightBoardX = tLeftBoardPos.x + scaleRatio * Right;
        }
        else if (LeftPivot == HorizPivot.Right)
        {
            mRightBoardX = tLeftBoardPos.x + scaleRatio * (targetWidth + Right);
        }

        float mBottomBoardY = 0;
        if (BottomPivot == VertPivot.Bottom)
        {
            mBottomBoardY = tBottomBoardPos.y + scaleRatio * Bottom;
        }
        else if (BottomPivot == VertPivot.Top)
        {
            mBottomBoardY = tBottomBoardPos.y + scaleRatio * (targetHeight + Bottom);
        }

        float mTopBoardY = 0;
        if (TopPivot == VertPivot.Bottom)
        {
            mTopBoardY = tBottomBoardPos.y + scaleRatio * Top;
        }
        else if (TopPivot == VertPivot.Top)
        {
            mTopBoardY = tBottomBoardPos.y + scaleRatio * (targetHeight + Top);
        }

        transform.position = new Vector3((mLeftBoardX + mRightBoardX) / 2, (mTopBoardY + mBottomBoardY) / 2, targetPos.z);
        UIWidget mWidget = GetComponent<UIWidget>();
        if (mWidget)
        {
            mWidget.width = (int)(Mathf.Abs(mLeftBoardX - mRightBoardX) / scaleRatio);
            mWidget.height = (int)(Mathf.Abs(mTopBoardY - mBottomBoardY) / scaleRatio);
        }
    }

}

使用方法:將SimpleAnchor掛載到需要打錨點(diǎn)的Widget上垛耳,為方便填寫(xiě)數(shù)值栅屏,可以先使用UIWidget自帶的Anchor調(diào)好數(shù)值,再Copy到SimpleAnchor對(duì)應(yīng)項(xiàng)即可堂鲜,最后別忘了把自帶Anchor的Type調(diào)整為None栈雳。

見(jiàn)下面兩個(gè)圖:

自帶Anchor先調(diào)整好大小
Copy到相應(yīng)位置并將自帶Anchor設(shè)置為None

目前還不完善,后續(xù)會(huì)將Center的情況考慮進(jìn)去缔莲,并寫(xiě)個(gè)Editor腳本方便調(diào)整相應(yīng)數(shù)值哥纫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痴奏,隨后出現(xiàn)的幾起案子蛀骇,更是在濱河造成了極大的恐慌,老刑警劉巖读拆,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件擅憔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡檐晕,警方通過(guò)查閱死者的電腦和手機(jī)暑诸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)辟灰,“玉大人个榕,你說(shuō)我怎么就攤上這事〗胬” “怎么了西采?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)继控。 經(jīng)常有香客問(wèn)我械馆,道長(zhǎng)胖眷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任狱杰,我火速辦了婚禮瘦材,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仿畸。我一直安慰自己,他們只是感情好朗和,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布错沽。 她就那樣靜靜地躺著,像睡著了一般眶拉。 火紅的嫁衣襯著肌膚如雪千埃。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天忆植,我揣著相機(jī)與錄音放可,去河邊找鬼。 笑死朝刊,一個(gè)胖子當(dāng)著我的面吹牛耀里,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拾氓,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼冯挎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了咙鞍?” 一聲冷哼從身側(cè)響起房官,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎续滋,沒(méi)想到半個(gè)月后翰守,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疲酌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年蜡峰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片徐勃。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡事示,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出僻肖,到底是詐尸還是另有隱情肖爵,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布臀脏,位于F島的核電站劝堪,受9級(jí)特大地震影響冀自,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秒啦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一熬粗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧余境,春花似錦驻呐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至即舌,卻和暖如春佣盒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背顽聂。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工肥惭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人紊搪。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓蜜葱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親嗦明。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笼沥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容