Siki_Unity_1-3_Unity零基礎入門_古跡探險


1-3 Unity零基礎入門 古跡探險

任務1/2:資料下載

鏈接:https://pan.baidu.com/s/1jHVymNk 密碼:rbob

任務3:工程的創建和打開

Project:古跡探險

任務4:工程目錄

任務5:資源的導入方式

方法1a. 在window->Asset Store->搜索

方法1b. 在Project面板上的搜索框內直接搜索想要資源的關鍵字即可,可以指定搜索范圍

可以選為Asset Store(前提是在Edit->Preferences->General->勾選Show Asset Store search hits)

方法2. 從第三方.unitypackage中導入

將.unitypackage拖入工程面板即可

或是在工程面板右鍵Import Package->Custom Package,選擇.unitypackage即可

方法3. 導入unity自帶的資源(指的是安裝unity自帶的Standard Assets資源)

在工程面板右鍵Import Package->除了Custom Package之外的都是自帶資源

如果在安裝unity的時候沒有勾選Standard Assets,則不會顯示

Standard Assets里面的資源挺優質的

任務6:3D物體

1. 自帶的簡單3D幾何體

cube/ sphere/ capsule/ cylinder/ Plane(單面顯示,多用作地板)/ Quad面片(單面顯示,小)/ Terrain/ Tree/ WindZone(風區,制造隨風搖擺的效果)/ 3D Text等

2. 復雜的3D模型

Mesh Filter:網格,模型的形狀

Mesh Renderer中的Materials:模型的特點,光滑度/透明等等

Texture:使用貼圖

任務7:菜單欄

Mobile Input是Standard Assets中擴展出來的一個菜單,用來表示是否啟動移動端的控制

GameObject菜單下方有一些有用的工具

Align With View:當想要把Camera的視角設置成當前Scene的視角的時候

任務8:工具欄

Center/ Pivot的區別

Center:中心點 有子物體的時候會計算平均的中心位置,可能會變化

Pivot:原點/ 坐標點 Position,在建模的時候一般就確定了

中間三個鍵:運行/ 暫停/ 逐幀運行

右上角Layers:每個GameObject都屬於一個層,可以設定成鎖定/不可見

任務9:窗口操作

任務10:Scene窗口下視野控制

飛行模式:按住鼠標右鍵進入飛行模式

鼠標移動進行視野旋轉

WASD進行前進后退左右的控制

QE進行垂直上下的控制

任務11:Transform組件

任務12:控制物體移動的小技巧

Ctrl:

之前提到了按住ctrl移動物體的時候會一米一米地移動,那么步長可以修改嗎?

Edit->Snap Settings->默認的move x/y/z 為1,可以修改

按住ctrl后也可以進行單位化的scale和rotate

v:

選定一個物體,按住v鍵,鼠標會自動吸附物體的頂點

可以將物體按照該頂點進行移動/ 旋轉/ 縮放

移動時會將該頂點與其他物體的頂點進行吸附

任務13:導入資源,Prefab預制體

Prefab的instance中的Inspector上有Select/ Revert/ Apply

Select:會跳轉到該instance對應的prefab上

Revert:

(如果instance的某些屬性修改成和Prefab不同時,會以粗體顯示,並且不會受到prefab的修改而改變)

Apply:點擊某個instance里的Apply,會將該instance的屬性值賦值給prefab(修改了prefab的屬性)

如果有一個instance的prefab被刪除了而仍需要保留該instance,但是instance會顯示missing,在GameObject中選中break prefab instance即可;如果有某一個instance想脫離prefab的關聯,也是選中break prefab instance即可

任務14&15:地形設計

作為開發,了解就好,團隊里的美工會設計好的

3D Object->Terrain

選中pivot,從原點進行聚焦觀察

創建一個Terrain后會在Project中自動創建一個New Terrain的文件,該文件保存了具體的地形數據,可以新建文件夾Terrains並命名為Terrain Data

組件:

Terrain Collider 地形的碰撞體

Terrain 設置地形的形狀

第一個按鈕為Raise/Lower the Terrain Height:筆刷粉刷地形的時候地形會升高/(按住Shift)降低(最低值為0)

第二個按鈕為Set the Terrain Height:升高地形,有一個height的值,升高的時候不會超過這個height,如果原地形的高度已經超過,則會慢慢降低地形直至該height;height旁邊有一個flatten的按鈕,會使整個地形的高度變為相同(flat),但不會超過maximun height

