一.什么是渲染管道?
是指在顯示器上為了顯示出圖像而經過的一系列必要操作。 渲染管道中的很多步驟,都要將幾何物體從一個坐標系中變換到另一個坐標系中去。 主要步驟有: 本地坐標->視圖坐標->背面裁剪->光照->裁剪->投影->視圖變換->光柵化。
二.如何優化內存?
有很多種方式,例如 1.壓縮自帶類庫; 2.將暫時不用的以后還需要使用的物體隱藏起來而不是直接Destroy掉; 3.釋放AssetBundle占用的資源; 4.降低模型的片面數,降低模型的骨骼數量,降低貼圖的大小;
5.使用光照貼圖,使用多層次細節(LOD),使用着色器(Shader),使用預設(Prefab)。
三、動態加載資源的方式?(有時候也問區別,具體請百度)
1.Resources.Load();
2.AssetBundle
四、什么是協同程序?
在主線程運行時同時開啟另一段邏輯處理,來協助當前程序的執行。換句話說,開啟協程就是開啟一個線程。可以用來控制運動、序列以及對象的行為。
五、你用過哪些插件?
(最好多熟悉幾個插件,問的時候好回答)
1.使用Unity3d實現2d游戲,有幾種方式?
1.使用本身的GUI; 2.把攝像機的Projection(投影)值調為Orthographic(正交投影),不考慮z軸; 3.使用2d插件,如:2DToolKit;
2.Unity3d中的碰撞器和觸發器的區別?
碰撞器有碰撞的效果,IsTrigger=false,可以調用OnCollisionEnter\/Stay\/Exit函數; 觸發器沒有碰撞效果,IsTrigger=true,可以調用OnTriggerEnter\/Stay\/Exit函數。
3.物體發生碰撞的必要條件
兩個物體都必須帶有碰撞器(Collider),其中一個物體還必須帶有Rigidbody剛體。
4.CharacterController和Rigidbody的區別?
CharacterController自帶膠囊碰撞器,里面包含有剛體的屬性; Rigidbody就是剛體,使物體帶有剛體的特征。
5.在物體發生碰撞的整個過程中,有幾個階段,分別列出對應的函數
三個階段 1.OnCollisionEnter 2.OnCollisionStay 3.OnCollisionExit
6.Unity3d的物理引擎中,有幾種施加力的方式,分別描述出來
rigidbody.AddForce\/AddForceAtPosition,都在rigidbody系列函數中。
7.什么叫做鏈條關節?
Hinge Joint,可以模擬兩個物體間用一根鏈條連接在一起的情況,能保持兩個物體在一個固定距離內部相互移動而不產生作用力,但是達到固定距離后就會產生拉力。
8.物體自身旋轉使用的函數?
Transform.Rotate()
9.物體圍繞某點旋轉使用的函數?
Transform.RotateAround()
10.Unity3d提供了一個用於保存和讀取數據的類(PlayerPrefs),請列出保存和讀取整形數據的函數
PlayerPrefs.SetInt() PlayerPrefs.GetInt()
11.Unity3d提供了幾種光源類型,分別是哪幾種?
四種。 平行光:Directional Light
點光源:Point Light
聚光燈:Spot Light
區域光源:Area Light
12.Unity3d腳本從喚醒到銷毀有着一套比較完整的生命周期,請列出系統自帶的幾個重要的方法。
Reset——> Awake——>Start——>Update——>FixedUpdate——>LateUpdate——>OnGUI——>OnDisable——>OnDestroy
13.物理更新一般放在哪個系統函數里?
FixedUpdate,每固定幀繪制時執行一次,和Update不同的是FixedUpdate是渲染幀執行,如果你的渲染效率低下的時候FixedUpdate調用次數就會跟着下降。FixedUpdate比較適用於物理引擎的計算,因為是跟每幀渲染有關。Update就比較適合做控制。
14.移動攝像機的動作放在哪個系統函數中,為什么放在這個函數中?
LateUpdate,在每幀執行完畢調用,它是在所有Update結束后才調,比較適合用於命令腳本的執行。官網上例子是攝像機的跟隨,都是在所有Update操作完才跟進攝像機,不然就有可能出現攝像機已經推進了,但是視角里還未有角色的空幀出現。
15.當游戲中需要頻繁創建一個物體時,我們需要怎樣做能夠節省內存?
使用預制物體對象Prefab,然后復制創建。
16.在場景中放置多個Camera並同時處於活動狀態會發生什么?
游戲界面可以看到很多攝像機的混合。
17.請描述Prefab的作用,並描述如何在移動設備的環境下恰當的使用它?
Prefab在實例化的時候用到,主要用於經常會用到的物體,屬性方便修改。
18.如何銷毀一個UnityEngine.Object及其子類?
使用Destroy()方法;
19.請簡述Unity3d下如何安全的在不同工程間遷移asset數據,請列舉出三種方法?
1.可以把assets目錄和Library目錄一起遷移 2.導出包 3.用Unity帶的assets Server功能
20.請描述游戲動畫有哪幾種,以及其原理?
主要有關節動畫、骨骼動畫、單一網格模型動畫(關鍵幀動畫)。 關節動畫:把角色分成若干獨立部分,一個部分對應一個網格模型,部分的動畫連接成一個整體的動畫,角色比較靈活,Quake2中使用這種動畫; 骨骼動畫,廣泛應用的動畫方式,集成了以上兩個方式的優點,骨骼按角色特點組成一定的層次結構,有關節相連,可做相對運動,皮膚作為單一網格蒙在骨骼之外,決定角色的外觀; 單一網格模型動畫由一個完整的網格模型構成,在動畫序列的關鍵幀里記錄各個頂點的原位置及其改變量,然后插值運算實現動畫效果,角色動畫較真實。
21.請描述為什么Unity3d中會發生在組件上出現數據丟失的情況
一般是組件上綁定的物體對象被刪除了
22.alpha blend工作原理
Alpha Blend 實現透明效果,不過只能針對某塊區域進行alpha操作,透明度可設。
23.寫出光照計算中的diffuse的計算公式
diffuse = Kd x colorLight x max(N*L,0);Kd 漫反射系數、colorLight 光的顏色、N 單位法線向量、L 由點指向光源的單位向量、其中N與L點乘,如果結果小於等於0,則漫反射為0。
24.Lod是什么,優缺點是什么?
LOD(Level of detail)多層次細節,是最常用的游戲優化技術。它按照模型的位置和重要程度決定物體渲染的資源分配,降低非重要物體的面數和細節度,從而獲得高效率的渲染運算。
25.兩種陰影判斷的方法、工作原理。
A.陰影由兩部分組成:本影與半影 a.本影:景物表面上那些沒有被光源直接照射的區域(全黑的輪廓分明的區域) b.半影:景物表面上那些被某些特定光源直接照射但並非被所有特定光源直接照射的區域(半明半暗區域) 求陰影區域的方法:做兩次消隱過程 .一次對每個光源進行消隱,求出對於光源而言不可見的區域L;
一次對視點的位置進行消隱,求出對於視點而言可見的面S; 32.shadow area= L ∩ S
陰影分為兩種:自身陰影和投射陰影 自身陰影:因物體自身的遮擋而使光線照射不到它上面的某些可見面 35.工作原理:利用背面剔除的方法求出,即假設視點在點光源的位置。 投射陰影:因不透明物體遮擋光線使得場景中位於該物體后面的物體或區域受不到光照照射而形成的陰影 工作原理:從光源處向物體的所有可見面投射光線,將這些面投影到場景中得到投影面,再將這些投影面與場景中的其他平面求交得出陰影多邊形,保存這些陰影多邊形信息,然后再按視點位置對場景進行相應處理得到所要求的視圖(利用空間換時間,每次只需依據視點位置進行一次陰影計算即可,省去了一次消隱過程) 若是動態光源此方法就無效了。
26.Vertex Shader是什么,怎么計算?
頂點着色器
27.MipMap是什么,作用?
MipMapping:在三維計算機圖形的貼圖渲染中有常用的技術,為加快渲染進度和減少圖像鋸齒,貼圖被處理成由一系列被預先計算和優化過的圖片組成的文件,這樣的貼圖被稱為MipMap。
28.機試:二選一 1.用代碼實現第三角色控制器 2.實現吊機吊物體的功能
29.反向旋轉動畫的方法是什么?
【反轉動畫,講動畫的速度調到-1,碰撞時,被碰撞物體與碰撞物體有collider組件,碰撞物體有剛體組件,或角色碰撞得包含角色組件 OR 改變animation.speed】
30.碰撞檢測需要物體具備什么屬性?
31.獲取、增加、刪除組件的命令分別是什么?
獲取:GetComponent 增加:AddComponent 刪除:Destroy
32.Animation.CrossFade命令作用是:(C) A.動畫放大 B.動畫轉換 C.動畫的淡入為其他動畫
33.Application.loadLevel命令為:(A)
A.加載關卡
B.異步加載關卡
C.加載動作
34.調試記錄到控制台的命令是什么?
Debug.Log();
35.編輯器類存放路徑是什么?
工程目錄下的Assets\/Editor文件夾下。
36.使用原生GUI創建一個可以拖動的窗口命令是什么?
GUI.DragWindow();
37.localPosition與Position的使用區別?
localPosition:自身位置,相對於父級的變換的位置。 Position:在世界坐標transform的位置
38.意義連線
Mathf.Round 插值 Mathf.Clamp 四舍五入 Mathf.Lerp 限制
39.寫一個計時器工具,從整點開始計時,格式為:00:00:00
40.寫出Animation的五個方法
41.怎么拿到一個對象上腳本的方法
GameObject.GetComponent<>();
42.上機題:用鼠標實現在場景中拖動物體,用鼠標滾輪實現縮放(用一個Cube即可)。
43.請簡述向量的點乘,向量的叉乘以及向量歸一化的幾何意義?
點乘的幾何意義是:計算兩個向量之間的夾角,以及在某一方向上的投影; 叉乘的幾何意義是:創建垂直於平面,三角形,或者多邊形的向量;
1、Animation.CrossFade命令作用是(C) A 動畫消失 B動畫轉換 C東環的淡入為其他動畫
2、Application.loadedLevel命令為(A) A加載關卡 B異步加載關卡 C加載動作
3、反向播放動畫的方法為?
Animation.Rewind
4、碰撞檢測需要物體具備什么屬性?
兩個物體都必須帶有碰撞器(Collider),其中一個物體還必須帶有Rigidbody剛體。
5、獲取、增加、刪除組件的命令分別是什么?
獲取:GetComponent 增加:AddComponent 刪除:Destroy
6、調試記錄到控制台的命令式什么?
Debug.Log();
7、編輯器類存放的路徑是什么?
工程目錄下的Assets\/Editor文件夾下。
8、使用原聲的GUI創建一個可以拖動的窗口的命令是什么?
GUI.DragWindow();
9、localPosition與position的使用區別
localPosition:自身位置,相對於父級的變換的位置。 Position:在世界坐標transform的位置
10、連線題(漢英對照)
Mathf.Round(四舍五入) 插值 Mathf.Clamp(限制) 四舍五入 Mathf.Lerp(插值) 限制
11、寫一個計時器工具,從游戲開始計時,格式為00:00:00
using UnityEngine;
using System.Collections;
public class Cube : MonoBehaviour {
private float timer = 0f;
private int h = 0;
private int m = 0;
private int s = 0;
private string timeStr = string.Empty;
// Update is called once per frame
void Update () {
timer += Time.deltaTime;
if (timer >= 1f) {
s++;
timer = 0;
}
if (s >= 60) {
m++;
s = 0;
}
if (m >= 60) {
h++;
m = 0;
}
if (h >= 99) {
h = 0;
}
}
void OnGUI(){
timeStr = string.Format ("{0:D2}:{1:D2}:{2:D2}", h, m, s);
GUI.Label (new Rect (10, 10, 100, 200), timeStr);
}
}
12、上機題:用鼠標實現在場景中拖動物體,用鼠標滾輪實現縮放(用一個Cube即可)
在場景中添加一個Plan,Camera,Directional Light,Cube。添加兩個腳本scrollerScirpt(掛在Camera),CubeDragScript(掛在Cube上)。
1.鼠標滾輪實現縮放:將攝像機的鏡頭拉近或者拉遠,調整攝像機的視角就可以實現,主要實現代碼如下:
void Update () { //鼠標滾輪的效果 //Camera.main.fieldOfView 攝像機的視野 //Camera.main.orthographicSize 攝像機的正交投影 //Zoom out if (Input.GetAxis("Mouse ScrollWheel") < 0) { if (Camera.main.fieldOfView <= 100) Camera.main.fieldOfView += 2; if (Camera.main.orthographicSize <= 20) Camera.main.orthographicSize += 0.5F; } //Zoom in if (Input.GetAxis("Mouse ScrollWheel") > 0) { if (Camera.main.fieldOfView > 2) Camera.main.fieldOfView -= 2; if (Camera.main.orthographicSize >= 1) Camera.main.orthographicSize -= 0.5F; } }2.鼠標實現在場景中拖動物體:
解決思路就是將世界坐標轉換成屏幕坐標,然后計算物體與鼠標之間移動量,循環鼠標被按下操作,得到鼠標的當前位置,加上計算好的移動量,將新的坐標賦值給物理就行了。主要是開啟一個協同程序(Corountine)來處理
主要代碼如下:
// Use this for initialization void Start () { StartCoroutine(OnMouseDown()); } IEnumerator OnMouseDown() { //將物體由世界坐標系轉換為屏幕坐標系 Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position);//三維物體坐標轉屏幕坐標 //完成兩個步驟 1.由於鼠標的坐標系是2維,需要轉換成3維的世界坐標系 // // 2.只有3維坐標情況下才能來計算鼠標位置與物理的距離,offset即是距離 //將鼠標屏幕坐標轉為三維坐標,再算出物體位置與鼠標之間的距離 Vector3 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z)); while (Input.GetMouseButton(0)) { //得到現在鼠標的2維坐標系位置 Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z); //將當前鼠標的2維位置轉換成3維位置,再加上鼠標的移動量 Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset; //curPosition就是物體應該的移動向量賦給transform的position屬性 transform.position = curPosition; yield return new WaitForFixedUpdate(); //這個很重要,循環執行 } }
