Unity 面試題匯總(三)

Unity腳本基礎

1.Unity3D中的協程(coroutine)和C#線程之間的區別是什么?

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

Unity3d沒有多線程的概念,不過 unity 也給我們提供了 StartCoroutine(協同程序)和LoadLevelAsync(異步加載關卡)后臺加載場景的方法。 StartCoroutine 為什么叫協同程序呢,所謂協同,就是當你在 StartCoroutine 的函數體里處理一段代碼時,利用 yield 語句等待執行結果,這期間不影響主程序的繼續執行,可以協同工作。而 LoadLevelAsync 則允許你在后臺加載新資源和場景,所以再利用協同,你就可以前臺用 loading 條或動畫提示玩家游戲未卡死,同時后臺協同處理加載的事宜

2.簡述Unity3D支持的作為腳本的語言的名稱

Unity的腳本語言基于 Mono 的.Net 平臺上運行,可以使用.NET 庫,這也為 XML、數據庫、正則表達式等問題提供了很好的解決方案。

Unity里的腳本都會經過編譯,他們的運行速度也很快。這三種語言實際上的功能和運行速度是一樣的,區別主要體現在語言特性上。

JavaScript:和網頁中常用的 JavaScript 不一樣,它編譯后的運行速度很快,語法方面也會有不少區別。

C#、Boo:可以看做是 Python 語言的變種,又糅合了 Ruby 和 C#的特性,它是靜態類型語言

3.Unity3D是否支持寫成多線程程序?如果支持的話需要注意什么?

僅能從主線程中訪問Unity3D的組件,對象和 Unity3D 系統調用

4.支持:如果同時你要處理很多事情或者與Unity的對象互動小可以用 thread,否則使用coroutine。

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

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

Awake -》OnEnable-》Start? ? OnEnable在同一周期中可以反復地發生

6.請簡述OnBecameVisible及 OnBecameInvisible 的發生時機,以及這一對回調函數的意義?

當物體是否可見切換之時。可以用于只需要在物體可見時才進行的計算。

7.Unity3D如何獲知場景中需要加載的數據?

Resource.Load

AssetBundle.Load

8.物體發生碰撞時,有幾個階段,分別對應的函數

三個階段,OnCollisionEnter/Stay/Exit函數

9.u3d中,幾種施加力的方式,描述出來

rigidbody.AddForce/AddForceAtPosition,都是 rigidbody 的成員函數

10.物體自旋轉使用的函數叫什么

transform.Rotate

11.物體繞某點旋轉使用函數叫什么

transform.RotateAround

12.u3d提供了一個用于保存讀取數據的類,(playerPrefs),請列出保存讀取整形數據的函數

PlayerPrefs.SetInt與 PlayerPrefs.GetInt

13.unity3d從喚醒到銷毀有一段生命周期,請列出系統自己調用的幾個重要方法。

Awake–>OnEnable –> Start –> Update –> FixedUpdate –> LateUpdate –>OnGUI –> Reset –> OnDisable –> OnDestroy

14.物理更新一般在哪個系統函數里?

FixedUpdate,每固定幀繪制時執行一次,和 update 不同的是 FixedUpdate 是渲染幀執行,如果你的渲染效率低下的時候 FixedUpdate 調用次數就會跟著下降。FixedUpdate 比較適用于物理引擎的計算,因為是跟每幀渲染有關。Update 就比較適合做控制。

15.移動相機動作在哪個函數里,為什么在這個函數里。

LateUpdate,,是在所有 update 結束后才調,比較適合用于命令腳本的執行。官網上例子是攝像機的跟隨,都是在所有 update 操作完才跟進攝像機,不然就有可能出現攝像機已經推進了,但是視角里還未有角色的空幀出現。

16.為什么u3d會出現組件上數據丟失的情況

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

17.什么是協同程序?

在主線程運行時同時開啟另一段邏輯處理,來協助當前程序的執行。換句話說,開啟協程就是開啟一個線程。可以用來控制運動、序列以及對象的行為。

18.反向旋轉動畫的方法是什么?

反轉動畫,講動畫的速度調到-1,碰撞時,被碰撞物體與碰撞物體有collider 組件,碰撞物體有剛體組件,或角色碰撞得包含角色組件 OR 改變 animation.speed

19.用代碼實現第三角色控制器

public class Player : MonoBehaviour?{

????public Transform _cameraTrans;

????private Vector3 _cameraOffset;

????void Awake()?{

????????_cameraOffset = transform.position - _cameraTrans.position;

????}

????void Update()?{

????????_cameraTrans.position = transform.position - _cameraOffset;

????}

}