第三個按鈕為Smooth the Terrain Height:將地形變化變得平緩

第四個按鈕為Paint Texture:繪制貼圖

Edit Texture->Add Texture,select texture: 分為Albedo Smoothness和Normal,Normal不是必要的。Normal選擇后會將凹凸不平的細節顯示地更好

可以添加多張貼圖,第一張被添加的貼圖會覆蓋整個Tarrain,第二張被添加的時候不會有任何效果,需要通過鼠標進行粉刷

添加貼圖的時候下面有一個size的選擇:表示一張貼圖的大小(需要粉刷多張貼圖到整個terrain)

第五個按鈕為Place Trees:放置植被

Edit Trees->Add Tree->選擇Tree的prefab->add

之后用筆刷粉刷即可,按住shift粉刷為減少樹;

可以設置brush size/ tree density/ tree height (random)/ Lock width to height/ color variation等

第六個按鈕為Paint Details:一般用來粉飾小草/植被的細節

Edit details->Add grass texture->選擇貼圖->筆刷粉刷即可(Opacity為密度)

草是貼圖,而樹是模型,草會隨着你的視野方向改變而面向你

第七個按鈕可以設置大小等(默認長寬為500m,一個大格為100m);這里設置成50*50*height(此時一個大格為10m);高度height為地形的最大高度,設置成50

可以設置筆刷的形狀/ 大小size/ 影響地形的快慢opacity

在修改地形屬性的時候右下角會有一個Clustering的處理光照進度條,如果不想要這個處理的話(耗費性能),Window->Lighting->Setting->Scene->uncheck Auto Generate

任務16/17/18:古跡探險地形設計

1. 放置人物 Meshes->dwarf_hero

2. 如何知道hero的大小呢?

創建一個cube,大小對比;調節hero高度在1-2m之間即可

3. 創建Terrain;width:20,length:20,height:20

4. 將自動生成的Terrain數據命名並放入Terrains文件夾

5 將hero放在(10, 0, 0)的位置

6. 地形粉刷

思路:三面環山,中間略微有起伏

size 100 opacity 30 粉刷山脈

size 100 opacity 5 粉刷中間空曠地區起伏

使用smooth height將地形變得平滑

7. 添加貼圖Texture:選擇GrassRockyAlbedo

將size改為20, 20

8. 實現群山環繞的效果

Prefabs->Rock_Large, scale為0.3

環繞三面擺放,並將每一塊石頭手動隨機旋轉/調節大小等

9. 既然為古跡探險,加入Ruin元素

Prefabs里的石頭/ruin隨意加

10. 添加草/植被

Meshes->Vegetation->Low有多種草的模型

Meshes->Vegetation->Bushes有樹的模型

手動調整大小位置旋轉

11. 將所有環境有關的GameObject(樹/石/Ruin)放入empty gameobject Env

總體效果:

任務19:剛體

Mass 質量,可以控制慣性

Drag 摩擦力(移動時的阻力)

Angular Drag 旋轉時的摩擦力

Constraints:凍結某個屬性(剛體效果不改變某個屬性)

任務20:碰撞器

Box collider是最節約性能的,越復雜的collider越耗費性能,Mesh collider最耗費性能

Mesh Collider:需要assign一個mesh,選擇和Mesh Filter相同的mesh即可

比如想要給Rock_Large添加一個Mesh Collider,需要展開Rock_Large,選中里面的Group1,添加一個mesh collider,把mesh選擇為Group1即可(會自動選擇)

NB: 不需要太精細的情況下,沒必要選擇mesh collider,因為太耗費性能;如果你的mesh比較簡單,那么選擇mesh collider是可行的

任務21/22:碰撞檢測函數/ 碰撞信息取得

void OnCollisionEnter/Exit/Stay(Collision collision);

碰撞檢測是基於剛體的,也就是說即使有collider但是沒有rigidbody,碰撞檢測是不可用的

碰撞檢測的條件:https://docs.unity3d.com/Manual/CollidersOverview.html

任務23:觸發檢測

勾選collider的is trigger,使得該collider成為一個觸發器,其他物體可以進入該collider內部

void OnTriggerEnter/Exit/Stay(Collider other);

任務24:Unity中的四種燈光

