在主線程運行的同時開啟另一段邏輯處理,來協助當前程序的執行,協程很像多線程,但是不是多線程,Unity的協程實在每幀結束之后去檢測yield的條件是否滿足。
碰撞器是觸發器的載體,而觸發器只是碰撞器身上的一個屬性。當Is
Trigger=false時,碰撞器根據物理引擎引發碰撞,產生碰撞的效果,可以調用OnCollisionEnter/Stay/Exit函數;當Is
Trigger=true時,碰撞器被物理引擎所忽略,沒有碰撞效果,可以調用OnTriggerEnter/Stay/Exit函數。如果既要檢測到物體的接觸又不想讓碰撞檢測影響物體移動或要檢測一個物件是否經過空間中的某個區域這時就可以用到觸發器
兩個物體都必須帶有碰撞器(Collider),其中一個物體還必須帶有Rigidbody剛體,而且必須是運動的物體帶有Rigidbody腳本才能檢測到碰撞。
ArrayList存在不安全類型(ArrayList會把所有插入其中的數據都當做Object來處理)裝箱拆箱的操作(費時)List是接口,ArrayList是一個實現了該接口的類,可以被實例化
五:如何安全的在不同工程間安全地遷移asset數據?三種方法
六:OnEnable、Awake、Start運行時的發生順序?哪些可能在同一個對象周期中反復的發生
Awake –>OnEnable->Start,OnEnable在同一周期中可以反復地發生。
七:MeshRender中material和sharedmaterial的區別?
對象池就存放需要被反復調用資源的一個空間,當一個對象回大量生成的時候如果每次都銷毀創建會很費時間,通過對象池把暫時不用的對象放到一個池中(也就是一個集合),當下次要重新生成這個對象的時候先去池中查找一下是否有可用的對象,如果有的話就直接拿出來使用,不需要再創建,如果池中沒有可用的對象,才需要重新創建,利用空間換時間來達到游戲的高速運行效果,在FPS游戲中要常被大量復制的對象包括子彈,敵人,粒子等
十:CharacterController和Rigidbody的區別
Rigidbody具有完全真實物理的特性,Unity中物理系統最基本的一個組件,包含了常用的物理特性,而CharacterController可以說是受限的的Rigidbody,具有一定的物理效果但不是完全真實的,是Unity為了使開發者能方便的開發第一人稱視角的游戲而封裝的一個組件
在游戲運行時實例化,prefab相當于一個模板,對你已經有的素材、腳本、參數做一個默認的配置,以便于以后的修改,同時prefab打包的內容簡化了導出的操作,便于團隊的交流。
十二:請簡述sealed關鍵字用在類聲明時與函數聲明時的作用
sealed修飾的類為密封類,類聲明時可防止其他類繼承此類,在方法中聲明則可防止派生類重寫此方法。
十三:請簡述private,public,protected,internal的區別
1.?使用本身的GUI,在Unity4.6以后出現的UGUI
2.把攝像機的Projection(投影)值調為Orthographic(正交投影),不考慮z軸;
十五:在物體發生碰撞的整個過程中,有幾個階段,分別列出對應的函數
三個階段,1.OnCollisionEnter?2.OnCollisionStay?3.OnCollisionExit
十六:Unity3d的物理引擎中,有幾種施加力的方式,分別描述出來
rigidbody.AddForce/AddForceAtPosition,都在rigidbody系列函數中。大家可以自己去查看一下rigidbody的API
Hinge?Joint,可以模擬兩個物體間用一根鏈條連接在一起的情況,能保持兩個物體在一個固定距離內部相互移動而不產生作用力,但是達到固定距離后就會產生拉力。
十九:Unity3d提供了一個用于保存和讀取數據的類(PlayerPrefs),請列出保存和讀取整形數據的函數
PlayerPrefs.SetInt()??PlayerPrefs.GetInt()
二十:Unity3d腳本從喚醒到銷毀有著一套比較完整的生命周期,請列出系統自帶的幾個重要的方法。
Awake——>OnEnable–>Start——>FixedUpdate——>Update——>LateUpdate——>OnGUI——>OnDisable——>OnDestroy
FixedUpdate,每固定幀繪制時執行一次,和Update不同的是FixedUpdate是渲染幀執行,如果你的渲染效率低下的時候FixedUpdate調用次數就會跟著下降。FixedUpdate比較適用于物理引擎的計算,因為是跟每幀渲染有關。Update就比較適合做控制。
二十二:在場景中放置多個Camera并同時處于活動狀態會發生什么?
二十三:如何銷毀一個UnityEngine.Object及其子類?
二十四:請描述為什么Unity3d中會發生在組件上出現數據丟失的情況
LOD(Level?of?detail)多層次細節,是最常用的游戲優化技術。它按照模型的位置和重要程度決定物體渲染的資源分配,降低非重要物體的面數和細節度,從而獲得高效率的渲染運算。缺點是增加了內存。
MipMapping:在三維計算機圖形的貼圖渲染中有常用的技術,為加快渲染進度和減少圖像鋸齒,貼圖被處理成由一系列被預先計算和優化過的圖片組成的文件,這樣的貼圖被稱為MipMap。
抽象類表示該類中可能已經有一些方法的具體定義,但接口就是公公只能定義各個方法的界面
,不能具體的實現代碼在成員方法中。類是子類用來繼承的,當父類已經有實際功能的方法時該方法在子類中可以不必實現,直接引用父類的方法,子類也可以重寫該父類的方法。實現接口的時候必須要實現接口中所有的方法,不能遺漏任何一個。
mono是.net的一個開源跨平臺工具,就類似java虛擬機,java本身不是跨平臺語言,但運行在虛擬機上就能夠實現了跨平臺。.net只能在windows下運行,mono可以實現跨平臺跑,可以運行于linux,Unix,Mac OS等。
Unity的腳本語言基于Mono的.Net平臺上運行,可以使用.NET庫,這也為XML、數據庫、正則表達式等問題提供了很好的解決方案。Unity里的腳本都會經過編譯,他們的運行速度也很快。這三種語言實際上的功能和運行速度是一樣的,區別主要體現在語言特性上。JavaScript、
C#、Boo
三十:U3D中用于記錄節點空間幾何信息的組件名稱,及其父類名稱
1.點乘描述了兩個向量的相似程度,結果越大兩向量越相似,還可表示投影
三十二:為何大家都在移動設備上尋求U3D原生GUI的替代方案
NGUI很好的解決了這一點,屏幕分辨率的自適應性,原理就是計算出屏幕的寬高比跟原來的預設的屏幕分辨率求出一個對比值,然后修改攝像機的size。UGUI通過錨點和中心點和分辨率也解決這個問題
LightMap:就是指在三維軟件里實現打好光,然后渲染把場景各表面的光照輸出到貼圖上,最后又通過引擎貼到場景上,這樣就使物體有了光照的感覺。
1. Unity3D支持C#、javascript等,cocos2d-x 支持c++、Html5、Lua等。
3. Unity3D支持iOS、Android、Flash、Windows、Mac、Wii等平臺的游戲開發,cocos2d-x支持iOS、Android、WP等。
簡單的說:C#?與C++?比較的話,最重要的特性就是C#?是一種完全面向對象的語言,而C++?不是,另外C#?是基于IL?中間語言和.NET?Framework?CLR?的,在可移植性,可維護性和強壯性都比C++?有很大的改進。C#?的設計目標是用來開發快速穩定可擴展的應用程序,當然也可以通過Interop?和Pinvoke?完成一些底層操作。更詳細的區別大家可以參考這里
ref和out參數的效果一樣,都是通過關鍵字找到定義在主函數里面的變量的內存地址,并通過方法體內的語法改變它的大小。不同點就是輸出參數必須對參數進行初始化。ref必須初始化,out 參數必須在函數里賦值。ref參數是引用,out參數為輸出參數。
委托類似于一種安全的指針引用,在使用它時是當做類來看待而不是一個方法,相當于對一組方法的列表的引用。用處:使用委托使程序員可以將方法引用封裝在委托對象內。然后可以將該委托對象傳遞給可調用所引用方法的代碼,而不必在編譯時知道將調用哪個方法。與C或C++中的函數指針不同,委托是面向對象,而且是類型安全的。
射線是3D世界中一個點向一個方向發射的一條無終點的線,在發射軌跡中與其他物體發生碰撞時,它將停止發射?。
四十二:Unity中,照相機的Clipping Planes的作用是什么?調整Near、Fare兩個值時,應該注意什么?
四十三:如何讓已經存在的GameObject在LoadLevel后不被卸載掉?
void Awake()
{
DontDestroyOnLoad(transform.gameObject);
}
審查元數據并收集關于它的類型信息的能力。實現原理:在運行時根據程序集及其中的類型得到元數據。下面是實現步驟:
2. Assembly.Load(“程序集”)加載程序集,返回類型是一個Assembly
foreach (Type type in assembly.GetTypes())
{
string t = type.Name;
}
4. Type type = assembly.GetType(“程序集.類名”);獲取當前類的類型
5. Activator.CreateInstance(type); 創建此類型實例
6. MethodInfo mInfo = type.GetMethod(“方法名”);獲取當前方法
3.給定方位的表達方式有兩種,互為負(歐拉角有無數種表達方式)
LateUpdate,是在所有的update結束后才調用,比較適合用于命令腳本的執行。官網上例子是攝像機的跟隨,都是所有的update操作完才進行攝像機的跟進,不然就有可能出現攝像機已經推進了,但是視角里還未有角色的空幀出現。
簡而言之,GPU的圖形(處理)流水線完成如下的工作:(并不一定是按照如下順序)??頂點處理:這階段GPU讀取描述3D圖形外觀的頂點數據并根據頂點數據確定3D圖形的形狀及位置關系,建立起3D圖形的骨架。在支持DX8和DX9規格的GPU中,這些工作由硬件實現的Vertex?Shader(定點著色器)完成。??光柵化計算:顯示器實際顯示的圖像是由像素組成的,我們需要將上面生成的圖形上的點和線通過一定的算法轉換到相應的像素點。把一個矢量圖形轉換為一系列像素點的過程就稱為光柵化。例如,一條數學表示的斜線段,最終被轉化成階梯狀的連續像素點。??紋理帖圖:頂點單元生成的多邊形只構成了3D物體的輪廓,而紋理映射(texture?mapping)工作完成對多變形表面的帖圖,通俗的說,就是將多邊形的表面貼上相應的圖片,從而生成“真實”的圖形。TMU(Texture?mapping?unit)即是用來完成此項工作。??像素處理:這階段(在對每個像素進行光柵化處理期間)GPU完成對像素的計算和處理,從而確定每個像素的最終屬性。在支持DX8和DX9規格的GPU中,這些工作由硬件實現的Pixel?Shader(像素著色器)完成。??最終輸出:由ROP(光柵化引擎)最終完成像素的輸出,1幀渲染完畢后,被送到顯存幀緩沖區。
總結:GPU的工作通俗的來說就是完成3D圖形的生成,將圖形映射到相應的像素點上,對每個像素進行計算確定最終顏色并完成輸出。
是指在顯示器上為了顯示出圖像而經過的一系列必要操作。?渲染管道中的很多步驟,都要將幾何物體從一個坐標系中變換到另一個坐標系中去。主要步驟有:
本地坐標->視圖坐標->背面裁剪->光照->裁剪->投影->視圖變換->光柵化
2.將暫時不用的以后還需要使用的物體隱藏起來而不是直接Destroy掉;
4.降低模型的片面數,降低模型的骨骼數量,降低貼圖的大??;
5.使用光照貼圖,使用多層次細節(LOD),使用著色器(Shader),使用預設(Prefab)。
關節動畫:把角色分成若干獨立部分,一個部分對應一個網格模型,部分的動畫連接成一個整體的動畫,角色比較靈活,Quake2中使用這種動畫;
骨骼動畫,廣泛應用的動畫方式,集成了以上兩個方式的優點,骨骼按角色特點組成一定的層次結構,有關節相連,可做相對運動,皮膚作為單一網格蒙在骨骼之外,決定角色的外觀;
單一網格模型動畫由一個完整的網格模型構成,在動畫序列的關鍵幀里記錄各個頂點的原位置及其改變量,然后插值運算實現動畫效果,角色動畫較真實。
Alpha?Blend?實現透明效果,不過只能針對某塊區域進行alpha操作,透明度可設。
本影:景物表面上那些沒有被光源直接照射的區域(全黑的輪廓分明的區域)。
半影:景物表面上那些被某些特定光源直接照射但并非被所有特定光源直接照射的區域(半明半暗區域)
工作原理:從光源處向物體的所有可見面投射光線,將這些面投影到場景中得到投影面,再將這些投影面與場景中的其他平面求交得出陰影多邊形,保存這些陰影多邊形信息,然后再按視點位置對場景進行相應處理得到所要求的視圖(利用空間換時間,每次只需依據視點位置進行一次陰影計算即可,省去了一次消隱過程)
頂點著色器是一段執行在GPU上的程序,用來取代fixed pipeline中的transformation和lighting,Vertex Shader主要操作頂點。
Vertex Shader對輸入頂點完成了從local space到homogeneous
space(齊次空間)的變換過程,homogeneous space即projection space的下一個space。在這其間共有world
transformation, view transformation和projection
transformation及lighting幾個過程。
string a = new string("abc");
a = (a.ToUpper() + "123").Substring(0, 2);
string b = new string(new char[]{'a','b','c'});
List ls = new List(new int[] { 1, 2, 3, 4, 5 });
foreach (int item in ls)
{
Console.WriteLine(item * item);
ls.Remove(item);
}
產生運行時錯誤,在 ls.Remove(item)這行,因為foreach是只讀的。不能一邊遍歷一邊修改。
五十九:Unity3D是否支持寫成多線程程序?如果支持的話需要注意什么?
僅能從主線程中訪問Unity3D的組件,對象和Unity3D系統調用
支持:如果同時你要處理很多事情或者與Unity的對象互動小可以用thread,否則使用coroutine。
注意:C#中有lock這個關鍵字,以確保只有一個線程可以在特定時間內訪問特定的對象
多線程程序同時運行多個線程 ,而在任一指定時刻只有一個協程在運行,并且這個正在運行的協同程序只在必要時才被掛起。除主線程之外的線程無法訪問Unity3D的對象、組件、方法。
Unity3d沒有多線程的概念,不過unity也給我們提供了StartCoroutine(協同程序)和LoadLevelAsync(異步加載關卡)后臺加載場景的方法。
StartCoroutine為什么叫協同程序呢,所謂協同,就是當你在StartCoroutine的函數體里處理一段代碼時,利用yield語句等待執行結果,這期間不影響主程序的繼續執行,可以協同工作。
六十二:為什么dynamic font在unicode環境下優于static font
Unicode是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案。
使用動態字體時,Unity將不會預先生成一個與所有字體的字符紋理。當需要支持亞洲語言或者較大的字體的時候,若使用正常紋理,則字體的紋理將非常大。
六十三:當一個細小的高速物體撞向另一個較大的物體時,會出現什么情況?如何避免?
六十四:請簡述OnBecameVisible及OnBecameInvisible的發生時機,以及這一對回調函數的意義?
當物體是否可見切換之時??梢杂糜谥恍枰谖矬w可見時才進行的計算。
如果動態物體共用著相同的材質,那么Unity會自動對這些物體進行批處理。動態批處理操作是自動完成的,并不需要你進行額外的操作。
區別:動態批處理一切都是自動的,不需要做任何操作,而且物體是可以移動的,但是限制很多。靜態批處理:自由度很高,限制很少,缺點可能會占用更多的內存,而且經過靜態批處理后的所有物體都不可以再移動了。
六十六:簡述StringBuilder和String的區別?
String類型是個不可變的對象,當每次對String進行改變時都需要生成一個新的String對象,然后將指針指向一個新的對象,如果在一個循環里面,不斷的改變一個對象,就要不斷的生成新的對象,所以效率很低,建議在不斷更改String對象的地方不要使用String類型。
StringBuilder對象在做字符串連接操作時是在原來的字符串上進行修改,改善了性能。這一點我們平時使用中也許都知道,連接操作頻繁的時候,使用StringBuilder對象。
表面著色器的抽象層次比較高,它可以輕松地以簡潔方式實現復雜著色。表面著色器可同時在前向渲染及延遲渲染模式下正常工作。
頂點片段著色器可以非常靈活地實現需要的效果,但是需要編寫更多的代碼,并且很難與Unity的渲染管線完美集成。
固定功能管線著色器可以作為前兩種著色器的備用選擇,當硬件無法運行那些酷炫Shader的時,還可以通過固定功能管線著色器來繪制出一些基本的內容。
char * strcpy(char * strDest,const char * strSrc)
{
if ((strDest==NULL)||(strSrc==NULL))
throw "Invalid argument(s)";
char * strDestCopy=strDest;
while ((*strDest++=*strSrc++)!='\0');
return strDestCopy;
}
1.屬性修飾符 2.存取修飾符 3.類修飾符 4.成員修飾符。
MATAThread:是多線程套間的意思,也是一種線程模型。
sealed:密封類。指示一個類不能被繼承。理所當然,密封類不能同時又是抽象類,因為抽象總是希望被繼承的。
sealed:密封方法??梢苑乐乖谂缮愔袑υ摲椒ǖ膐verride(重載)。不是類的每個成員方法都可以作為密封方法密封方法,必須對基類的虛方法進行重載,提供具體的實現方法。所以,在方法的聲明中,sealed修飾符總是和override修飾符同時使用。
delegate:委托。用來定義一個函數指針。C#中的事件驅動是基于delegate + event的。
readonly:指示一個域只能在聲明時以及相同類的內部被賦值。
static:指示一個成員屬于類型本身,而不是屬于特定的對象。即在定義后可不經實例化,就可使用。
virtual:指示一個方法或存取器的實現可以在繼承類中被覆蓋。
new:在派生類中隱藏指定的基類成員,從而實現重寫的功能。 若要隱藏繼承類的成員,請使用相同名稱在派生類中聲明該成員,并用 new 修飾符修飾它。
2.stack的空間由操作系統自動分配和釋放,heap的空間是手動申請和釋放的,heap常用new關鍵字來分配。
1.值類型的數據存儲在內存的棧中;引用類型的數據存儲在內存的堆中,而內存單元中只存放堆中對象的地址。
3.值類型表示實際數據,引用類型表示指向存儲在內存堆中的數據的指針或引用
4.值類型繼承自System.ValueType,引用類型繼承自System.Object
6.值類型的變量直接存放實際的數據,而引用類型的變量存放的則是數據的地址,即對象的引用。
int Fib1(int index)
{
if(index<1)
{
return -1;
}
if(index==1|| index==2)
{
return 1;
}
return Fib1(index-1)+Fib1(index-2);
}
int Fib5(int index)
{
if(index<1)
{
return -1;
}
int a1 - 1, a2 = 1, a3 = 1;
for(int i = 0; i < index - 2; i++)
{
a3=a1+a2;
a1=a2;
a2=a3;
}
return a3;
}
function Start() {
// 協同程序WaitAndPrint在Start函數內執行,可以視同于它與Start函數同步執行.
StartCoroutine(WaitAndPrint(2.0));
print (“Before WaitAndPrint Finishes ” + Time.time );
}
function WaitAndPrint (waitTime : float) {
// 暫停執行waitTime秒
yield WaitForSeconds (waitTime);
print (“WaitAndPrint “+ Time.time );
}
作用:一個協同程序在執行過程中,可以在任意位置使用yield語句。yield的返回值控制何時恢復協同程序向下執行。協同程序在對象自有幀執行過程中堪稱優秀。協同程序在性能上沒有更多的開銷。
里氏替換原則(Liskov Substitution Principle LSP)面向對象設計的基本原則之一。通俗點:就是子類對象可以賦值給基類對象,基類對象不能賦值給子類對象
Mock與Stub的區別:Mock:關注行為驗證。細粒度的測試,即代碼的邏輯,多數情況下用于單元測試。Stub:關注狀態驗證。粗粒度的測試,在某個依賴系統不存在或者還沒實現或者難以測試的情況下使用,例如訪問文件系統,數據庫連接,遠程協議等。
序列化簡單理解成把對象轉換為容易傳輸的格式的過程。比如,可以序列化一個對象,然后使用HTTP通過Internet在客戶端和服務器端之間傳輸該對象
棧通常保存著我們代碼執行的步驟,如在代碼段1中 AddFive()方法,int pValue變量,int
result變量等等。而堆上存放的則多是對象,數據等。我們可以把棧想象成一個接著一個疊放在一起的盒子。當我們使用的時候,每次從最頂部取走一個盒子。棧也是如此,當一個方法(或類型)被調用完成的時候,就從棧頂取走,接著下一個。堆則不然,像是一個倉庫,儲存著我們使用的各種對象等信息,跟棧不同的是他們被調用完畢不會立即被清理掉。
C#事件本質就是對消息的封裝,用作對象之間的通信;發送方叫事件發送器,接收方叫事件接收器
socket通常也稱作”套接字”,實現服務器和客戶端之間的物理連接,并進行數據傳輸,主要有UDP和TCP兩個協議。Socket處于網絡協議的傳輸層。
http協議傳輸的主要有http協議 和基于http協議的Soap協議(web service),常見的方式是 http 的post 和get 請求,web 服務。
Unity可以到處Android和iOS的工程,然后通過安卓或者iOS的類去給Unity發消息,調用Unity中的方法
八十一:如何在Unity3D中查看場景的面試,頂點數和Draw Call數?如何降低Draw Call數?
在Game視圖右上角點擊Stats。降低Draw Call 的技術是Draw Call Batching
這個在5.0以后在window-》Profiler下面,快捷鍵是cmd + 7(ctl + 7
八十二:請問alpha test在何時使用?能達到什么效果?
Alpha?Test?,中文就是透明度測試。簡而言之就是V&F?shader中最后fragment函數輸出的該點顏色值(即上一講frag的輸出half4)的alpha值與固定值進行比較。AlphaTest語句通常于Pass{}中的起始位置。Alpha
Test產生的效果也很極端,要么完全透明,即看不到,要么完全不透明。
1.使用assetbundle,實現資源分離和共享,將內存控制到200m之內,同時也可以實現資源的在線更新
2.頂點數對渲染無論是cpu還是gpu都是壓力最大的貢獻者,降低頂點數到8萬以下,fps穩定到了30幀左右
7.把不需要跟骨骼動畫和動作過渡的地方全部使用animation,控制骨骼數量在30根以下
10.animator的初始化很耗時(粒子上能不能盡量不用animator)
11.除主角外都不要跟骨骼運動apply root motion
12.絕對禁止掉那些不帶剛體帶包圍盒的物體(static collider?)運動
NUGI的代碼效率很差,基本上runtime的時候對cpu的貢獻和render不相上下
13每幀遞歸的計算finalalpha改為只有初始化和變動時計算
16filldrawcall時構建頂點緩存使用array.copy
17.代碼剪裁:使用strip level ,使用.net2.0 subset
19.給美術定一個嚴格的經過科學驗證的美術標準,并在U3D里面配以相應的檢查工具
八十五:將Camera組件的ClearFlags選項選成Depth only是什么意思?有何用處?
如果把攝像機的ClearFlags勾選為Deapth Only,那么攝像機就會只渲染看得見的對象,把背景會完全透明,這種情況一般用在兩個攝像機以上的場景中
八十六:在編輯場景時將GameObject設置為Static有何作用?
設置游戲對象為Static時,這些部分被靜態物體擋住而不可見時,將會剔除(或禁用)網格對象。因此,在你的場景中的所有不會動的物體都應該標記為Static。
八十七:有A和B兩組物體,有什么辦法能夠保證A組物體永遠比B組物體先渲染?
把A組物體的渲染對列大于B物體的渲染隊列,通過shader里面的渲染隊列來渲染
八十八:將圖片的TextureType選項分別選為““Texture”和“Sprite”有什么區別
Sprite作為UI精靈使用,Texture作用模型貼圖使用。Sprite需要2的整次冪,打包圖片省資源
八十九:問一個Terrain,分別貼3張,4張,5張地表貼圖,渲染速度有什么區別?為什么?
九十:什么是DrawCall?DrawCall高了又什么影響?如何降低DrawCall?
Unity中,每次引擎準備數據并通知GPU的過程稱為一次Draw Call。DrawCall越高對顯卡的消耗就越大。降低DrawCall的方法:
3. 高級特性Shader降級為統一的低級特性的Shader。
可以有cookies – 帶有 alpha通道的立方圖(Cubemap )紋理。點光源是最耗費資源的。
九十二:Unity的Shader中,Blend SrcAlpha OneMinusSrcAlpha這句話是什么意思?
作用就是Alpha混合。公式:最終顏色?=?源顏色?x?源透明值?+?目標顏色 x(1?-?源透明值)
原理就是對水面的貼圖紋理進行擾動,以產生波光玲玲的效果。用shader可以通過GPU在像素級別作擾動,效果細膩,需要的頂點少,速度快
1. 只要提供一個half-pixel偏移量,它可以讓一個控件的位置在Windows系統上精確的顯示出來(只有這個Anchor的子控件會受到影響)
2. 如果掛載到一個對象上,那么他可以將這個對象依附到屏幕的角落或者邊緣
3.UIPanel用來收集和管理它下面所有widget的組件。通過widget的geometry創建實際的draw call。沒有panel所有東西都不能夠被渲染出來,你可以把UIPanel當做Renderer