20.實現吊機吊物體的功能

吊機吊物體需要節點掛接和坐標系轉換

21.獲取、增加、刪除組件的命令分別是什么

獲取:GetComponent

增加:AddComponent

刪除:Destroy

22.Animation.CrossFade命令作用是:C

A. 動畫放大B.動畫轉換 C.動畫的淡入為其他動畫

23.Application.loadLevel命令為:A

A.加載關卡B.異步加載關卡 C.加載動作

24.?調試記錄到控制臺的命令是什么?

Debug.Log();

25.編輯器類存放路徑是什么?

工程目錄下的Assets/Editor文件夾下。

26.使用原生GUI創建一個可以拖動的窗口命令是什么?

GUI.DragWindow();

27.localPosition與 Position 的使用區別?

localPosition:自身位置,相對于父級的變換的位置。 Position:在世界坐標 transform的位置

28.含義Mathf.Round, Mathf.Clamp, Mathf.Lerp

Mathf.Round四舍五入

Mathf.Clamp限制

Mathf.Lerp插值

29.寫一個計時器工具,從整點開始計時,格式為:00:00:00

private float timer = 0f;

private int h = 0;

private int m = 0;

private int s = 0;

private string timeStr = string.Empty;

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);

}

30.寫出Animation的五個方法

AddClip添加剪輯、Blend 混合、Play 播放、Stop 停止、Sample 采樣

31.用鼠標實現在場景中拖動物體,用鼠標滾輪實現縮放(用一個 Cube 即可)。

在場景中添加一個Plan,Camera,Directional Light,Cube。添加兩個腳本scrollerScirpt(掛在Camera),CubeDragScript(掛在Cube上)。

1.鼠標滾輪實現縮放:將攝像機的鏡頭拉近或者拉遠,調整攝像機的視角就可以實現,主要實現代碼如下:

void Update () {

//鼠標滾輪的效果

?????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(); //這個很重要,循環執行

?????}

}

32.NGUI Button怎樣接受用戶點擊并調用函數,具體方法名稱是什么

1、主要是在UICamera腳本中用射線判斷點擊的物體并通過SendMessage調用OnClick() OnPress()等函數,可以說NGUI的按鈕是通過發消息這個方式調用的。具體方法名稱是OnClick()

2、void Awake ()?{

//獲取需要監聽的按鈕對象

???????GameObject button = GameObject.Find("UI Root/Button3");

//設置這個按鈕的監聽,指向本類的ButtonClick方法中。

???????UIEventListener.Get(button).onClick = OnButton3Click;

???}

???private void OnButton3Click(GameObject button)?{

Debug.Log("我是按鈕3被點擊了");

}

33.<憤怒的小鳥>給予初速度以后,怎么讓小鳥受到重力和空氣阻力的影響而繪制拋物線軌跡,說出具體的計算方法.?