Create->Light->Directional Light/ Point Light/ Spotlight/ Area Light

Directional Light:直射光/ 平行光/ 太陽,它的position是沒有影響的,只有rotation是有影響的;在天空盒子里可以看到一個太陽,太陽是位於直射光的后面的,當直射光旋轉的時候,太陽的位置也會隨之改變

Point Light:點光源/ 燈泡,屬性Range,Intensity

SpotLight:手電筒/ 從一點發射一個錐形范圍的光,錐形的大小和長度是可調節的

Area Light:區域光,主要用於烘培,實際環境的光照設置不會使用它

任務25:給場景添加火堆

古墓探險不需要太強烈的光,將directional light調成日出的狀態(180, 90, 0), indensity 0.3

創建一個空物體Light,將Direcitional light放在其下,並添加一個Point light

調成暗紫色,intensity調弱一點,分別放幾個在山上

調成弱黃色,放幾個在空地上

創建火堆Bonfire:

Prefabs->Lantern_01 火堆頭

Prefabs->Barrier_02 火堆底

在Bonfire中創建一個point light,放置在火堆的正中間,顏色偏黃,intensity調強

制作成Prefab方便日后修改

任務26/27:Lightmapping

Lightmapping 光照貼圖

如果不使用光照貼圖的話,光在游戲運行時對場景的影響是需要實時計算的,耗費性能

如果使用lightmapping的話,會提前將光照計算好,烘培成貼圖,將貼圖貼在環境模型上,實際運行時就不需要實時進行計算了,能夠很大提高性能

將Terrain,Env及其孩子勾選成static的;再將所有燈光也勾選成static

將所有燈光的mode選擇成baked

Window->Lighting->Settings

Scene中的Debug Settings中點擊Generate Lighting

會發現整個環境亮了許多,將直射光改為Rotation的x值改為191.2;點光源的range調小,重新烘焙

此時若是禁用了燈光,會發現環境下的燈光效果不變(不再是real time了)

但是這樣的話火堆的效果就沒有了,火焰需要一閃一閃的效果

火堆光的進一步改進:

將火堆光的mode改為mixed,表示即可以實時計算,又可以烘培

並將其的Shadow Type改為Hard Shadows或Soft Shadows(hard烘培時間會慢一點)

任務28:使用粒子系統創建火焰

在Bonfire下創建Effects->Particle System

Shape:修改成火堆的大小

Start Lifetime:生命時間改小一點 1.5

Start Speed:速度設置為Random between two constants 1~1.5

粒子樣子:FX->Fire->flame 4x4,這是一個4*4的動畫效果

在Fire中創建material flame,shader選擇Particles->Additive;texture選擇flame 4x4;顏色設置成白色

將該material指定給粒子系統

改變粒子系統的Renderer中的material即可

但是這時候texture的動畫效果沒有展示

勾選粒子系統的Texture Sheet Animation,將Tiles設置成4*4(4行4列的動畫)

現在已經有火焰的效果了,但是粒子太大了

修改粒子系統的Start Size即可

粒子應該越來越小:

Size over Lifetime:修改成一個曲線

也可以修改粒子數量

Emission中的Rate over time可以修改成1-20

任務29: 創建動畫(火光閃爍)

通過動畫系統實現燈光的閃爍

1. 選中Bonfire的點光源

2. Window->Animation->Create->將新建的Flicker.anim放在文件夾Animations中

會自動在Bonfire的點光源里創建一個Animator的組件,用來控制動畫的播放;和在Animations文件夾下創建一個動畫文件Flicker.anim和一個叫Point light的動畫狀態機

3. 編輯Flicker動畫

Window->Animation,以打開animation窗口,並選中Flicker或點光源

Add Property->Light->Intensity 火光亮度

經過不同時間,調整intensity數值(火焰效果需要intensity的變化很大)

Add Property->Transform->Position 火光左右搖擺

把sample設為25,減慢動畫播放速度

 

任務30:導航系統-導航網格生成

導航系統(尋路系統):角色朝某個地方運動時,通過導航系統尋找最短路徑,並沿着最短路徑到達指定位置,並會自動進行避障

進行導航網格的烘焙:

確保Env和Terrain的navigation static是勾選狀態

生成導航網格

Window->Navigation->Bake

點擊bake生成藍色區域,為可行走區域

Agent Radius:控制不可行走區域的半徑,修改成0.1

