在我的上一篇文章中,我們制作了一個(gè)簡(jiǎn)單的游戲寂呛,現(xiàn)在讓我們從場(chǎng)景、攝像機(jī)凤跑、光源方面來(lái)改進(jìn)它嫩舟。
改進(jìn)結(jié)果圖
為了適應(yīng)這個(gè)游戲的劇情氢烘,我們要將畫(huà)面改得陰森一些:
你可以下載運(yùn)行我的項(xiàng)目,將我的項(xiàng)目中的Assets文件夾覆蓋你的項(xiàng)目中的Assets文件夾家厌,然后在U3D中雙擊“ass”播玖,就可以運(yùn)行了!
地形
選中一個(gè)Terrain(地形)以后饭于,在Inspector中有很多調(diào)整地形的工具:
其中前三個(gè)分別調(diào)整地形的隆起蜀踏、凹陷、平滑過(guò)渡镰绎。選中工具以后要先在Inspector中設(shè)置好刷子的形狀脓斩、大小和效果強(qiáng)度:
使用隆起工具時(shí),按住shift再點(diǎn)擊可以讓選中區(qū)域的地形變回原本的平面畴栖。
第4~6個(gè)工具分別是地面紋理随静、數(shù)目、草。
地面紋理比較容易使用燎猛,點(diǎn)擊Edit texture->add texture恋捆。然后在Diffuse中選擇一張你提前放在Assert中的圖片,你就會(huì)發(fā)現(xiàn)整個(gè)地形的紋理都變成了你選擇的圖片(第一個(gè)Texture默認(rèn)影響整個(gè)地形)重绷,后面你可以添加其他的texture沸停,可以在原本的紋理上用刷子“刷出”第二紋理、第三紋理(比如在草地上有一些光禿的土壤)昭卓。
水域
這里的水域我使用的是Standard Asset的水愤钾,它有動(dòng)態(tài)水波效果,還有倒影效果候醒,非常漂亮能颁。
首先將示例資源添加到我們的Asset:
然后選擇我們需要的Water文件夾,添加好以后你可以在你的Asset中搜索到
WaterProNighttime
Perfab倒淫,將它拖到你的場(chǎng)景中伙菊,調(diào)整好大小和位置就好了。
攝像機(jī)
在Unity中敌土,攝像機(jī)就是一個(gè)Component(部件)镜硕,任何一個(gè)GameOnject只要掛載上它,都可以變成一個(gè)“攝像師”的角色返干。
你可以去Unity文檔分別查找這些類的作用是什么(一般在第一句話就會(huì)講兴枯,比如說(shuō)Behaviour的作用是控制部件是否enable),然后你就知道為什么Unity要這樣劃分繼承關(guān)系了犬金。
一個(gè)畫(huà)面不一定是由一個(gè)攝像機(jī)渲染出來(lái)的念恍,你可以通過(guò)使用多個(gè)攝像機(jī)達(dá)到一些特別的效果,比如說(shuō)一個(gè)攝像機(jī)只渲染某一個(gè)層的對(duì)象晚顷,另一個(gè)攝像機(jī)渲染另一個(gè)層的對(duì)象(用Culling Mask控制)。
攝像機(jī)可設(shè)置的屬性
- ClearFlags :像機(jī)渲染每一幀包含兩個(gè)部分疗疟,一個(gè)就是我們能看到的顏色緩沖该默,另一個(gè)是深度緩沖(它決定畫(huà)面中物體之間的前后關(guān)系)。ClearFlags決定此攝像機(jī)在渲染下一幀之前如何清除當(dāng)前畫(huà)面的渲染策彤。
- ClearFlags默認(rèn)是Skybox栓袖,它會(huì)將顏色緩沖和深度緩沖都清除,然后渲染一個(gè)天空盒店诗,再在其上渲染場(chǎng)景中的物體裹刮。
- Solid Color:同樣會(huì)將顏色緩沖和深度緩沖都清除,只不過(guò)它不渲染天空盒庞瘸,而是簡(jiǎn)單地用一個(gè)顏色填充捧弃,再渲染場(chǎng)景中的物體。
- Depth only:僅清除深度緩沖,這樣此攝像機(jī)的顏色渲染會(huì)疊加在當(dāng)前畫(huà)面违霞,在多攝像頭的時(shí)候有時(shí)用到嘴办。
- Don't Clear:都不清除,這樣攝像機(jī)的渲染都會(huì)疊加在當(dāng)前畫(huà)面买鸽,但是深度要與遺留的畫(huà)面進(jìn)行比較涧郊,如果某個(gè)要渲染像素的深度比遺留像素的深度要淺,則覆蓋這個(gè)像素眼五,否則還是顯示原來(lái)的像素妆艘。
- Culling Mask:用這個(gè)屬性來(lái)設(shè)置攝像機(jī)只渲染哪些物體双仍。
- Projection:投影方式,分為透視(模擬人眼觀察人眼)和正交(物體大小不受距離影響)桌吃。
- Field of view:視野范圍朱沃,只適用于透視模式。
- Clipping Planes:攝像機(jī)觀察的深度范圍茅诱。Near為最近可觀察的點(diǎn)逗物,F(xiàn)ar為最遠(yuǎn)可觀察的點(diǎn)。
- Normalized View Port Rect:標(biāo)準(zhǔn)視圖矩形瑟俭,用四個(gè)數(shù)值來(lái)控制攝像機(jī)的渲染畫(huà)面在屏幕中的位置及大小翎卓,該項(xiàng)使用屏幕坐標(biāo)系(屏幕左下角為原點(diǎn)),數(shù)值在0~1之間摆寄。
X 水平位置起點(diǎn)
Y 垂直位置起點(diǎn)
W 寬度
H 高度 - Depth:深度 失暴,用于控制攝像機(jī)的渲染順序,決定有多個(gè)攝像機(jī)時(shí)的渲染順序微饥,深度大的攝像機(jī)在深度小的攝像機(jī)之后渲染逗扒。
這個(gè)參數(shù)可同Normalized View Port Rect做小地圖,類似CS右上角的地圖欠橘。
改進(jìn)游戲攝像機(jī)
為了讓游戲更有代入感矩肩,我們想要讓攝像機(jī)隨著船運(yùn)動(dòng)。做到這一點(diǎn)很簡(jiǎn)單肃续,只需要讓攝像機(jī)成為船的子對(duì)象就好了黍檩。
因?yàn)槲覀兊拇窃谶\(yùn)行時(shí)通過(guò)腳本來(lái)加載的,所以我們的攝像機(jī)也應(yīng)該通過(guò)腳本來(lái)加載始锚。
首先我們刪掉原本的攝像機(jī)刽酱。然后在BoatController中加入一個(gè)方法:
private void attachCamera() {
cameraObj = new GameObject("Camera_follow"); // 新建一個(gè)空對(duì)象叫做Camera_follow
cameraObj.transform.parent = boat.transform; // 先讓這個(gè)對(duì)象成為boat的子對(duì)象
// 調(diào)整一下Camera_follow與boat的相對(duì)方位
cameraObj.transform.localPosition = new Vector3(0, 7, -8);
cameraObj.transform.localRotation = Quaternion.Euler(10, 0, 0);
cameraObj.AddComponent<Camera>(); // 添加Camera組件,讓這個(gè)空對(duì)象成為一個(gè)攝像機(jī)
Camera cameraComp = cameraObj.GetComponent<Camera>(); // 獲取攝像機(jī)組件
cameraComp.fieldOfView = 40;
// 將Resources/skybox添加為這個(gè)攝像機(jī)的天空盒
cameraObj.AddComponent<Skybox>().material = Resources.Load("skybox") as Material;
}
然后在BoatController的構(gòu)造函數(shù)最后調(diào)用這個(gè)方法attachCamera();
瞧捌。我在我的Github項(xiàng)目中默認(rèn)注釋掉了這一行棵里,使用的依然是原本的Camera,你可以解除注釋,刪掉原來(lái)的Camera就可以看到效果了衍慎。
你在Inspector窗口可以調(diào)整的屬性转唉,絕大部分也可以在運(yùn)行時(shí)通過(guò)腳本來(lái)調(diào)整,比如說(shuō)在上面我用腳本調(diào)整了fieldOfView(攝像機(jī)的視角寬度)稳捆。要查看其他你可以調(diào)整的屬性赠法,可以看攝像機(jī)官方文檔。
光源
Light也是一種Component乔夯,且其繼承關(guān)系與Camera一模一樣砖织!
有四種光源:
- Directional light: 方向光,類似太陽(yáng)的日照效果末荐,它的位置不會(huì)影響光照情況侧纯,只有它的rotation起作用。
- Point light: 點(diǎn)光源甲脏。
- Spotlight: 聚光燈眶熬,從一個(gè)點(diǎn)發(fā)出錐形區(qū)域的光。
- Area Light:區(qū)域光块请,一般用于光照貼圖烘培娜氏。
光源的設(shè)置屬性比較簡(jiǎn)單,自己在Inspector中玩一玩就知道了墩新。
改進(jìn)游戲光源
為了營(yíng)造一個(gè)陰森的效果贸弥,我們希望只有一個(gè)聚光燈從船的上方照下來(lái),再?zèng)]有其他的光源海渊。首先先刪除原本的Directional Light绵疲。
你可能會(huì)發(fā)現(xiàn),即使你將所有光源都刪除臣疑,畫(huà)面還是亮的盔憨,這是因?yàn)镾kybox本身會(huì)發(fā)光,這時(shí)你需要找到Window->Lighting->Scene->Ambient Intensity 將強(qiáng)度調(diào)整為0朝捆。
實(shí)現(xiàn)的方式與Camera類似般渡,在BoatController中再加入一個(gè)方法:
private void attachLight() {
lightObj = new GameObject("Light_follow");
lightObj.transform.parent = boat.transform;
lightObj.transform.localPosition = new Vector3(0, 5, -2);
lightObj.transform.localRotation = Quaternion.Euler(60, 0, 0);
lightObj.AddComponent<Light>();
Light lightComp = lightObj.GetComponent<Light>();
lightComp.type = LightType.Spot; // 調(diào)整光源的類型為聚光燈
lightComp.intensity = 4; // 調(diào)整光源的強(qiáng)度
lightComp.spotAngle = 170; // 調(diào)整光源的照射張角
}
同樣要在BoatController構(gòu)造函數(shù)的最后一句話調(diào)用這個(gè)函數(shù)。
可能有同學(xué)不知道芙盘,我的這些相對(duì)位置、角度是怎么得到的呢脸秽?因?yàn)橛螒驔](méi)有運(yùn)行的時(shí)候所有物體都沒(méi)有加載儒老,也就不知道這些參數(shù)到底要怎么確定。
其實(shí)你可以在運(yùn)行游戲的時(shí)候點(diǎn)擊Scene標(biāo)簽(就在運(yùn)行按鈕的下面一行记餐,注意不要全屏游戲驮樊,否則你看不到這個(gè)標(biāo)簽),然后在里面調(diào)整。將合適的數(shù)據(jù)寫(xiě)在腳本中囚衔。
注意你在運(yùn)行過(guò)程中的調(diào)整會(huì)在游戲結(jié)束后全部復(fù)原挖腰!
總結(jié):
U3d 設(shè)計(jì)師 沒(méi)有將 Camera,Light 設(shè)計(jì)為 GameObject ,這樣我們只需要在一個(gè)物體上掛載上相應(yīng)的部件练湿,就可以將這個(gè)物體變成“攝影師”猴仑、光源,甚至同時(shí)成為兩者肥哎。否則如果攝像機(jī)辽俗、光源原生就是GameObject,我們還要去調(diào)整它們的位置篡诽、父子關(guān)系崖飘,比較麻煩。
只有Component可以改變物體特性杈女,只有Component可以在Inspoector中暴露出屬性以供設(shè)置朱浴,GameObject本身不應(yīng)該具備任何可設(shè)置的屬性(除了它必須掛載Transform部件可以設(shè)置)。即使是我們直接在Hierarchy右鍵創(chuàng)建一個(gè)Camera达椰,也只不過(guò)是Unity幫我們?cè)谝粋€(gè)空對(duì)象上掛載了幾個(gè)部件而已翰蠢。
不需要一次性將Camera和Light的所有屬性都背下來(lái),只要先學(xué)會(huì)在Inspector中調(diào)整這個(gè)部件砰碴,將來(lái)需要在腳本中調(diào)整的時(shí)候去官方文檔查找對(duì)應(yīng)的屬性或方法就好了躏筏!