Unity面試題匯總(第一部分)


一、什么是渲染管道?

    答:就是告訴GPU一些數據,經過一系列的操作,得到最終要顯示的數據。渲染管道中的很多步驟,總的來說是將幾何物體從一個坐標系變換到另一個坐標系中去。

      主要步驟如下:

        本地坐標系 -- 經過世界變換矩陣 --> 世界坐標系 -- 經過視圖變換矩陣 --> 視圖坐標系 -- 經過投影變換矩陣 -->  投影坐標系 -- 經過視口變換矩陣 --> 視口坐標系

 

二、如何優化內存?

    答:優化內存的方式有很多種

      比如:

        1.壓縮自帶類庫;

        2.將暫時不用的,以后還需要使用的物體隱藏起來,而不是Destroy掉;

        3.釋放AssetBundle占用的資源;

        4.降低模型的片面數,降低模型的骨骼數量,降低貼圖的大小;

        5.使用光照貼圖,使用多層次細節(LOD),使用着色器(Shader),使用預設(Prefab)。

 

三、動態加載資源的方式,以及區別。

    答:

      1.通過Resources.Load()模塊:調用它的load函數,可以直接load並返回某個類型的Object,前提是需要把這個資源放在Resource命名的文件夾下,Unity不管有沒有場景引用,都會將其全部打包到安裝包中。

      2.通過bundle的形式:即將資源打包成 asset bundle 放在服務器或本地磁盤,然后使用www模塊get下來,之后從這個bundle中load某個Object。

      3.通過AssetDatabase.loadasset:這種方式只在editor范圍內有效,游戲運行時沒有這個函數,他通常是在開發中調用。

      區別:

      Resoueces的方式需要把所有資源全部打入安裝包,這對游戲的發布和版本升級(patch)是不利的,所以Unity不太推薦使用它,而都用bundle的方式代替,把資源打成幾個小的bundle,用哪個就load哪個,這樣有利於分包發布和版本升級。但是在開發過程中,不可能每更新一個資源就打一次bundle,所以在editor環境下可以使用AssetDatabase來模擬,這通常需要我們封裝一個dynamic resource的loader模塊,在不同的環境下做不同的實現。

 

四、什么是協同程序?

    答:在主線程運行的同時開啟另一段邏輯處理,來協助當前程序的執行,協程很像多線程,但是不是多線程。Unity的協程是在每幀結束之后去檢測yield的條件是否滿足。

 

五、Unity中的碰撞器和觸發器的區別。

    答:

      1.碰撞器是觸發器的載體,而觸發器只是碰撞器身上的一個屬性。

      2.當 Is Trigger = fasle 時,碰撞器根據物理引擎引發碰撞,產生碰撞的效果。可以調用OnCollisionEnter、OnCollisionExit 函數;

      3.當 Is Trigger = true 時,碰撞器被物理引擎所忽略,沒有碰撞效果,可以調用OnTriggerEnter、OnTriggerExit 函數。

      4.如果既要檢測到物體的接觸,又不想讓碰撞檢測影響物體移動,或者要檢測一個物體是否經過空間中的你某個區域,這時就可以用到觸發器。

 

六、物體發生碰撞的必要條件是什么?

    答:

      兩個物體都必須帶有碰撞器(Collider),其中一個物體必須還帶有Rigidbody,而且必須是運動的物體帶有Rigidbody才能檢測到碰撞。

 

七、請簡述 ArrayList 和 List 的主要區別。

    答:

      ArrayList存在類型不安全(ArrayList會把插入其中的數據都當作Object來處理),裝箱和拆箱的操作(費時)。

      List類是ArrayList類的泛型等效類。它的大部分用法都與ArrayList相似,因為List類也繼承了IList接口。最關鍵的區別在於,在聲明List集合時,我們同時需要為其聲明List集合內數據的對象類型

 

八、如何安全的在不同工程間安全地遷移asset數據?

    答:

      1.將Asset目錄和Library目錄一起遷移。

      2.導出包,export Package。

      3.用 unity 自帶的 assets Server 功能。

 

