前言
該篇文章主要是總結(jié)一些unity常用(漲姿勢)的知識侣诵,提升自己的同時咏闪,也能應(yīng)付面試塘装。
##回答精辟##
Let'Go
1,如何避免點擊UI按鈕時穿透匿值,同時觸發(fā)了相同位置場景模型的點擊事件的情況?
答:
方法一 : 打開NGUI——Open——CameraTools赂摆,把里面的攝像機的勾都打上 挟憔,然后視你需要遮蓋的層來選擇即可
方法二 : 代碼控制,利用UIcamera.hoveredObject 或者UIcamera.isOverUI 可以獲取當(dāng)前鼠標(biāo)是否停駐在UI界面上,然后我們在場景的點擊事件中只需要在事件判斷加上判斷
鼠標(biāo)時否停在UI界面的邏輯值即可。
方法三:通過射線分層處理烟号,顯示層分為不同的Layer绊谭,用射線進行判斷是否點擊到UI層。
方法四:可以在最下層加個碰撞框作為屏蔽層(不建議)
2汪拥,切換場景時达传,如何讓背景音樂持續(xù)播放,而不是重新播放迫筑?
答:
這里我們假定第一次播放背景音樂的場景為startScence,我們在startScence創(chuàng)建一個新的gameObject,命名為BgmSound.并添加AudioSource組件以及一個空腳本宪赶。
在腳本中我們控制AudioSource的播放,為了切換場景音樂持續(xù)播放,我們可以在代碼中的Awake中加上DontDestroyOnLoad(this.gameObject)。這樣就能保證切換不間斷脯燃。
但是這樣會出一個問題搂妻,當(dāng)其他場景切換到此場景的時候場景會多出一個startScence.為了解決這個問題我們就只能把BgmSound動態(tài)加載.我們把BmgSound做成一個Prefab.并加上標(biāo)簽bgm.我們在代碼中控制.
01 public GameObject bgmObj = null;
02 void Start () {
03 bgmObj =GameObject.FindGameObjectWithTag( "bgm" );
04
05 if(bgmObj==null) {
06
07 bgmObj= (GameObject)Instantiate(prefab); //這里的prefab就是 BgmSound做成的預(yù)制體
08
09 }
10
11 }
3,如何實現(xiàn)游戲存檔和讀檔的功能辕棚?
答:
對于小型的數(shù)據(jù)存儲可以采用前兩種方式 :
方法一: 利用插件如: easy save
方法二: Unity給我們提供了數(shù)據(jù)持久化方案PlayerPrefs.里面有三個API.SetInt 欲主、SetFloat 邓厕、SetString 我們能通過鍵值形式存儲int、float岛蚤、string 這三種基本數(shù)據(jù)類型邑狸。
對于大型數(shù)據(jù),我們更希望的是得到一個結(jié)構(gòu)化的游戲存檔.而非前者這樣松散的單個數(shù)據(jù).
我們可以采用數(shù)據(jù)序列化的思路,在游戲中將需要保存的信息分類給出id,然后序列化成字符串輸出到Json中.
給出Api: JsonConvert.SerializeObject(object ); 將obj序列化成字符串 JsonConvert.DeserializeObject(string,type); 將字符串根據(jù)類型反序列轉(zhuǎn)化為obj.
從游戲數(shù)據(jù)存儲的安全性出發(fā),我們還可以對序列化生成的數(shù)據(jù)進行加密操作.
4涤妒,什么是協(xié)同程序单雾?請舉一個游戲中應(yīng)用協(xié)程的例子。
答:
協(xié)同程序她紫,即在主程序運行時同時開啟另一段邏輯處理硅堆,來協(xié)同當(dāng)前程序的執(zhí)行。
在Unity中:我們可以把某個需要協(xié)同處理的函數(shù)的返回值改為 IEnumerator .然后使用 StartCoroutine 開啟協(xié)程.參數(shù)可以為方法名字符串贿讹,也可以是方法加().區(qū)別就是,字符串做參數(shù)的時候協(xié)程函
數(shù)只能最多有一個參數(shù)渐逃。而類似于StartCoroutine(Func(int a,int b))則可以使用多個參數(shù)。但是字符串做參數(shù)的好處是可以用 StopCoroutine 來定向 停止某個協(xié)程民褂。在協(xié)程函數(shù)中我們可以使用
WaitForSeconds(float) 來延遲 float 秒.達到延時效果.
在Unity 協(xié)同程序主要是用來延時,其應(yīng)用有很多地方,比如: 子彈茄菊、特效、敵人死亡等的延遲銷毀赊堪、怪物的定時刷新效果面殖、技能持續(xù)時間效果。
一個簡單的協(xié)程:
01 using UnityEngine;
02 using System.Collections;
03 using System.Collections.Generic;
04
05 public class test : MonoBehaviour {
06 IEnumerator Start()
07 {
08 yield return new WaitForSeconds(2.0f);
09 Destroy(this.gameObject);
10 }
11
12 }
這段代碼可以看出,不僅僅我們定義的函數(shù)可以設(shè)置為 IEnumerator 還可以把Start哭廉、Awake 這類函數(shù)設(shè)為協(xié)程函數(shù).
5脊僚,什么是游戲框架?使用框架的好處是什么遵绰?
答:
我覺得如果把做游戲比喻成畫一幅畫來說,框架就是把畫里面元素的線描好了辽幌。至于怎么去組合、怎么涂色就看你的你自己的想法椿访。
在我的理解中乌企,游戲主框架就是整個游戲各個模塊的架構(gòu)。游戲主框架規(guī)定了有哪些模塊以及這些模塊給出的接口赎离,以及管理游戲的各個模塊逛犹。
使用框架后,游戲分為各個模塊,被對于開發(fā)者就可以集中精力去實現(xiàn)各個模塊內(nèi)部的邏輯實現(xiàn)。同樣的, 在架構(gòu)下梁剔,保證了每個模塊的封裝虽画,也實現(xiàn)了模塊的重用性。
6荣病,如何在Unity中播放視頻码撰?
答:
提要:在Unity 中 視頻支持.mov、.mpg个盆、.mpeg脖岛、.mp4朵栖、.avi和.asf.而Unity對于視頻都是以MovieTexture來使用的。如果視頻中有聲音那么在視頻文件下面會相應(yīng)生成audio文件柴梆。所以一個完
整的視頻播放是應(yīng)該畫面和音頻的同步播放陨溅。
方法一:基于GameObject上,這種方式可以讓影片以任何方式播放,比如你要實現(xiàn)一個教室,教室講臺上有個投影幕,電影應(yīng)當(dāng)在投影幕上播放。這樣影片播放就是實打?qū)嵉脑跓赡贿@個游戲
GameObject上面播放绍在。
實現(xiàn)方法:首先你要在播放的地方加個plane门扇。上面掛一個 Play 腳本。
01 using UnityEngine;
02 using System.Collections;
03
04 public class Play : MonoBehaviour
05 {
06
07 //電影紋理
08 public MovieTexture movTexture;
09 public AudioSource audioSource;
10 void Start()
11 {
12 //設(shè)置當(dāng)前對象的主紋理為電影紋理
13 renderer.material.mainTexture = movTexture;
14 //設(shè)置電影紋理播放模式為循環(huán)
15 movTexture.loop = true;
16 //如果有聲音才播放聲音
17 audioSource = GetComponent<AudioSource>();
18 }
19 public void OnPlay()
20 {
21 movTexture.Play();
22 // audioSource.Play();
23 }
24 public void OnPause()
25 {1536134
26 movTexture.Pause();
27 // audioSource.Pause();
28 }
29 public void OnStop()
30 {
31 movTexture.Stop();
32 // audioSource.Stop();
33 }
34 }
我們將視頻生成的MovieTexture拖放復(fù)制到movTexture中,如果有聲音偿渡,應(yīng)當(dāng)給plane添加AudioSource組件并把把生成的音頻文件拖放到AudioClip處臼寄。腳本中給出了三個函數(shù)分別對應(yīng)的是
視頻的播放、暫停溜宽、停止吉拳。
方法二:基于Unity 的OnGUI實現(xiàn),這樣視頻就是以UI元素存在于游戲中。
實現(xiàn)方法:這種方法不需要載體适揉。直接可以將腳本掛在Mamera上留攒。
01 using UnityEngine;
02 using System.Collections;
03
04 public class Play : MonoBehaviour
05 {
06
07 //電影紋理
08 public MovieTexture movTexture;
09 public AudioSource audioSource;
10 void Start()
11 {
12 //設(shè)置電影紋理播放模式為循環(huán)
13 movTexture.loop = true;
14 //如果有聲音才播放聲音
15 audioSource = GetComponent<AudioSource>();
16 }
17
18 void OnGUI()
19 {
20 //繪制電影紋理
21 GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), movTexture, ScaleMode.StretchToFill);
22 }
23 public void OnPlay()
24 {
25 movTexture.Play();
26 // audioSource.Play();
27 }
28 public void OnPause()
29 {
30 movTexture.Pause();
31 // audioSource.Pause();
32 }
33 public void OnStop()
34 {
35 movTexture.Stop();
36 // audioSource.Stop();
37 }
38
39 }
我們將視頻生成的MovieTexture拖放復(fù)制到movTexture中,如果有聲音,應(yīng)當(dāng)給plane添加AudioSource組件并把把生成的音頻文件拖放到AudioClip處嫉嘀。腳本中給出了三個函數(shù)分別對應(yīng)的是 視頻的播放稼跳、暫停、停止吃沪。
7,跑酷游戲的無盡關(guān)卡是如何生成的什猖?
答:
其實跑酷游戲的場景都是由一段一段不同的路徑連接而成票彪。為了保證地圖的多樣性,游戲每段路徑都保證了不同,但是保證多個地路段模型的兩端都是能夠兩兩連接。這樣的話,其實整個游戲?qū)崟r存在的只有三個路段:1.Player正在運動的路段不狮、2.Player運動的上一個路段降铸、3.Player下一個即將進入的路段。之所以要保證多個路段是因為保證在跑酷中Cmaera在合理的角度可能會有前一段或者后一段路徑的視野摇零,我們要保證給玩家的是地圖一直存在的效果而不是臨時產(chǎn)生推掸。所以我們應(yīng)該保留三個路段( 這個數(shù)值不唯一,因為我們盡可能讓一段路徑的長度保證足夠長驻仅。 )
實現(xiàn): 一個RoadManage腳本谅畅,一個Road腳本。前者處理路徑的生成和銷毀噪服。后者處理Road和Player的數(shù)據(jù)關(guān)系毡泻,觸發(fā)前者的生成、銷毀函數(shù)粘优。
RoadManage腳本應(yīng)當(dāng)掛在Camera仇味、Light等物體上呻顽, 每個路徑Prefab都是綁定Road腳本。這個腳本能夠?qū)崟r獲得Player的位置和自身位置關(guān)系丹墨。如果當(dāng)Player剛剛進入RoadA.那么RoadA就通知RoadManage生成一個路徑廊遍。并銷毀自身。大題實現(xiàn)過程就是這樣.下面給出樣例代碼:[源自:siki的逃離地球]
01 using UnityEngine;
02 using System.Collections;
03
04 public class Road: MonoBehaviour
05 {
06 private Transform player;
07 void Awake()
08 {
09 player = GameObject.FindGameObjectWithTag("Player").transform;
10 }
11
12 void Update()
13 {
14 if (player.position.z > transform.position.z + 100)
15 RoadManage._instance.GenerateRoad();
16 Destroy(this.gameObject);
17 }
18 }
[C#] 純文本查看 復(fù)制代碼
?
01 using UnityEngine;
02 using System.Collections;
03
04 public class RoadManage : MonoBehaviour
05 {
06 public Road road1;
07 public Road road2; //這里保留了兩個路徑
08 public int roadCount = 2; //生成的第幾個路徑用于確定位置
09
10 public GameObject[] roads; //供隨機生成的不同路徑Prefabs;
11
12 public static RoadManage _instance;
13 void Awake()
14 {
15 _instance = this;
16 }
17
18 public void GenerateRoad()
19 {
20 roadCount++;
21 int type = Random.Range(0, roads.Length);
22 GameObject newRoad = Instantiate(roads[type], new Vector3(0, 0, roadCount * 3000), Quaternion.identity) as GameObject;
23 road1 = road2;
24 road2 = newRoad.GetComponent<Road>();
25 }
26 }
PS: 在地圖生成和銷毀中如果用對象池優(yōu)化贩挣。
8喉前,如何增強ARPG游戲的打擊感?
答:
這個不是太了解揽惹,我覺得打擊感應(yīng)該就是打擊過程中的給玩家反饋的擬真度被饿。真實性越強的打擊效果給玩家的打擊感越強。那么這個問題其實就是問的如何增強游戲打擊的擬真度搪搏。
我覺得要增加擬真度可以通過特效狭握、聲音、動畫等幾個方面疯溺。
1.特效论颅。不僅僅是游戲中的技能特效牛曹。例如武士2中的出血特效乙嘀、連擊特效等等。好的特效不僅僅會給玩家視覺上的享受荚坞,還可以讓玩家更容易融入游戲場景中墨闲。
2.聲音今妄。在合適的時機播放正確的音樂可能玩家不會感覺到什么,但是如果在合適的時機沒有播放或者播放的不適當(dāng)?shù)囊魳吩П蹋婕揖蜁a(chǎn)生強烈的違和感盾鳞。就假如說對打過程中,如果你的拳頭都已經(jīng)碰到敵人的身體瞻离√诮觯可以打擊音效還沒有播放。然而當(dāng)敵人都飛出去了套利。音效才播放出來推励。無疑玩家會感覺十分的不舒服。所以說肉迫,選好音效验辞、控制好播放時機對增加游戲的打擊感是必不可少的。
3.動畫喊衫。這里的動畫不是簡簡單單的動畫受神,更應(yīng)該說是結(jié)合游戲過程中物理作用下的模型的反饋。比如說格侯。玩家橫向一拳打向敵人鼻听,敵人不應(yīng)該是飛起來财著。好的動畫是應(yīng)該結(jié)合實時的物理條件下的動作反饋。給人以真實的效果呈現(xiàn)撑碴。
4.還有一些元素可以增加打擊感撑教,例如手柄上的震動或者必殺技的慢放等等。
9醉拓,游戲慢鏡頭回放功能的實現(xiàn)思路伟姐?如足球游戲中的精彩鏡頭回放。
答:
這個效果我沒有實現(xiàn)過亿卤,但我我覺得可以通過這兩種方法實現(xiàn):
1.對于足球愤兵、籃球游戲這種精彩回放往往是進球的那段時間,那么回放核心物體就是球排吴。我們可以使用一個Camera去跟隨球秆乳。讓Camera實時將渲染畫面用圖片形式保存到文件中(保存的時候也可以清除之前無用的畫面 )。如果邏輯上判定為精彩鏡頭钻哩。就可以將保存的圖片用動畫的方式播放出來屹堰。
2.如果是魔獸爭霸、LOL這種游戲回放街氢,是可以對游戲的整個場景實時回放的扯键。這樣的話就不能用Camera去實現(xiàn)了。但是我們知道一個游戲最關(guān)鍵的就是用戶輸入和游戲自身的隨機數(shù)種子珊肃。所以我們只需要記錄隨機數(shù)種子和操作序列荣刑。然后模擬一遍就可以完全真實的回放整個游戲的真實狀態(tài)。
10伦乔,LOD技術(shù)是什么嘶摊?優(yōu)缺點是?
答:
LOD( Level of detail )技術(shù)是作為Unity優(yōu)化的一大常用技術(shù)评矩。
我們都知道一個模型越是精細,頂點就會越多。渲染的時候就會耗時阱飘。所以我們在游戲優(yōu)化的時候我們除了盡量減少DrawCall也會盡量使得在不影響游戲畫面的情況下減少模型的頂點斥杜。
生活中我們都會遇到過這樣的例子: "誒,你看這東西像嗎沥匈?" “一般般吧蔗喂,不過拿遠了看還真分辨不出來「咛”缰儿。對,當(dāng)一個物體離我們眼睛過遠的時候我們是用過肉眼很難分辨其精細程度的散址。那么在游戲中我們知道一個物體不在Camera鏡頭之內(nèi)或者說是離Camera很遠的時候,無論它是否精細乖阵,我們通過肉眼是很難觀察到的宣赔。這樣的話,其實就算模型不是那么精細瞪浸。也不太會影響游戲畫面儒将。所以.LOD技術(shù)就是在根據(jù)攝像機距離對象的遠近,選擇使用不同精度的模型对蒲。它的好處是可以在適當(dāng)?shù)臅r候大量減少需要繪制的頂點數(shù)目钩蚊。這樣就達到了優(yōu)化的作用。
優(yōu)點就是:合理的使用LOD可以大大減少游戲渲染時間蹈矮。在保證游戲畫面依然精細的條件下讓支持游戲的最低配置要求大大減少砰逻。
缺點是:當(dāng)然游戲需要占用更多內(nèi)存。而且如果在LOD算法沒有把握好距離的時候泛鸟,會讓玩家看到模型頂點切換的突變蝠咆。反而效果不好。
1谈况,LOD是Levels of Detail的簡稱勺美,譯為多細節(jié)層次。LOD技術(shù)指根據(jù)物體模型的節(jié)點在顯示環(huán)境中所處的位置和重要度碑韵,決定物體渲染的資源分配赡茸,降低非重要物體的面數(shù)和細節(jié)度,從而獲得高效率的渲染運算祝闻。
2占卧,LOD的優(yōu)點可以根據(jù)距離動態(tài)地選折渲染不同細節(jié)的模型
3,LOD缺點增加項目的包的大小联喘,并且內(nèi)存會增大华蜒,屬于內(nèi)存換效果
在Unity中也可以使用LOD技術(shù),Unity提供了LODgroup這個組件豁遭。開發(fā)者可以將不同的層次細節(jié)的物體模型分別添加到LOD:0~LOD:7中叭喜。其中,LOD:0是視點距離最近具體觀看下進行顯示的模型蓖谢。一般添加層次細節(jié)最豐富的模型捂蕴,后面依次添加與原始模型外觀相同但層次細節(jié)逐次降低的模型,最后的“Culled”表示該模型在場景中消失.一般這是指物體非常遠或者不在Camera視野內(nèi)的情況
結(jié)束語
##如有錯誤闪幽,歡迎指正##