Vector3 v代表初速度 v'代表現在的速度, 假設小鳥是沿的 z 軸也就是 transform.forward方向運動的質量為 1,那么 v'=v-new Vector3(0,g*t,f*t),transform.Translate(v')做的就是拋物線運動(g 為重力加速度不要用現實中的需要自己調試,f 為阻力也要自己調試設置,t 為時間)

34.當游戲中需要頻繁創建一個物體時,我們需要怎樣做能夠節省內存?

1、使用預制物體對象 Prefab

2、使用對象池技術,不使用時關閉,使用時打開

35.碰撞檢測需要物體具備什么屬性?

能檢測碰撞發生的方式有兩種,一種是利用碰撞器,另一種則是利用觸發器

【Physics.OverlapSphere相交球檢測碰撞,碰撞檢測需要包圍盒】

36.Vector3.forward與Vector3(0,0,1)是一樣的意思對嗎?

37.下哪個函數在游戲進入新場景后會被馬上調用?

MonoBehaviour.OnLevelWasLoaded

38.itween插件的作用是什么,itween 作用于世界坐標還是局部坐標,請列舉出 3 個其常用方法?

iTween是一個動畫庫,作者創建它的目的就是最小的投入實現最大的產出。讓你做開發更輕松,用它可以輕松實現各種動畫,晃動,旋轉,移動,褪色,上色,控制音頻等等“方法:

a、MoveTo 物體移動;

b、ColorTo:隨著時間改變對象的顏色組;

c、LookTo:隨時間旋轉物體讓其臉部朝向所提供的 Vector3 或 Transform 位置;

39.U3D中用于記錄節點空間幾何信息的組件名稱,及其父類名稱

Transform父類是 Component

40.NGUI:把子控件放在父控件里面,如何上下邊距都是10。

給子控件設置上下兩個錨點為10

41.如何使子控件居中,如果使用UGUI怎么實現

設置子控件錨點為中心

42.去掉敏感字的程序(手寫程序)

String s = "你是壞蛋";

s.Replace("壞蛋", "**");

43.unity3D從喚醒到銷毀有一段生命周期,列出系統自己調用的重要方法。

Awake ()

OnEnable ()

Start()

FixedUpdate()

OnTriggerXXX(Collider other)

OnCollisionXXX (Collision collisionInfo)

Update()

LateUpdate ()

OnGUI()

OnDisable ()

OnDestroy ()

44.Unity3d中resources目錄一般用來放些什么,打包的時候會有什么影響?

resource一般用來放置一些需要動態加載的資源,打包程序的時候會將Resource目錄下的全部文件都加密壓縮打進包內,這樣再想使用assetbundle方式打小包的話就不行了

45.空間內一物體繞球面固定點(0、1、2)按照固定速度speed環繞運動。

public float Speed = 1;

void Update ()?{

????transform.RotateAround (new Vector3(0,1,2),Vector3.up,Speed);

}

46.以下關于WWW.LoadFromCacheOrDownload描述正確的是:C

A.可被用于將Text Assets自動緩存到本地磁盤

B.可被用于將Resource自動緩存到本地磁盤

C.可被用于將Assets Bundles自動緩存到本地磁盤

D.可被用于將任意的Unity資源文件自動緩存到本地磁盤

47.以下哪個函數在游戲進入新場景后會被馬上調用?C

A:MonoBehaviour.OnSceneWasLoaded

B:MonoBehaviour.OnSceneEnter

C:MonoBehaviour.OnLevelWasLoaded

D:MonoBehaviour.OnLevelEnter

48.關于MonoBehavior.LateUpdate函數描述錯誤的是:B

A.當MonoBehavior類型應用后,每幀調用一次

B.常被用于處理RigidBody的更新

C.在所有Update函數執行后才能被調用

D.常被用于實現跟隨相機效果,且目標物體的位置已經在Update函數中被更新

49.某個GameObject有一個名為MyScript的腳本,該腳本中有一個名為DoSomething的函數,則如何在該GameObject的另一個腳本中國調用該函數?A

A.GetComponent().DoSomething()

B.GetComponent("MyScript").DoSomething()

C.GetComponent< MyScript >().Call("DoSomething")

D.GetComponent("MyScript"). Call("DoSomething")

50.啟用MipMaps對內存的影響是?A

A.增加約33%的內存

B.減少約33%的內存

C.增加約25%的內存

D.減少約25%的內存

51.以下關于MonoBehaviour.OnGUI()的描述的是:D

A.如果MonoBehaviour沒有被啟用,則OnGUI函數不會被調用

B.用于繪制和處理GUI events

C.每幀可能會被繪制多次,每次對應于一個GUI event

D.每幀被調用一次

52.采用Input.mousePosition來獲取鼠標在屏幕上的位置,以下表述正確的是:B

A.左上角為原點(0, 0),右下角為(Screen.Width, Screen.Height)

B.左下角為原點(0, 0),右上角為(Screen.Height, Screen.Width)

C.左下角為原點(0, 0),右上角為(Screen.Width, Screen.Height)

D.左上角為原點(0, 0),右下角為(Screen.Height, Screen.Height)

53.正確排列出下面Unity腳本自帶的函數執行順序Start,Awake,Update,OnUpdate,OnEnable,FixedUpdate,OnGUI,LateUpdate、OnDisable、OnDestory

Awake-->OnEnable-->Start-->Update-->FixedUpdate-->LateUpdate-->OnGUI-->OnDisable -->OnDestory

54.Unity中銷毀GameObject的方式,簡述DestroyDestroyImmediate的區別

Destroy銷毀場景中的物體,但是內存中它還是存在的,只有當內存不夠時,機制才會將它銷毀并釋放內存。而DestroyImmediate會立即將對象銷毀,并且將內存釋放。

55.Unity中如何派發事件(消息)

在腳本里的Update函數里調用EventDispatcher.Instance().OnTick();就可以了

56.ScriptObject的作用和使用方式

ScriptObject類型經常使用于存儲一些Unity本身不可以打包的一些object,比如字符串,一些類對象,用這個類型的子類型可以用BuildPipeline打包成assetbundle包共后續使用,非常方便。

57.如何檢測物體是否被其他對象遮擋

使用射線進行檢測

58.寫一個角色控制器,鼠標控制屏幕晃動,鼠標控制開槍。

public class Player : MonoBehaviour?{

????public GameObject _prefabBullet;

????private float _angleSpeed = 120f;

????void Update() {

????????float eularY = Input.GetAxis("Mouse X") * _angleSpeed * Time.deltaTime;

????????transform.Rotate(new Vector3(0,?eularY, 0));

????????if (Input.GetMouseButtonDown(0)) {

????????????Instantiate(_prefabBullet, transform.position, transform.rotation);

????????}

????}

}

59.敵人AI,有各種狀態,實現各種狀態之間的切換。

通過狀態機來實現各種狀態之間的切換

60.

1.寫一個角色控制器,鼠標控制屏幕晃動,鼠標控制開槍。

2.敵人AI,有各種狀態,實現各種狀態之間的切換。

3.敵人會和主角對抗,敵人被打到之后,會閃一次紅色,然后紅色比例提升10%,10次攻擊之后,成紅色。

4.敵人會自動攻擊主角,主角也會有顏色變化。

5.敵人會在范圍內巡邏。

6.UI,左邊顯示8個AI的被攻擊次數,右邊顯示AI的攻擊次數排序。

public class Player : MonoBehaviour {

????public Camera _camera;

????public GameObject _prefabBullet;

????private float _angleSpeed = 120f;

//生命值

????private int _life = 10;

//玩家的狀態

????private bool _state = false;

//是否被打到

????public void IsState() {

????????if (_state && _life > 0) {

????????????_life -= 1;

????????????_state = false;

????????} else {

????????????_state = true;

????????}

????}

????public void RoleRotate() {

????????float eularY = Input.GetAxis("Mouse X") * _angleSpeed * Time.deltaTime;

????}

//風發射子彈

????public void RoleShoot() {

????????if (Input.GetMouseButtonDown(0)) {

????????????Instantiate(_prefabBullet, transform.position, transform.rotation);

????????}

????}

}

public class Enemy : MonoBehaviour {

//敵人被打到狀態

????private bool _state = false;

//玩家與敵人距離

????private float _distance;

//角色

????public GameObject _role;

//生命值

????private int _life = 10;

//敵人被攻擊次數

????private int _timeAccack = 0;

//敵人狀態

????public void EnemyState() {

????????if (_distance >= 10f) {

????????????if (_life >= 1 && _state == true) {

????????????????_life -= 1;

????????????????_timeAccack++;

????????????}

????????????_state = false;

????????}

????????else if (_distance >= 0 && _state == false) {

????????????_state = true;

????????}

????}

//敵人與玩家距離

????public void Distance() {

????????_distance = Vector3.Distance(transform.position, _role.transform.position);

????}

????void OnGUI() {

????????GUI.TextArea(new Rect(20, 50, 80, 30), _timeAccack.ToString());

????????GUI.TextArea(new Rect(20, 90, 80, 30), _timeAccack.ToString());

????????GUI.TextArea(new Rect(20, 130, 80, 30), _timeAccack.ToString());

????}

}

61.3D空間有三個cube當做點,有一條魚的模型,要求在三點之間游動,要求轉向平滑一點,控制魚的運動朝向(用四元數和歐拉角

使用transform.localRotation = Quaternion.Slerp(Quaternion a,Quaternion b,float c)實現物體平滑轉向

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 111. [動畫系統]如何將其他類型的動畫轉換成關鍵幀動畫? 動畫->點緩存->關鍵幀 112. [動畫]Unit...
    胤醚貔貅閱讀 13,212評論 3 89
  • 希望我的開發日志記錄的經驗越來越多,給以后得自己留個記錄和參考,同時也能為廣大的同樣是想做unity獨立開發者的朋...
    文壇小生閱讀 691評論 0 5
  • 最先執行的方法是: 1、(激活時的初始化代碼)Awake,2、Start、3、Update【FixUpdate、L...
    困卡閱讀 4,282評論 0 8
  • Unity編輯器基礎 1.請描述游戲動畫有幾種,以及其原理。 主要有關節動畫、單一網格模型動畫(關鍵幀動畫)、骨骼...
    豆錚閱讀 4,654評論 0 6
  • 管理中的“剛柔并濟”是指同時具備強大的心力與同理心。欠缺鐵腕手段,便難以推動并落實工作,空有想法。欠缺彈性或是柔軟...
    LR0811閱讀 773評論 0 0