九、OnEnable、Awake、Start運行時的發生順序?哪些可能在同一個對象周期中反復的發升?

    答:Awake --> OnEnable --> Start,OnEnable在同一周期中可以反復的發生。

 

十、MeshRender 中的 material 和 sharedmaterial 的區別是什么?

    答:修改sharedMaterial將改變所有物體使用這個材質的外觀,並且也改變儲存在工程里的材質設置。不推薦修改由sharedMaterial返回的材質。如果想修改對象的材質,使用material替代。

 

十一、Unity提供了幾種光源,分別是什么?

    答:四種光源。

      1.平行光:Directional Light。

      2.點光源:Point Light。

      3.聚光燈:Spot Light。

      4.區域光源:Area Light。

 

十二、簡述一下對象池,你覺得在FPS里哪些東西適合使用對象池?

    答:對象池就是存放需要被反復調用的資源的一個空間,當一個對象會大量生成的時候,如果每次都銷毀創建會很費時間。所以通過對象池把暫時不用的對象放到一個空間中(也就是一個集合),當下次要重新生成這個對象的時候,先去池中查找一下是否有可用的對象,如果有的話就直接拿出來使用,不需要再創建。如果沒有可用對象的話,才進行創建。利用空間換時間來達到游戲的高速運行效果。在FPS游戲中,常常被大量賦值的對象包括:子彈、敵人、粒子等...

 

十三、CharacterController 和 Rigidbody的區別是什么?

    答:Rigidbody具有完全真實的物理特性,是Unity中最基本的一個組件,包含了常用的物理特性。而CharacterController可以說是受限的Rigidbody,具有一定的物理效果但不是完全真實的,是Unity為了使開發者能方便、快速的開發游戲而封裝的一個組件。

 

十四、簡述prefab的用處。

    答:在游戲運行時實例化,prefab相當於一個模版,對已經有的素材、腳本、參數做一個默認的配置,以便於以后的修改,同時prefab打包的內容簡化了導出的操作,便於團隊的交流。

 

十五、請簡述sealed關鍵字用在類聲明時與用在函數聲明時的作用。

    答:sealed修飾的類為密封類,用在類聲明時:可防止其他類繼承此類。用在方法中聲明時:則可防止派生類重寫此方法。

 

十六、請簡述private、protected、public、internal的區別。

    答:1.private:僅對該類公開。

      2.protected:對該類和其派生類公開。

      3.public:對任何類和成員都公開,無訪問限制。

      4.internal:只能在包含該類的程序集中訪問該類。

      知識擴展:什么事程序集?

          經由編譯器編譯得到的,供CLR進一步編譯執行的那個中間產物,在WINDOWS系統中,它一般表現為·dll或者是·exe的格式,但是要注意,它們跟普通意義上的WIN32可執行程序是完全不同的東西,程序集必須依靠CLR才能順利執行。

 

十七、使用Unity實現2d游戲,有幾種方式?

    答:1.使用本身的GUI,在Unity4.6以后出現的UGUI;

      2.把攝像機的Projection(投影)值調為Orthographic(正交投影),不考慮z軸。

      3.使用2d插件,如:2DToolKit 和 NGUI。

 

十八、在物體發生碰撞的整個過程中,有幾個階段,列出對應的函數。

    答:OnCollisionEnter --> OnCollisionStay --> OnCollisionExit。

 

十九、Unity3d的物理引擎中,有幾種施加力的方式,分別描述出來。

    答:Rigidbody.AddForce 和 Rigidbody.AddForceAtPosition。

 

二十、什么叫做鏈條關節?

    答:Hinge Joint,可以模擬兩個物體間用一根鏈條連接在一起的情況,能保持兩個物體在一個固定距離內部相互移動而不產生作用力,但是達到固定距離后就會產生拉力。

 

二十一、物體自身旋轉使用的函數是什么?

    答:Transform.Rotate();

 

二十二、Unity3d提供了用於保存和讀取數據的類(PlayerPrefs),請列出保存和讀取整型數據的函數。

    答:1.保存整型數據函數:PlayerPrefs.SetInt()

      2.讀取整型數據函數:PlayerPrefs.GetInt()。

 

