Unity的學習(三):古蹟探險

一、新建項目

新建項目,並在Assets下右鍵Import Package ->Custom Package導入資源。如下圖所示。
在這裏插入圖片描述
在這裏插入圖片描述

二、地形設計

地形工具的使用可以參考Unity官方文檔

2.1創建地形

在Hierarchy中右鍵創建Terrain(地形),同時在Assets中會出現New Terrain(保存的是地形相關數據),將其重命名爲Terrain Data並將其放入創建的Terrain文件夾中。
在這裏插入圖片描述

2.2 調整地形的長度和寬度

在Hierarchy視圖中選中Terrain,可以在Inspector視圖中看到Terrain遊戲物體的組件Terrain,這時點擊齒輪(Terrain Settings),在其中可以設置許多地形相關屬性。找到Terrain Width 和Terrain Length以及Terrain Height(地形的最大高度),將他們的值設爲50,每一個在修改後,按下回車將會生效。如下圖所示。
在這裏插入圖片描述

2.3 Raise or Lower Terrain(升高或降低地形)

在這裏插入圖片描述

其中
Brush size:用來調整刷子尺寸的
Opacity:地形強度,當Opacity越大時,地形升高的越快。

按住shift鍵並且用刷子刷地形可以降低地形。
在這裏插入圖片描述

詳細的可以參考Unity官方文檔

2.4 Smooth Height

此工具可以將地形設計的更加平滑。

2.5 Paint Texture

使用 Paint Texture 工具可將紋理(如草、雪或沙)添加到地形。如下圖所示。在這裏插入圖片描述

詳情請參考Unity官方文檔的Paint Texture地形圖層

2.6 Paint Trees

通過點擊Paint Trees圖標可以在地形上擺放一些樹,如下圖所示。
在這裏插入圖片描述

詳細請參考Unity官方文檔

2.7 Paint Details

通過點擊Paint Details圖標,可以對草和其他一些細節進行處理,如下圖所示。
在這裏插入圖片描述
詳細的請參考Unity官方文檔

三、古蹟探險地形設計

此處自由發揮,就不描述了。
由於太亮,所以需要**調節光的強度。**如下圖所示。
在這裏插入圖片描述

最終效果類似於如下圖。
在這裏插入圖片描述

四、相機和當前視野保持一致

讓相機和當前視野保持一致。選擇Main Camera -> GameObject -> Align With View。如下圖所示。
在這裏插入圖片描述

五、剛體

在場景中創建球體,運行遊戲發現球體在半空中並沒有掉落,這時就需要給球體遊戲對象添加Rigidbody(剛體)組件來實現物理效果。
在這裏插入圖片描述
在這裏插入圖片描述
Mass:對象的質量(默認爲千克)
Drag:阻力
Angular Drag:旋轉時的阻力
Use Gravity:是否受重力影響
Freeze Position:鎖定剛體沿世界 X、Y 和 Z 軸的移動。
Freeze Rotation:鎖定剛體圍繞局部 X、Y 和 Z 軸旋轉。

有關剛體的更多信息,請參考Unity官方文檔

六、碰撞器

碰撞器組件定義對象的形狀以便用於物理碰撞。如下圖所示,當禁用球體的碰撞器(Sphere Collider)後,球體會直接穿過地面,而沒禁用碰撞器時,則會與地面發送物理碰撞效果,也就不會穿過地面。

注意:碰撞發生的條件,兩個物體必須都有碰撞體(Collider),並且其中一個需要有剛體(Rigidbody)。
在這裏插入圖片描述
關於碰撞器的詳細信息可以查看Unity官方文檔

6.1 碰撞檢測的方法

在Assets下創建Scripts文件夾,在Scripts中創建命名爲Sphere的C#腳本,並將腳本掛載到Sphere遊戲物體上。如下圖所示。
在這裏插入圖片描述

可以使用以下方法(詳情可以參考Unity官方文檔)來進行碰撞檢測,這些方法都是由Unity調用的:

    //當該碰撞體/剛體已開始接觸另一個剛體/碰撞體時,調用 OnCollisionEnter。(碰撞發生時調用)
    private void OnCollisionEnter(Collision collision) {
        
    }

    //當該碰撞體/剛體已停止接觸另一個剛體/碰撞體時,調用 OnCollisionExit。(碰撞結束時調用)
    private void OnCollisionExit(Collision collision) {
        
    }

    //對應正在接觸剛體/碰撞體的每一個碰撞體/剛體,每幀調用一次 :ref::OnCollisionStay。(碰撞過程中調用)
    private void OnCollisionStay(Collision collision) {
        
    }

6.2 碰撞信息的獲取

//當該碰撞體/剛體已開始接觸另一個剛體/碰撞體時,調用 OnCollisionEnter。(碰撞發生時調用)
    private void OnCollisionEnter(Collision collision) {
        //獲取我們和哪一個碰撞器發生了碰撞
        print(collision.collider); 
        //獲取我們碰撞的遊戲物體的名字
        print(collision.collider.name);
        //獲取我們碰撞的遊戲物體的標籤
        print(collision.collider.tag);
    }

