unity開發遇到的幾個坑(UGUI等)__遊戲開發及技術

來源:互聯網
上載者:User

最近開始研究unity,準備將之前自己業餘時間做的一款遊戲(金庸群俠傳X)發行移動端版本(我不是遊戲公司從業人員,業餘時間自己做著玩,大神輕噴)。由於之前使用silverlight(C#)做的,所以移植unity有天然的語言優勢。

看了一下unity的更新公告,4.6出的UGUI我比較喜歡,因為之前也用過NGUI,總感覺不是很順暢。那麼,即使有坑,我們也來趟趟吧。


到現在陸陸續續大概已經趟了一個月的坑了,總的感覺是,對於unity還是比較滿意的:非常簡單容易上手,功能還算齊全——現在DEMO版本已經能夠在android、ios上較好的運行。上兩張截圖吧






現在總結一下我在開發中碰到的幾個“坑”——當然,話說在前頭,因為我也是剛開始學習unity,目前我自己認為的坑也可能是我自己的理解不夠,如果大家有更好的解決方案,歡迎指正。樓主寫這篇部落格的時候是2015年1月13日,使用的是當前最新的unity 4.6f1版本。


1、scroll rect的各種問題

(2015年02月9日:這個是我自己搞錯了,unity有提供方法,只是我之前用錯了,請移步這篇博文,這一條下面寫的大家就當看個笑話吧 :D)

很多介面需要用到滾屏,unity提供scroll rect控制項。具體的組織方式為:

每個ScrollRect對應一個scrollcontent,ScrollContent定義內容的排版組織方式,如Grid Layout Group或者Vertical Layout Group。(這裡比較像silverlight中的StackPanel和GridPanel)


我使用以後發現一個最大的問題是,scroll content無法根據其包含的內容自動調整。也就是說,scroll content的寬和高需要手動指定,如果其中內容超出了它的範圍,那麼超出的內容將無法滾屏過去。

這一點實在是把我噁心到爆了,於是出現了諸如以下的代碼


        if (Mode == SelectMenuMode.Vertical)        {            selectContent.GetComponent<VerticalLayoutGroup>().enabled = true;            selectContent.GetComponent<GridLayoutGroup>().enabled = false;            float spacing = selectContent.GetComponent<VerticalLayoutGroup>().spacing;            //by cg:            //unity每次需要手動設定scroll content的大小            float height = spacing;            foreach (Transform s in selectContent)            {                height += s.GetComponent<RectTransform>().rect.height - spacing;            }            float width = selectContent.GetComponent<RectTransform>().rect.width;            selectContent.GetComponent<RectTransform>().sizeDelta = new Vector2(width, height);                    }        else if (Mode == SelectMenuMode.Grid)        {            selectContent.GetComponent<VerticalLayoutGroup>().enabled = false;            selectContent.GetComponent<GridLayoutGroup>().enabled = true;            float cellX = selectContent.GetComponent<GridLayoutGroup>().cellSize.x;            float cellY = selectContent.GetComponent<GridLayoutGroup>().cellSize.y;            float spacingX = selectContent.GetComponent<GridLayoutGroup>().spacing.x;            float spacingY = selectContent.GetComponent<GridLayoutGroup>().spacing.y;            float width = selectContent.GetComponent<RectTransform>().rect.width;            float height = Mathf.CeilToInt(selectContent.childCount / (width / (cellX + spacingX))) * (cellY + spacingY);            selectContent.GetComponent<RectTransform>().sizeDelta = new Vector2(width, height);        }

每次需要手動去設定scroll Content的RectTranform的sizeDelta屬性。這樣代碼很醜陋且極其不靈活。如果對於內容的寬高和排列可以預期,那還好。假如內容是一個文本,那豈不是還要算字型所佔寬高、行間距等等…… 


其次的一個問題是:scroll content的position設定貌似是有BUG。


為了實現大地圖滑動滾屏的效果,我將大地圖放到一個scroll content中,然後可以由玩家手指滑動來進行拖拽,這個unity實現都沒有問題。問題是,我需要由代碼實現“滾屏”到某個點,則問題來了——


我手動在unity editor的運行時態設定的scoll content的x,y都是OK的,放到代碼裡去設定transform.localPosition,就完全錯位了。

最後經過反覆嘗試,代碼寫成了這樣……


<span style="white-space:pre"></span>//大地圖卷屏        if(location.name.Equals(RuntimeData.Instance.GetLocation(RuntimeData.Instance.CurrentBigMap)))        {            float x = -location.X + 640; //減去半個螢幕寬度,置中            float y = -location.Y - 320; //減去半個螢幕高度,置中            if (x < -1140) x = -1140; //邊界限制            if (y > 640) y = 640;            if (x > 0) x = 0;            if (y < 0) y = 0;            //by cg: 這裡對齊的邏輯有點奇怪,應該是unity的BUG,沒處理好對齊錨點。先手動修正。            BigMap.transform.localPosition = new Vector3(-570f + x, 320f + y, 0);        }

原因應該是我將scroll content的Anchor Pivot設定成了(0,1),但unity設定localPosition卻沒有寫參考這個錨點的邏輯,需要手動修正。


還有比較大的一個問題,ScrollRect所在的GameObject的Image組件,alpha設定有個BUG

按道理來說,這個Image只是scrollRect的一個背景,不影響其內容。但在把alpha設定到特別小的時候,不管是在editor上還是在運行環境中,scroll content都將顯示不出來。我試了大概是設到4-8以下就會完蛋。。所以我們需要獲得一個背景透明的scroll content,還不能把背景設定得太過於透明了……


2、LINQ不能在IOS上使用

在PC、EDITOR、MAC、ANDROID都沒有問題的代碼,放到IOS真機(IPHONE、IPAD)上出問題。原因搜了一下大概意思應該是蘋果不允許出現動態代碼。

這個是unity一直的問題了,貌似有辦法通過第三方的LINQ實現來保證。總之我是放棄使用LINQ了。


3、unity新版動畫系統Mecanim使用中碰到的問題

我的遊戲中人物分幾種動畫,如 站立、移動、攻擊。我使用Mecanim的狀態機器來實現,動畫之間使用SetTrigger來實現切換。

我發現一個動畫在切換後如果沒有播放完畢,再調用SetTrigger的話,有時就會出現動畫狀態錯亂。我的狀態機是這樣的:


所以我代碼裡現在是每次需要等待一段時間後,再進行切換。。


4、sprite editor中的BUG

在sprite editor中通過滑鼠調整錨點為custom,第一次儲存(這時候unity已經自動將類型切換為custom了)會失敗。需要儲存兩次——但是第二次必須又和第一次不是同一個錨點,否則儲存按鈕點不下去。

或者先手動將錨點類型改為custom,然後再儲存才可以。



好了,吐槽了這麼多問題,總之unity新版本我還是很支援的。畢竟原生態的GUI系統還是比NGUI等硬往上“套”的UI系統要好很多。對於unity3d使用C#程式設計語言也是更加好頂贊。我不是一個喜歡討論哪個程式設計語言好的人,就我來說,我至少使用過10多種語言編寫過代碼,目前來說感覺比較酸爽的還是C#。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.