二十三、Unity3d腳本從喚醒到銷毀有着一套比較完整的生命周期,請列出系統自帶的幾個重要的方法。

    答:Awake ---> OnEnable ---> Start ---> FixedUpdate ---> Update ---> LateUpdate ---> OnGUI ---> OnDisable ---> OnDestroy

 

二十四、物理系統更新一般放在哪個系統函數里?

    答:一般放在FixedUpdate里。

      FixedUpdate函數:每固定幀繪制時執行一次,和Update不同,它是渲染幀執行。FixedUpdate比較適合用於物理引擎計算,Update比較適合做控制。

 

二十五、在場景中放置多個Camera,並同時處於活動狀態會發生什么?

    答:1.若是Depth值相等,則會使用最后創建(激活)出來的攝像機進行渲染。

      2.若是Depth值不相等,則會使用Depth值最高的攝像機進行渲染。

 

二十六、如何銷毀一個UnityEngine.Object及其子類?

    答:使用Destroy()方法。

 

二十七、描述為什么Unity3d中會發生組件上出現數據丟失的情況?

    答:一般是組件上綁定的物體對象被刪除了。

 

二十八、請描述什么是LOD,它的優缺點分別是什么?

    答:LOD(Level of detail)多層次細節,是最常用的游戲優化技術。

      優點:它按照模型的位置和重要程度決定其渲染的資源分配,降低物體的面數和細節度,從而獲得高效率的渲染運算。

      缺點:增加了內存。

 

二十九、MipMap是什么?它的作用是什么?

    答:MipMap是常用的游戲優化技術,貼圖會根據與攝像機的距離,選擇不同精度的貼圖。

      作用:為了加快渲染進度和減少圖像鋸齒,貼圖被處理成一系列被預先計算和優化過的圖片組成的文件。其技術特點優點類似於LOD技術,但是不用的是,LOD是針對模型資源,而MipMap是針對的紋理貼圖資源。

      優點:優化顯存寬帶,用以減少渲染。

      缺點:增加了內存。

 

三十、請描述接口與抽象類之間的不同。

    答:1.接口和抽象類的概念不一樣。接口是對動作的的抽象,而抽象類是對根源的抽象。

      2.接口表示的是:這個對象能做什么。抽象類表示的是:這個對象是什么。

      3.在高級語言上,一個類只能繼承自另一個類,但是可以實現多個接口。

      4.接口中的所有方法都是抽象的,不用去實現。而抽象類是聲明方法的存在而不一定去實現。

      總結:當我們關注一個事物的本質的時候,用抽象類。當我們關注的是一個操作的時候,用接口。

         抽象類的功能遠超過接口,但是定義抽線類的代價更高。因為對於高級語言來說,每個類只能繼承自另一個類,在這個類中,你必須繼承或編寫出其所有子類的所有共性。雖然接口在功能上會弱化很多,但是它只是針對一個動作的描述,而且你可以在一個類中同時實現多個接口,這在設計階段會降低難度。

 

三十一、請簡述.Net與Mono的關系。

    答:mono是.net的一個開源跨平台工具,類似java虛擬機,java本身不是跨平台語言,但運行在虛擬機上就能夠實現跨平台。.net只能在windows平台下運行,mono可以實現跨平台運行,可運行於linux、Unix、Mac OS等。

 

 三十二、請簡述Unity3d支持的作為腳本的語言名稱。

    答:JavaScript C#Boo。

 

三十三、Unity3d中用於記錄節點空間幾何信息的組件名稱,及其父類名稱。

    答:用於記錄節點空間幾何信息的組件:Transform。

      其父類名稱是:Component。

 

三十四、請簡述向量的點乘、叉乘以及歸一化的意義?

    答:1.向量的點乘:兩個向量的相似度,結果越大兩個向量越相似。還可以表示投影。

      2.向量的叉乘:得到新向量垂直於原來的兩個向量。

      3.歸一化:用在只關心向量的方向,而不關心大小的時候。

 