Agent Height:

因為草是可以穿越的,所以把草的Navigation static取消勾選

發現一些石頭/樹的上方也是可行走的,選中石頭的Mesh renderer組件(Group1),Navigation->Object->Navigation Area->Not Walkable(樹也類似)

控制Hero在導航網格上行走

給Hero添加導航組件Nav Mesh Agent后會自動生成一個圓柱體,用於計算某個區域是否可以穿過的參照,需要保證圓柱體和Hero模型大小保持一致:Radius/ Height

之后需要代碼來告訴Hero要去的目的地(下個任務)

任務31:通過導航系統控制英雄的移動

思路:通過鼠標在地面上點擊的點作為目的地,讓導航系統控制英雄向目的地移動

創建Hero.cs並attach到Hero

1. 獲取目標位置:鼠標按下的時候,向鼠標點擊的位置發射一道射線,判斷射線和Terrain的哪一個位置發生碰撞,獲取該位置

Input.GetMouseButtonDown(0); // 鼠標左鍵按下

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // main camera中的ScreenPointToRay()將屏幕坐標轉換為一道射線;Input.mousePosition為屏幕坐標

RaycastHit hit; // 用來保存碰撞信息

Physics.Raycast(ray, out hit); // 如果與任意碰撞器發生碰撞,返回true;out參數hit為碰撞信息

hit.point; // 碰撞的地面位置(x,y,z)

2. 控制角色到達位置:將hit.point的點賦值給Nav Mesh Agent

using UnityEngine.AI;

public navMeshAgent agent; // 得到Nav Mesh Agent;

agent.SetDestination(hit.point); // 設置Nav Mesh Agent的目的地點

3. 成功,但是角色轉向太慢了

Nav Mesh Agent->Angular Speed=360

public class Hero : MonoBehaviour {

    public NavMeshAgent agent;
    
    // Update is called once per frame
    void Update () {
        if(Input.GetMouseButtonDown(0)) {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if(Physics.Raycast(ray, out hit)) {
                agent.SetDestination(hit.point);
            }
        }
    }
}

任務32:控制攝像機的跟隨

調整相機的跟隨位置(12.22, 7.27, -5) (39.3, 0, 0) (Hero位置(12.078, 1.363, 0))

創建FollowTarget.cs並attach到Main Camera上

public Transform hero; // 跟隨目標的Transform(Transform組件就夠用了)

private Vector3 offset; offset = transform.position - hero.position; // 偏移量

transform.position = hero.position + offset; // 相機位置的跟隨

public class FollowTarget : MonoBehaviour {

    public Transform hero;
    private Vector3 offset;

    // Use this for initialization
    void Start () {
        offset = transform.position - hero.position;
    }
    
    // Update is called once per frame
    void Update () {
        transform.position = hero.position + offset;
    }
}

任務33:控制角色的動畫播放

動畫效果為Animations中的四個動畫文件,我們這里需要的是idle/ walk和run

通過動畫狀態機進行動畫的控制

Hero->Animator中需要動畫狀態機

在Animation文件夾中創建Animation Controller,叫做HeroController,並賦值到Hero

編輯動畫狀態機:

選中Hero,Window->Animator

設置默認狀態Entry,將idle動畫拖到Entry

狀態切換:

idle->walk; // 通過速度的檢測來切換狀態

如何獲得Nav Mesh Agent中的Speed呢

在Animator窗口左側Parameter中添加一個float speed

將walk動畫拖到Animator窗口中

右鍵idle狀態,make transition,指向walk狀態

點擊transition的線

在Inspector中添加一個condition:speed greater than 0

取消勾選Has Exit Time,因為動畫的切換會隨時發生

在Hero.cs中

public Animator anim; // 獲取Animator組件

anim.setFloat("speed", agent.velocity.magnitude); // 賦值給speed

public class Hero : MonoBehaviour {

    public NavMeshAgent agent;
    public Animator anim;
    
    // Update is called once per frame
    void Update () {
        if(Input.GetMouseButtonDown(0)) {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if(Physics.Raycast(ray, out hit)) {
                agent.SetDestination(hit.point);
            }
        }

        anim.SetFloat("speed", agent.velocity.magnitude);
    }
}

walk->run; // speed>2時

run->walk; //類似

walk->idle; // 類似

 

完成

 


免責聲明!

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



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