Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
者按 在游戲制作時,UI界面設計是非常重要的工作,不僅僅是考慮排版布局、美術風格,還要考慮到玩家的交互行為。另外,采取哪種實現方案也是需要慎重考慮的,一個好方案讓我們在保質保量的前提下,能快速高效地完成。筆者將為大家介紹業界常用的UI解決方案,并對它們做簡單地分析對比。同時,也歡迎大家留言,分享你在UI設計時所積累的經驗,或是遇到的困難,咱們共同成長進步。
作者:W
筆者自14年畢業參加工作以來,一直使用Unity引擎來開發各種項目,如兒童啟蒙教育類繪本、大型3D網絡海戰、三消、視頻VR以及NBA體育競技等,大部分工作內容是與UI界面相關。使用過的UI系統插件包括Unity原始的GUI、第3方插件NGUI、Unity進階版的UGUI以及第3方的UI編輯器FairyGUI。另外,經網上了解還有EZ GUI、IGUI等第3方插件,以及Unity近推出的高階版UIToolkit。這些偏冷門的或者新出爐的,筆者暫沒在公司項目中使用過。你知道的,公司項目對穩定性有較高的要求,不會一味地追求新技術。讀者不用驚訝,有公司還在使用Unity 4.x或者5.x舊版本的呢,哈哈!
經過前面介紹,這么多種實現方案,我們在實際項目中應該如何做選擇呢?有木有最佳方案?通吃的那種?答案是否定的。每種方案都有其適用性,需要結合項目本身以及開發者自身情況綜合來考量。那在選擇方案時,有木有一些具體的參考點呢?這個是有的,筆者歸結為以下2點:
1)可視化程度:Unity原始的UI系統,需要在運行時才能顯示,這給我們搭建UI界面時帶來很多不便。正因為此,許多像NGUI一樣的高度可視化的插件陸續誕生。搭建UI界面時,只需將對應組件拖入場景即可顯示和調整,達到所見即所得的目的。另外,像是否支持圖文混排、虛擬列表等組件以及對策劃美術是否友好等問題,也都可以歸結為插件的可視化程度高不高的體現。
2)性能:DrawCall,每次CPU準備數據并通知GPU的過程。這個操作是比較好性能的,原則上我們是希望它越少越好的。影響它的因素:一方面表現為UI資源的管理方式,這主要與程序猿技術能力有關,知道啥時候加載,又啥時候卸載,什么類型資源共享,什么類型資源進行九宮格。另一方面表現為與UI系統本身的渲染原理相關,這是UI方案的“硬傷”,關于UI方案的硬傷,對于熟知該UI渲染原理的程序猿來說,他知道該怎么去做,一定程度“規避”產生太多DrawCall。嘻嘻,這很考驗咱程序猿功底咯!如果UI方案本身這方面就做的很好,那豈不是更好,哈哈。
限于篇幅,我不能對這些UI方案深入展開,希望簡短的介紹能講清楚它們各自特點。至于具體怎么使用,我會附上官網或學習地址,那里通常配有技術文檔、教程幫助上手。
2.1 Unity原始GUI
因性能和可視化方面都不足,自打好用的如NGUI等第3方插件問世后,Unity的原始GUI系統,基本不會用于游戲運行模式時的UI設計中;一般只是在編輯器工具擴展時使用。但現如今Unity又推出新的UIElement框架,可用于編輯器工具的擴展,原生GUI系統會越來越失寵,究其最終原因就是性能差且不好用。目前來看,原始GUI在編輯器工具擴展領域的地位應該不太可能迅速被UIElement取代,因為擴展工具時,原始GUI還是可以勝任的,且很多開發者應該已經習慣用它來編寫工具和擴展。其實,程序猿也是有情懷的,哈哈!
2.2 NGUI
資源地址:https://assetstore.unity.com/packages/tools/gui/ngui-next-gen-ui-2413#description
其特點如下:
1) 圖集:需要自己規劃好后,手動打開圖集。
2) 渲染原理:先根據Panel的Depth排序,Panel面板內部再根據Depth排序。將相同材質的Widget進行Mesh合并。
3) 支持圖文混排。
4) 支持循環列表組件。
2.3 Unity進階版UGUI
學習地址:http://c.biancheng.net/view/2712.html
UGUI是在NGUI之后Unity官方推出的,一定程度上借鑒了NGUI的設計理念,在某些方面做了改進優化,如自適應、圖集等。其特點如下:
1)圖集:圖集概念不重,會自動打包成圖集。要注意的是,放在Resources文件夾下的貼圖不會被打入圖集;
2)渲染原理:根據Hierarchy的順序來排序,越下面渲染在越頂層。Canvas與NGUI的UIPanel類似,每個Canvas將優化合并為1個Mesh或多個SubMesh;
3)不支持圖文混排,需要自己實現;
4)不支持循環列表組件,需要自己實現;
5)有錨點,方便屏幕自適應。
2.4 FairyGUI
官網地址:https://www.fairygui.com/download
它是獨立的UI編輯器,且對美術、策劃都友好。其特點如下:
1)目前主流的游戲開發引擎都支持;
2)渲染原理:沒有采取Mesh合并的策略,而是基于類似于Unity的Dynamic Batching技術,對DrawCall進行優化。它在不改變顯示效果的前提下,盡可能的把相同材質的物體調整到連續的RenderingOrder值上,以促使它們能夠被Unity DynamicBatching優化;
3)支持圖文混排;
4)支持虛擬列表,即使數量巨大的列表也不會感覺太卡頓。
2.5 其他方案
因為筆者未在實際項目中使用過,所以這里不做評述了,讀者可以根據貼出的鏈接跳轉過去瞅一瞅哈!
1)Unity高階版UIToolkit
學習地址:https://docs.unity3d.com/cn/2020.1/Manual/UIElements.html
是Unity新推出的新一代UI系統,既支持游戲編輯模式也支持運行時模式。但目前還不夠完善。讀者可以嘗嘗鮮,試用一下。
2)EZGUI
資源地址:https://assetstore.unity.com/packages/tools/ez-gui-32
【注:官方資源下架 已購買可以繼續使用】
3)IGUI
資源地址:https://assetstore.unity.com/packages/tools/gui/igui-basic-1946
【注:官方資源下架 已購買可以繼續使用】
本篇主要介紹了Unity項目比較流行的UI解決方案,筆者在這里只是做一個匯總概述,并沒有去深究。至于讀者該如何選擇,仁者見仁,智者見智。一句話總結:沒有最好的,只有最適合的!
參考資料
1、Unity官網:https://unity.cn/
2、Siki學院:http://www.sikiedu.com/course/explore/unity?subCategory=&selectedthirdLevelCategory=&filter%5Btype%5D=all&filter%5Bprice%5D=all&filter%5BcurrentLevelId%5D=all&orderBy=hotSeq&from_flag=baidu_unity
本教程中,我們來學習一下如何使用Array.splice()方法將數組等分,還會講一下,Array.splice() 和 Array.slice() 它們之間的不同之處。
我們可以分兩步將數組分成兩半:
Math.ceil() 函數返回大于或等于一個給定數字的最小整數。
const list = [1, 2, 3, 4, 5, 6];
const middleIndex = Math.ceil(list.length / 2);
const firstHalf = list.splice(0, middleIndex);
const secondHalf = list.splice(-middleIndex);
console.log(firstHalf); // [1, 2, 3]
console.log(secondHalf); // [4, 5, 6]
console.log(list); // []
Array.splice() 方法通過刪除,替換或添加元素來更改數組的內容。而 Array.slice() 方法會先對數組一份拷貝,在操作。
在這兩個操作結束時,由于我們已經從數組中刪除了所有元素,所以原始數組是空的。
另請注意,在上述情況下,元素數為偶數,如果元素數為奇數,則前一半將有一個額外的元素。
const list = [1, 2, 3, 4, 5];
const middleIndex = Math.ceil(list.length / 2);
list.splice(0, middleIndex); // returns [1, 2, 3]
list.splice(-middleIndex); // returns [4, 5]
有時我們并不希望改變原始數組,這個可以配合 Array.slice() 來解決這個問題:
const list = [1, 2, 3, 4, 5, 6];
const middleIndex = Math.ceil(list.length / 2);
const firstHalf = list.slice().splice(0, middleIndex);
const secondHalf = list.slice().splice(-middleIndex);
console.log(firstHalf); // [1, 2, 3]
console.log(secondHalf); // [4, 5, 6]
console.log(list); // [1, 2, 3, 4, 5, 6];
我們看到原始數組保持不變,因為在使用Array.slice()刪除元素之前,我們使用Array.slice()復制了原始數組。
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const threePartIndex = Math.ceil(list.length / 3);
const thirdPart = list.splice(-threePartIndex);
const secondPart = list.splice(-threePartIndex);
const firstPart = list;
console.log(firstPart); // [1, 2, 3]
console.log(secondPart); // [4, 5, 6]
console.log(thirdPart); // [7, 8, 9]
簡單解釋一下上面做了啥:
現在,我們來看一看 Array.splice() 更多用法,這里因為我不想改變原數組,所以使用了 Array.slice(),如果智米們想改變原數組可以進行刪除它。
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9];
獲取數組的第一個元素
list.slice().splice(0, 1) // [1]
獲取數組的前5個元素
list.slice().splice(0, 5) // [1, 2, 3, 4, 5]
獲取數組前5個元素之后的所有元素
list.slice().splice(5) // 6, 7, 8, 9]
獲取數組的最后一個元素
list.slice().splice(-1) // [9]
獲取數組的最后三個元素
list.slice().splice(-3) // [7, 8, 9]
作者:Ashish Lahoti 譯者:前端小智 來源:jamesknelson
原文:https://codingnconcepts.com/javascript/how-to-divide-array-in-equal-parts-in-javascript/
10 年 JavaScript 都會發生一次改朝換代式的變革。在我看來,JavaScript 當前正處于一次快速變革的開始,而這段時期未來可能會被稱為 JavaScript 第三紀元。
本文最初發布于 shawn swyx wang 博客,經原作者授權由 InfoQ 中文站翻譯并分享。
JS 的第一紀元(從 1997 至 2007) 堪稱虎頭蛇尾。大家都知道 Brendan Eich 的故事,但是關于 ES4 是如何與諸如 Flash/Actionscript 之類的封閉生態系統艱難地進行激烈競爭的故事卻鮮為人知。我推薦大家讀讀《JavaScript:20 年發展史》來了解 JS 起源的前前后后,我認為這本書是一個非常合適的選擇, 因為該書是由 JS 的主要作者 Brendan Eich 和 Allen Wirfs-Brock 聯手發布的。
JS 的第二紀元(從 2009 至 2019) 是從關鍵的 2009 年開始的,這一年誕生了 npm,Node.js 和 ES5。隨著 Doug Crockford 在 《JavaScript 精粹》 一書中向我們展示了 JS 的精妙之后,JS 的使用者們創造出了一大堆的 JS 構建工具 和庫,并將 JS 的應用范圍擴展到了臺式機和新型智能手機。到了 2019 年,我們甚至看見,在手機端出現了諸如 Facebook 的 Hermes 之類的定制 JS 運行時系統,以及諸如 Svelte 3 之類的預編譯前端框架。
譯者注:
《JavaScript 精粹》,這本書的作者是 Doug Crockford,書中他主要從以 JS 的語法、對象、函數、繼承、數組、正則表達式、編碼格式以及一些優秀的功能等方面,向大家展示 JS 的精妙之處,同時也指出了 JS 的很多缺陷。
Hermes,是 Facebook 推出的一款運行在安卓系統中的 JS 引擎,該引擎對運行在安卓系統中的 React Native 應用做了性能優化,該引擎最大的特點是,會提前對代碼進行靜態優化和字節碼壓縮。
Svelte,是一個全新理念的前端框架,該框架最主要的 2 大特性是:
第一,將諸如代碼檢查、狀態管理、動畫等功能都做了封裝;
第二,構建時會將源碼直接轉換為目標運行代碼,而不是在運行時再處理(這里大家可以回想下在使用 webpack 構建的過程中,那個在運行時處理代碼的 runtimechunk.js)。
2020 年感覺像是一個新紀元的開始。如果說第一個紀元是關于一個語言的誕生,第二紀元是關于人們對這個語言的探索和擴展,那么第三紀元則是與摒棄歷史觀念和工具層級折疊相關。
注:作者早期提出過 層級折疊 的觀點
在當前的 JS 生態里,如果我們希望將編寫的代碼投入目標環境(例如瀏覽器環境)運行的話,大部分代碼都需要通過幾層工具的轉換,如 TS 編譯器、ESLint/JSLint、Less/Scss 、Babel、uglify 等,那么作者認為未來的趨勢是,這些處理層會被盡可能的折疊。
首當其沖要摒棄的歷史觀念是:JS 生態需要依賴 CommonJS 模塊系統,這種觀念是不斷妥協的結果。ES Modules 作為替代者已經伺機而動很久了,只是缺少一個一蹴而就的機會,主要的原因是,當前在使用中的工具雖然慢但是“已經夠用”,于是大家缺乏更換的動力。在前端,現代瀏覽器雖然已經具備了處理一些 ES Modules 功能的能力,但一些重要的細節依然沒有得到很好的解決。
譯者注:
由于這些重要的細節沒有解決,所以 V8 官方建議大家,在現代瀏覽器上使用 ES Modules 功能時,依然通過諸如 webpack、Rollup 之類的構建工具對源代碼進行構建。
Pika 的 Snowpack 項目希望通過提供一個外觀模式(facade)來加快 ES Modules 功能的提前應用,該模式會隨著 ES Modules 的完善而逐步消失。最后來點鼓舞人心的消息,IE11 從今年開始至 2029 年將逐步結束其緩慢的發展歷程。
另一個要摒棄的歷史觀念是:必須使用 JavaScript 構建 JavaScript 工具。 在熱路徑中,類型安全性和 性能提升(10 到 100 倍) 的潛力太大了,不容忽視。這種“只使用 JS 為 JS 構建工具”的想法,隨著 TypeScript 幾乎完全接管了 JavaScript 而逐漸消失,同時最近嶄露頭角的 Deno 和 Relay 也進一步證明了,人們將會通過學習 Rust 來向 JS 核心工具庫做貢獻。Brandon Dail 預測這種轉變(工具的構建形式)將會在 2023 年完成。不過大部分使用中的非核心工具,由于其易用性相對性能更加重要,因此我們將依然會使用 JavaScript 和 TypeScript 進行編寫。以前我們考慮的是“功能內核,命令式 Shell”,而現在我們應該考慮的是“系統內核,腳本 Shell”。
注:上面的觀點也是有爭議的。Python 的解析器 PyPy 就表明這不是一個既定的結論。
層級也在以有趣的方式進行折疊。Deno 采取了激進的方式,它編寫了一個全新的運行時,同時將諸如測試、格式化、代碼校驗和打包等一堆常用的任務工具折疊到一個二進制文件中,針對 TypeScript 甚至直接包含了一個 標準庫。而 Rome 則采用了不同的方式,它還是基于 Node.js 將這些層折疊了起來(據我所知,這些使用起來很簡單)。
10 年前,諸如 AWS、Azure、GCP 等公有云都還不存在,但是今天,它們已經是生活的一部分了。JavaScript 和云之間的關系非常微妙,以至于我都很難清晰的表述出來。云平臺的開發者不會直接使用 JS,但是 JS 卻又是他們最大的客戶。AWS Lambda 第一個推出對 JS 的支持,它的一個明顯變化是,折疊了 IDE 層和云服務層,移除了中間那個令人討厭的筆記本電腦。許多諸如 Glitch、Repl.it、Codesandbox、GitHub Codespaces、Stackblitz 的 云服務發行者 都在利用 JS 來探索這個領域。與此同時,像 Netlify 和 Vercel 一樣,JAMstack 從 PoV 開始,合并了 CI/CD 層和 CDN 層,移除了其間令人厭煩的運行時服務。
即使在前端框架中,層級折疊的發展同樣鼓舞人心。從動畫到狀態管理,Svelte 將所有的事情都折疊到了編譯器里。React 也在探索 元框架 和 客戶端與服務端集成 的方案,同時 Vue 正在致力于開發一個稱為 Vite 的“無需打包”的開發服務項目。
總結:
在 JS 第三紀元中,其構建工具的發展將會是下面幾個方面:
所有這些工作,最終都是促使開發體驗(更快的構建,行業標準的工具化)和用戶體驗(更小的構建包,更快的功能交付)變得更好。這是 JavaScript 從腳本編程語言到完整應用平臺的最終蛻變。
如果 Gary Bernhardt 的預言成真,那么第三紀元將是 JavaScript 的最后一個發展紀元(Gary Bernhardt 給出的時間結點是 2035 年)。Web Assembly 總是在 JavaScript 的周圍若隱若現,甚至連 Brendan Eich 都改變了他的名言稱:“永遠押寶在 JS 和 WASM”,他最初認為 JS 可能是“通用虛擬機”,但是曾經有人告訴我,現在 WASM 就是這個想法的最終實現。
如果真如上面所說,那么我們現在正處于 JavaScript 消亡的邊緣。
大約到 2030 年的時候,JavaScript 的第三紀元接近尾聲,那時 JavaScript 將會有什么樣的發展?請在下面評論區說出你的預測:
參考閱讀: https://www.swyx.io/writing/js-third-age/
*請認真填寫需求信息,我們會在24小時內與您取得聯系。