三十五、為什么大家都在移動設備上尋求Unity3d原生GUI的替代方案?

    答:1.不美觀。

      2.OnGUI很耗費時間,效率不高,使用不方便。

 

三十六、請簡述如何在不同分辨率下保持UI的一致性?

    答:1.NGUI插件很好的解決了這一點,屏幕分辨率的自適應性。原理就是計算出當前屏幕的寬高比跟原來預設的屏幕的分辨率求出一個對比值,然后修改攝像機的Size。

      2.UGUI通過錨點、中心點和分辨率也解決了這個問題。

 

三十七、什么是LightMap?

    答:就是指在三維軟件里先打好光,然后進行渲染,把場景各表面的光照輸出到貼圖上,最后又通過引擎貼到場景上,這樣就使物體有了光照的感覺。

 

三十八、請簡述Unity3d和Cocos2d的區別。

    答:1.Unity支出C#、JavaScript等語言。Cocos2d支持c++、Html5等語言。

      2.Cocos2d開源並且免費。

      3.Unity3d支持ios、android、flash、windows、mac、wii等平台的游戲開發。Cocos2d支持ios、android、wp等平台的游戲開發。

 

三十九、請簡述C#與C++的區別。

    答:1.C 是完全面向過程的語言,用於開發規模較小的程序效率很高,但是如果開發規模較大的程序,就會顯得代碼量陡增,編寫效率下降。

      2.C++是半面向對象的語言,引入了類的封裝性、繼承性、多態性。大大簡化了代碼的編寫,提高了代碼的重用率。

      3.C#是完全面向對象的語言,簡單易學,開發效率非常高。

 

四十、請簡述結構體和類的區別。

    答:1.結構體不能被繼承,而類可以。

      2.結構體是值類型。而類是引用類型。

      3.結構體在數據參數方面效率更高,簡單數組的應用中成本很低。

      4.類在運算方面更有優勢,在抽象多級別時是最佳選擇。

 

四十一、請簡述ref參數和out參數是什么,有什么區別。

    答:1.ref關鍵字和out關鍵字的效果一樣,都是通過關鍵字找到定義在主函數里面的變量的內存地址,並通過方法體內的語法改變它的值。

      2.ref關鍵字修飾的參數必須初始化,out關鍵字修飾的參數必須在函數里賦值。

      3.ref關鍵字修飾的參數是引用,out關鍵字修飾的參數為輸出參數。

 

四十二、請簡述C#中的委托是什么,有什么用處。

    答:委托是一個類。

      它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞,這種做法可以避免在程序中大量的使用if-else(Switch)語句,同時使得程序具有更好的可擴展性。

 

四十三、C#中的排序方式有哪些?

    答:冒泡排序、選擇排序、快速排序、插入排序、希爾排序、歸並排序。

 

四十四、射線檢測碰撞物的原理是什么?

    答:射線是3D世界中一個點向一個方向發射的一條無終點的直線,在發射軌跡中與其他物體發聲碰撞時,它將停止發射。

 

四十五、Unity3d中,照相機的Clipping Planes的作用是什么?調整Near、Far兩個值,應該注意什么?

    答:Clipping Planes:裁剪平面,攝像機開始渲染和停止渲染之間的距離。

 

四十六、如何讓已經存在的GameObject在LoadLevel后不被卸載掉?

    答:

void Awake()
{
     DontDestroyOnLoad(transform.gameObject);          
}

 

四十七、請簡述GC(垃圾回收)產生的原因,並描述如何避免。

    答:GC回收堆上的內存。

      避免:1.減少new產生對象的次數。

         2.使用公用的對象(靜態成員)

         3.將String換為StringBuilder。

 

四十八、請簡述反射的實現原理。

    答:審查元數據並收集關於它的類型信息的能力。實現原理:在運行時根據程序集及其中的類型得到元數據。以下是實現步驟:

      1.引用 using System.Reflection;

      2.Assembly.Load("程序集") 加載程序集,返回類型是一個Assembly;

      3.得到程序集中的所有類的名稱

      foreach(Type type in assembly.GetTypes())

      {

        string t = type.name;

      }

      4.Type type = assembly.GetType("程序集.類名");獲取當前類的類型

      5.Activator.CreateInstance(type);創建此類型實例

      6.MethodInfo info = type.GetMeethod("方法名");獲取當前方法

      7.m.Info.Invoke(null, 方法參數);

 