在這裏插入圖片描述

6.3 觸發檢測

有時候我們需要做一些機關,當角色靠近機關時會觸發一些效果,這時我們就可以將碰撞器設置爲觸發器(勾選 Is Trigger)。如下圖所示。可以創建一個Cube,移除掉Mesh Filter和Mesh Renderer組件。
在這裏插入圖片描述

或者直接創建一個空遊戲物體(Create Empty),然後給它添加碰撞器(Collider),並將碰撞器的Is Trigger勾選。並可以使用Edit Collider圖標對Collider範圍進行調節。如下圖所示。
在這裏插入圖片描述

6.4 觸發檢測的方法

可以使用以下方法來進行觸發檢測,詳情參考Unity官方文檔

	//當一個遊戲物體開始進入到另一個遊戲物體觸發區域時,調用OnTriggerEnter
    private void OnTriggerEnter(Collider other) {
        
    }

    //當一個遊戲物體離開另一個遊戲物體觸發區域時,調用OnTriggerExit
    private void OnTriggerExit(Collider other) {
        
    }

    //當一個遊戲物體正在另一個遊戲物體觸發區域時,調用OnTriggerStay
    private void OnTriggerStay(Collider other) {
        
    }

6.5 觸發信息的獲取

//當一個遊戲物體開始進入到另一個遊戲物體觸發區域時,調用OnTriggerEnter
    private void OnTriggerEnter(Collider other) {
        //獲取觸發器
        print(other);
        //獲取觸發器所在遊戲物體的名字
        print(other.name);
        //獲取觸發器所在遊戲物體的標籤
        print(other.tag);
    }

在這裏插入圖片描述

七、Unity中四種燈光

關於光源的詳細信息可以參考Unity官方文檔

7.1 Directional Light

方向光對於在場景中創建諸如陽光的效果非常有用。方向光在許多方面的表現很像太陽光,可視爲存在於無限遠處的光源。方向光沒有任何可識別的光源位置,因此光源對象可以放置在場景中的任何位置。
在這裏插入圖片描述

7.2 Point Light

點光源位於空間中的一個點,並在所有方向上均勻發光。照射到表面的光線的方向是從接觸點返回到光源對象中心的線。強度隨着遠離光源而衰減,在到達指定距離時變爲零。點光源可用於模擬場景中的燈和其他局部光源。還可以用點光源逼真地模擬火花或爆炸照亮周圍環境。
在這裏插入圖片描述

7.3 Spot Light

像點光源一樣,聚光燈具有指定的位置和光線衰減範圍。不同的是聚光燈有一個角度約束,形成錐形的光照區域。錐體的中心指向光源對象的發光 (Z) 方向。聚光燈錐體邊緣的光線也會減弱。加寬該角度會增加錐體的寬度,並隨之增加這種淡化的大小,稱爲“半影”。
聚光燈通常用於人造光源,例如手電筒、汽車前照燈和探照燈。
在這裏插入圖片描述

7.4 Area Light

面光源是通過空間中的矩形來定義的。光線在表面區域上均勻地向所有方向上發射,但僅從矩形的所在的面發射。無法手動控制面光源的範圍,但是當遠離光源時,強度將按照距離的平方呈反比衰減。由於光照計算對處理器性能消耗較大,因此面光源不可實時處理,只能烘焙到光照貼圖中。
在這裏插入圖片描述

八、給場景添加火堆

8.1 給場景添加光源

給場景添加光源,並對光的顏色做一些設置。
在這裏插入圖片描述

8.2 添加火堆

在這裏插入圖片描述

給火堆添加光源,並將其設爲Prefab(預製體)。
在這裏插入圖片描述

九、Lightmapping

當我們在場景中不使用光照貼圖的話,光對場景的影響是需要實時計算的,這樣比較耗費性能。如果視野Lightmapping的話,會提前將光照信息計算好,然後烘焙成一個貼圖,並將貼圖貼到模型上,這樣在實際運行中就不需要進行重複計算了。
在這裏插入圖片描述
在這裏插入圖片描述

由於火光會有動畫效果,一閃一閃的,如果用Backed的話,效果是不變的。所以火堆這裏需要用Mixed。
在這裏插入圖片描述

觀察Scene視圖,發現其中沒有陰影。
在這裏插入圖片描述

十、使用粒子系統創建火焰

選擇Bonfire預製體,創建粒子系統。
在這裏插入圖片描述
調整形狀。
在這裏插入圖片描述

調整Start LifeTime和Start Speed
在這裏插入圖片描述

在這裏插入圖片描述
比較詳細的過程可以去看siki學院的視頻

最終效果,如下圖所示。
在這裏插入圖片描述

十一、給燈光添加閃爍效果

創建動畫
在這裏插入圖片描述
在這裏插入圖片描述