四十九、簡述四元數的作用,四元數相對於歐拉角有哪些有點。(重點知識,需要學習和了解:矩陣旋轉、歐拉角、四元數)

    答:四元數用於表示旋轉。

      其相對於歐拉角的有點:

      1.避免萬向鎖。

      2.只需要一個4維的四元數就可以執行繞任意過原點的向量的旋轉,方便快捷,在某些實現下比旋轉矩陣效率更高。

      3.可以提供平滑插值。

 

五十、移動相機動作在哪個函數里執行,為什么在這個函數里執行?

    答:在LateUpdate里面執行。

      因為需要在所有的Update結束之后才調用。在官網的例子中,都是所有的Update操作完成才進行攝像機的跟進,不然的話可能會造成攝像機已經跟進,但是視角里還未有角色的空幀出現。

 

五十一、簡述GPU的工作原理。

    答:簡而言之,GPU的圖形(處理)流水線完成如下的工作:(並不一定是按照如下順序) 頂點處理:這階段GPU讀取描述3D圖形 外觀的頂點數據並根據頂點數據確定3D圖形的形狀及位置關系,建立起3D圖形的骨架。在支持DX8DX9規格的GPU中,這工作由硬件實現的Vertex Shader(定點着色器)完成。 光柵化計算:顯示器實際顯示的圖像是由像素組成的,我們需要將上面 生成的圖形上的點和線通過一定的算法轉換到相應的像素點。把一個矢量圖形轉換為一系列像素點的過程就稱為光柵化。例如,一 條數學表示的斜線段,最終被轉化成階梯狀的連續像素點。 紋理帖圖:頂點單元生成的多邊形只構成了3D物體的輪廓,而紋理映 射(texture mapping)工作完成對多變形表面的帖圖,通俗的說,就是將多邊形的表面貼上相應的圖片,從而生成真實的圖形。 TMUTexture mapping unit)即是用來完成此項工作。 像素處理:這階段(在對每個像素進行光柵化處理期間)GPU完成對像素 的計算和處理,從而確定每個像素的最終屬性。在支持DX8DX9規格的GPU中,這些工作由硬件實現的Pixel Shader(像素着 色器)完成。 最終輸出:由ROP(光柵化引擎)最終完成像素的輸出,1幀渲染完畢后,被送到顯存幀緩沖區。

    總結:GPU的工作通俗的來說就是完成3D圖形的生成,將圖形映射到相應的像素點上,對每個像素進行計算確定最終顏色並完成 輸出。

 

五十二、請簡述游戲動畫有哪幾種,以及其原理。

    答:1.關節動畫。原理:把角色分成若干獨立部分,一個部分對應一個網格模型,部分的動畫連接成一個整體的動畫,角色動畫比較靈活。

      2.單一網格模型動畫(關鍵幀動畫)。原理:由一個完整的網格模型構成,在動畫序列的關鍵幀里記錄各個頂點的原位置及其該變量,然后插值運算實現動畫效果,角色動畫較真實。

      3.骨骼動畫。原理:廣泛應用的動畫方式,集成了其它兩個動畫方式的優點。骨骼按角色特點組成一定的層次結構,有關節相連,可做相對運動,皮膚作為單一網格蒙在骨骼之外,決定角色的外觀。

 

五十三、請簡述alpha blend的工作原理。

    答:Alpha Blend實現透明效果,不過只能針對某塊區域進行alpha操作,透明度可以設置。(這道題需要去復習計算機圖形學才能回答)

 

五十四、寫出光照運算中的diffuse的計算公式。(這道題需要去學習Shader的實現原理,目前還沒能力去掌握)

    答:diffuse = kd x colorLight x max(N*L, 0);其中:

      kd:漫反射系數。

      colorLight:光的顏色。

      N:單位法線向量。

      L:由點只想光源的單位向量。其中N與L點乘,如果結果小於等於0,則漫反射為0。

 

五十五、Vertex Shader是什么,怎么計算的?

    答:頂點着色器是一段執行在GPU上的程序,用來取代 fixed pipeline 中的transformation 和 lighting,Vertex Shader 主要操作頂點。

      Vertex Shader對輸入頂點完成了從local spacehomogeneous space(齊次空間)的變換過程,homogeneous space projection space的下一個space。在這其間共有world transformation, view transformationprojection transformationlighting 幾個過程。

 

五十六、下列代碼在運行中會產生幾個臨時對象?

 

string a = new string("abc");
a = (a.ToUpper() + "123").Substring(0, 2);

 

    答:在C#中第一行是會報錯的。

      正確初始化方式:string b = new string(new char[] {'a', 'b', 'c'});

      會產生5個臨時對象。

 

五十七、下列代碼在運行中會發生什么問題?如何避免?

List<int> list = new List<int>(new int[] {1, 2, 3, 4, 5});
foreach (int item in list)
{
     Console.WriteLine(item * item);
     list.Remove(item);        
}

    答:發生的問題:產生運行時錯誤,在list.Remove(item)這行,因為foreach是只讀的,在遍歷過程中,是將遍歷的值賦值給臨時創建的item,所以不能一邊遍歷一遍刪除。

      如何避免:可以用for循環遍歷,並刪除數據。

 

五十八、Unity3d是否支持多線程?如果支持的話需要注意什么?

    答:不支持。僅能從主線程中訪問Unity3d的對象、組件和方法。如果需要同時處理很多事情,並且與Unity3d的對象互動小的話,可以用thread,否則使用coroutine。

      需要注意的是:C#中有lock這個關鍵字,以確保只有一個線程可以在特定的時間內訪問特定的對象。

 

五十九、Unity3d的協程和C#的線程之間的區別是什么?

    答:C#多線程程序同時運行多個線程。

      unity3d的協程在任意指定時刻只有一個協程在運行,並且這個正在運行的協同程序只在必要時才被掛起。除主線程之外的線程無法訪問u3d的對象、組件、方法。

      unity3d沒有多線程概念,不過unity3d也給我們提供了StartCoroutine(協同程序)和LoadLevelAsync(異步加載關卡)后台加載場景的方法。

 

六十、請簡述矩陣相乘的意義以及注意點。

    答:用於表示線性變換:平移、縮放、旋轉、投影、仿射。

      注意矩陣的蠕變:誤差的積累。

 

六十一、為什么dynamic font 在 unicode 環境下優於static font?

    答:當你在導入設置的字符(Characters )下拉菜單設置為動態(Dynamic),Unity將不會預先生成一個與所有字體的字符紋理。相反,它會使用操作系統內置的字體渲染實時來創建的紋理。這樣做的好處,它可以保存下載的大小和紋理內存,尤其是當你使用通常在用戶系統中的字體,所以你不必包括字體的數據,或當你需要支持亞洲語言或較大的字體大小(使用正常字體紋理,使字體的紋理非常大)。它的缺點,字體渲染未必所有的用戶機器上看起來完全是相同的(尤其是Mac和Windows計算機之間,或當一個字體未安裝和使用一個備用的字體),並且,在生成屏幕上所需要的字符字體紋理,有時可能會導致速度變慢。

 

六十二、當一個細小的高速物體撞向另一個較大的物體時,會出現什么情況?如何避免?

    答:可能會出現穿透現象(碰撞檢測失敗)。

      如何避免:將在明天的程序中去實現下功能。

 

六十三、請簡述OnBecameVisible和OnBecameInvisible的發生時機,以及這對回調函數的意思。

    答:OnBecameVisible:當物體處於攝像機渲染的范圍時,調用。

      OnBecameInvisible:當原本處於攝像機渲染的范圍的物體,不在攝像機渲染范圍的時候,調用。

 