給燈光添加運動動畫效果,讓火苗左右搖擺。
在這裏插入圖片描述

整個動畫效果,如下圖所示。
在這裏插入圖片描述

十二、導航系統(尋路系統)

要使用導航系統需要進行導航網格的烘焙,在烘焙之前需要確定Environment的static是勾選上的(確保Navigation Static勾選上就行了)。
在這裏插入圖片描述

12.1 生成導航網格

在Navigation -> Bake ->Bake按鈕。可通過Agent Radius來調節代理半徑(類似於在障礙物的範圍不可進行導航)。
在這裏插入圖片描述

對於草之類的,角色應該是可以通過的,我們需要將其Navigation Static勾選取消掉,然後再重新進行烘焙。
在這裏插入圖片描述

對於不能到達的,要選中物體->Navigation->Object->AI->Navigation Area->Not Walkable。
在這裏插入圖片描述
在這裏插入圖片描述

12.2 添加導航組件

想要控制角色在網格上行走,需要給角色添加導航組件Nav Mesh Agent,可通過Radius和Height調整寬度和高度。
在這裏插入圖片描述

12.3 通過導航組件控制角色的移動

通過鼠標點擊地面,獲取鼠標點擊的點,將這個點設置爲目的地,然後讓角色到達目的地。

在Scripts文件夾下創建Hero腳本,並將其掛載到Hero遊戲物體上。
在這裏插入圖片描述

12.3.1 射線檢測

void Update() {

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

            //射線檢測
            //ScreenPointToRay:將屏幕座標轉換爲射線
            //Input.mousePosition:鼠標位置
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            //用於從射線投射獲取信息的結構。
            RaycastHit hit;
            //Physics.Raycast():向場景中的所有碰撞體投射射線,並返回有關命中對象的詳細信息,信息保存在hit中。
            if (Physics.Raycast(ray, out hit)) {
                print(hit.point);
            }


        }

    }

在這裏插入圖片描述

12.3.2 控制角色到達目的地

在Hero腳本中定義屬性public NavMeshAgent agent;並將組件Nav Mesh Agent拖入。如下圖所示。
在這裏插入圖片描述
在判斷代碼中用agent調用SetDestination()方法

 if (Physics.Raycast(ray, out hit)) {
       //print(hit.point);
       //設置目的地
       agent.SetDestination(hit.point);
}

效果,如下圖所示。
在這裏插入圖片描述

完整代碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Hero : MonoBehaviour {

    public NavMeshAgent agent;

    // Start is called before the first frame update
    void Start() {

    }

    // Update is called once per frame
    void Update() {

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

            //射線檢測
            //ScreenPointToRay:將屏幕座標轉換爲射線
            //Input.mousePosition:鼠標位置
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            //用於從射線投射獲取信息的結構。
            RaycastHit hit;
            //Physics.Raycast():向場景中的所有碰撞體投射射線,並返回有關命中對象的詳細信息,信息保存在hit中。
            if (Physics.Raycast(ray, out hit)) {
                //print(hit.point);
                //設置目的地
                agent.SetDestination(hit.point);
            }


        }

    }
}

十三、控制攝像機的跟隨

調節相機到合適的角度,創建FollowTarget腳本,並將其掛載到Main Camera遊戲物體上。
在這裏插入圖片描述

在FollowTarget腳本中定義屬性public Transform hero;保存,並在Unity中將Hero賦給hero。如下圖所示。
在這裏插入圖片描述
代碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FollowTarget : MonoBehaviour {

    //因爲跟隨目標,只需要目標的位置
    public Transform hero;

    //位置的偏移
    private Vector3 offset;

    // Start is called before the first frame update
    void Start() {
        //當前遊戲物體位置減去角色hero的位置
        offset = transform.position - hero.position;
    }

    // Update is called once per frame
    void Update() {
        //相機跟隨
        transform.position = offset + hero.position;
    }
}

效果:
在這裏插入圖片描述

十四、控制角色的動畫播放

創建Animator Controller。
在這裏插入圖片描述

編輯狀態機。
在這裏插入圖片描述
在腳本中設置參數的值進行動畫的切換。
在這裏插入圖片描述
代碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Hero : MonoBehaviour {

    public NavMeshAgent agent;

    public Animator anim;

    // Start is called before the first frame update
    void Start() {

    }

    // Update is called once per frame
    void Update() {

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

            //射線檢測
            //ScreenPointToRay:將屏幕座標轉換爲射線
            //Input.mousePosition:鼠標位置
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            //用於從射線投射獲取信息的結構。
            RaycastHit hit;
            //Physics.Raycast():向場景中的所有碰撞體投射射線,並返回有關命中對象的詳細信息,信息保存在hit中。
            if (Physics.Raycast(ray, out hit)) {
                //print(hit.point);
                //設置目的地
                agent.SetDestination(hit.point);
            }


        }
        //agent.velocity.magnitude:速度的大小
        anim.SetFloat("speed",agent.velocity.magnitude);

    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章