六十四、什么叫動態合批?跟靜態合批有什么區別?

    答:如果動態物體共用着相同的材質,那么Unity會自動對這些物體進行批處理。動態批處理操作是自動完成的,並不需要我們進行額外的操作。

      區別:動態批處理:一切都是自動的,不需要做任何操作,並且物體是可以移動的,但是限制很多。

         靜態批處理:自由度很高,限制很少,缺點是可能會占用更多的內存,而且經過靜態批處理之后的物體就不可以再移動了。

 

六十五、請簡述StringBuilder 和 String的區別?

    答:String是字符串常量。

      StringBuffer是字符串變量 ,線程安全。

      StringBuilder是字符串變量,線程不安全。

      String類型是個不可變的對象,當每次對String進行改變時都需要生成一個新的String對象,然后將指針指向這個新的對象,如果在一個循環里面,不斷的改變一個String對象,就要不斷的生成新的對象,所以效率很低,建議在不斷更改String對象的地方不要使用 String類型。

      StringBuilder對象在做字符串連接操作時是在原來的字符串上進行修改,改善了性能。這一點我們平時使用中也許都知道,連接操作頻繁的時候,使用StringBuilder對象。

 

六十六、Unity3d Shader分哪幾種?有什么區別?

    答:表面着色器:抽象層次比較高,可以輕松地以簡潔的方式實現復雜着色。表面着色器可同時在前向渲染及延遲渲染模式下正常的工作。

      頂點片段着色器:可以非常靈活地實現需要的效果,但是需要編寫更多的代碼,並且很難與Unity的渲染管線完美集成。

      固定功能管線着色器:可以作為前兩種着色器的備用選擇,當硬件無法運行那些酷炫的Shader時,還可以通過固定功能管線着色器來繪制一些基本的內容。

 

六十七、C#中的四種訪問修飾符是什么?各有什么區別?

    答:1.屬性修飾符。

      2.存取修飾符。

      3.類型修飾符。

      4.成員修飾符。

 

      1.屬性修飾符:

        a.Seriallizable:按值將對象封送到遠程服務器。

        b.STAThread:是單線程套間的意思,是一種線程模式。

        c.MATAThread:是多線程套間的意思,也是一種線程模式。

      2.存取修飾符:

        a.public:存取不受限制。

        b.protected:只有包含該成員的類以及派生類可以存取。

        c.private:只有包含該成員的類可以存取。

        d.internal:只有當前工程可以存取。

      3.類修飾符:

        a.abstract:抽象類。指示一個類只能作為其它類的基類。

        b.sealed:密封類。指示一個類不能被繼承。所有密封類不能同時又是抽象類,因為抽象類總是希望被繼承的。

      4.成員修飾符:

        a.abstract:指示該方法或屬性沒有實現。

        b.sealed:密封方法。可以防止在派生類中對該方法的override(重載)。

        c.delegate:委托。用來定義一個函數指針。C#中的事件驅動是基於 delegate + event的。

        d.const:指定該成員的值只讀,不允許修改。

        e.event:聲明一個事件。

        f.extern:指示方法在外部實現。

        g.override.重寫。對由基類繼承成員的新實現。

        h.readOnly:指示一個域只能在聲明時以及相同類的內部被賦值。

        i.static:指示一個成員屬於類型本身,而不是屬於特定的對象。即在定義后可不經實例化,就可使用。

        j.virtual:指示一個方法或存取器的實現可以在繼承類中被覆蓋。

        k.new:在派生類中隱藏指定的基類成員,從而實現重寫的功能。若要隱藏繼承類的成員,請使用相同名稱在派生類中聲明該成員,並用new修飾符修飾它。

 

六十八、Heap與Stack有何區別?

    答:1.heap是堆,stack是棧。

      2.heap的空間是手動申請和釋放的,heap常用new關鍵字了來分配。stack空間由操作系統自動分配和釋放。

      3.heap的空間是很大的自由區。stack的空間有限。

 

六十九、值類型和引用類型有哪些區別?

    答:1.值類型的數據存儲在棧中;引用類型的數據存儲在堆中。

      2.值類型存取速度快;引用類型存取速度慢。

      3.值類型表示實際數據;引用類型表示指向存儲在堆上的數據的指針或引用。

      4.值類型繼承自System.ValueType;引用類型繼承自System.Object。

      5.棧的內存分配是自動釋放的;而堆在.NET中會有GC來釋放。

 

七十、協同程序的執行代碼是什么?有何用處?有何缺點?

    答:

function Start()
{
     StartCoroutine(WaitAndPrint(2.0f));
     print("Before WaitAndPrint Finishes " + Time.time);     
}

function WaitAndPrint(waitTime: float)
{
     yield WaitForSeconds(waitTime);
     print("WaitAndPrint" + Time.time)  
}

    作用:一個協同程序在執行過程中,可以在任意位置使用yield語句。yield的返回值控制合適恢復協同程序向下執行。協同程序在對象自有幀執行過程中堪稱優秀。協同程序在性能上沒有更多的開銷。

    缺點:協同程序並非真線程,可能會發生堵塞。

 

七十一、請簡述序列化。

    答:序列化簡單理解成把對象轉換為容易傳輸的格式的過程。比如,可以序列化一個對象,然后使用HTTP通過Internet在客戶端和服務器之間傳輸該對象。

 

七十二、概述C#中代理和事件?

    答:代理就是用來定義指向方法的引用。

      C#事件本質就是對消息的封裝,用作對象之間的通信;發送方叫事件發送器,接收方叫事件接收器。

 

七十三、客戶端和服務器交互方式有幾種?

    答:1.Socket通常也稱作“套接字”,實現服務器和客戶端之間的物理連接,並進行數據傳輸,主要有UDP和TCP兩個協議。Socket處於網絡協議的傳輸層。

      2.Http協議傳輸的主要有http協議和基於http協議的Soap協議(web service),常見的方式是http的post和get請求,web服務。

 

七十四、Unity和Android與ios如何交互?

    答:Unity可以導出Android和ios的工程,然后通過Android或者ios的類去給Unity發消息,調用Unity中的方法。

 

七十五、如何在Unity中查看場景的面數,頂點數和Draw Call數?如何降低Draw Call數?

    答:在Game視圖右上角點擊Stats。

      降低Draw Call的技術是Draw Call Baching。

 

七十六:請問alpha test在何時使用?能達到什么效果?

    答:Alpha Test ,中文就是透明度測試。簡而言之就是V&F shader中最后fragment函數輸出的該點顏色值(即上一講frag的輸出half4)的alpha值與固定值進行比較。AlphaTest語句通常於Pass{}中的起始位置。Alpha Test產生的效果也很極端,要么完全透明,即看不到,要么完全不透明。

 

七十七、Unity在移動設備上的一些優化資源的方法?

    答:1.使用assetbundle,實現資源分離和共享,將內存控制在200m之內,同時也可以實現資源的在線更新。

      2.頂點數對渲染無論是CPU還是GPU都是壓力最大的貢獻者,降低頂點數到8萬以下,fps30幀以上。

      3.只用一盞動態光,不使用陰影,不使用光照探頭。

      4.剪裁粒子系統。

      5.合並同時出現的粒子系統。

      6.自己實現輕量級的粒子系統。

      7.animator也是一個效率奇差的地方,把不需要骨骼動畫和動作過渡的地方全部使用Animation,控制骨骼數量在30根以下。

      8.刪除無意義的animator。

      9.animator的初始化很耗時,粒子上盡量不要使用animator。

      10.除主角外盡量都不要跟骨骼運動(apply root motion)。

      11.絕對禁止哪些不帶剛體,帶包圍盒的物體(static collider)運動。

      12.每幀遞歸的計算 finalalpha 改為只有初始化和變動時計算。

      13.去掉法線計算。

      14.不要每幀計算 veiwsize 和 windowsize。

      15.filldrawcall時構建頂點緩存使用array.copy。

      16.代碼裁剪:使用strip level,使用.net2.0 subset。

      17.盡量減少 smooth group。

      18.給美術定一個嚴格的經過科學驗證的美術標准,並且最喜愛Unity3d里面配以相應的檢查工具。

  

        

 

 

      

 

      

      

 

 

 

 

 

 

 

 

 

      

 

 

 

 

 

               


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM