1. 程式人生 > >Unity官方案例--Roll a ball

Unity官方案例--Roll a ball

現在的我還是一名 Unity3d 遊戲開發初學者,所以現在都在圍繞 Unity3d 的官方案例來做練習,為此寫下一些文章作為筆記,文章中難免會有一些疏漏,有些不當之處還望指正。

專案簡介

首先玩家可以控制一個小球,去吃那些懸浮在平面上的小方塊,全部吃玩就遊戲結束了,是一個很簡單的小遊戲。

建立工程

首先我們建立一個空的工程

誒呀,圖片加載出了點問題!

環境搭建

建立地面

在 Hierarchy 介面中右鍵選擇 3D Object 中的 Plane 建立一個地面,其中將他 Inspector 介面中的 Scale(X:2,Y:1,Z:2)使地面擴大一下,這裡需要讓大家養成一個好的習慣就是物體的需要命名並且要有意義

,所以我將我們的 Plan物體名改為 Ground。

誒呀,圖片加載出了點問題!

給地面新增材質

但由於這地面太白了,再加上預設的燈光效果很亮表現得很刺眼,所以我給地面添加了一個黑色的材質,這裡有需要大家養成一個檔案分類的好習慣,所以我在我們的 Assets 資料夾中新建了一個 Materials 資料夾用來存放我們需要用到的材質檔案,選中 Materials 資料夾後右鍵選擇 Create 選項中選擇 Material 就可以建立一個材質檔案了,我將它改名為 Ground,其中在他的 Inspector 介面中將 Main Maps 中的 Albedo 的顏色調整為黑色,最後只需將這個材質檔案拖到我們場景中的地面上即可。

誒呀,圖片加載出了點問題!

新增牆

在 Hierarchy 介面中右鍵選擇 3D Object 中的 Cube 來建立四周的牆,其中在它們的 Inspector 介面中都設定 Scale(X:21,Y:1,Z:1),它們的位置分別設定為

Wall[Positon(X:0,Y:0,Z:10)],

Wall1[Positon(X:0,Y:0,Z:-10)],

Wall2[Position(X:10,Y:0,Z:0),Rotation(X:0,Y:90,Z:0)],

Wall3[Position(X:-10,Y:0,Z:0),Rotation(X:0,Y:90,Z:0)]

這裡又有一點需要大家養成的習慣就是若有相同的物體應該建立一個空的物體將他們都存放在你裡面

,所以我在 Hierarchy 中建立了一個空的物體改名為 Walls 將這四個牆存放在其中。

誒呀,圖片加載出了點問題!

設定攝像機

選擇我們場景中的 Main Camera 設定它的 Position(X:0,Y:10,Z:-10),Rotation(X:45,Y:0,Z:0)即可。

誒呀,圖片加載出了點問題!

新增 Player

在 Hierarchy 介面中右鍵選擇 3D Object 中選擇 Sphere 將它改名為 Player,設定它的 Position(X:0,Y:0.5,Z:0)

誒呀,圖片加載出了點問題!

新增 Pick Up

在 Hierarchy 介面中右鍵選擇 3D Object 中選擇 Cube 將他改名為 Pickup ,其中幾個比較關鍵的設定是 Position 的y的值最好要大於1因為過低 他會卡在地面裡,Rotation(X:45,Y:45,Z:45),還有一個特別關鍵的就是將 Box Collider 中的 Is Trigger 勾上,它的作用是做觸發器,簡單來說就是就是當兩個物體發生碰撞不產生碰撞效果,但會觸發碰撞事件(如果還不能理解,自己在 Unity 中實驗一下),然後就是多建立幾個 Pick Up 位置你們隨便放,不過這裡也有一個方法方便我們建立多個相同的物體並且還可以同步之後需要更改的設定,那就是建立 Prefab。我們在 Assets 資料夾中建立一個 Prefabs 資料夾,將我們建立的 Pickup物體拖至此資料夾,當我們看到 Pickup 物體的名稱變藍後,這就意味著我們的 prefab 建立完成,當我們需要建立 Pickup 物體時,現在只需將 prefab 中的 Pickup 拖至我們的場景中即可建立,然後就是建立一個空的物體改名為 Pickups 用來存放我們建立的 Pickup 。

誒呀,圖片加載出了點問題!

在 Inspector 介面中找到 Tag 選項後單機再選擇選項中最下方的 Add Tag... 後會來到我們的 Tags & Layers 介面,在下方會看見一個 + 標誌後單機在輸入框中輸入 PickUp 後選擇 Sa7e 後即可新增標籤

誒呀,圖片加載出了點問題!

新增 UI

在 Hierarchy 介面中右鍵選擇 UI 後再選擇 Text 選項就可以新增我們的 UI 了,我們將創建出來的 Text 檔案改名為 CountText,我們可以在 Inspector 介面中的 Text(Script) 中調整文字內容、字型、字型大小、顏色等多種屬性,我們必須要做的是將文字預設的內容給刪掉就行了,其他的設定看自己喜好了,但我們要將它至於介面的左上角該如何操作呢?我們可以在 Rect Transform 中看到一個田字格,我們單機一下它就會出現很多位置選項,但是並沒有我們所需要的左上角,這時候我們只需要一直按住鍵盤上的 Alt 鍵就會發現上面的位置選項發生了變化,之後就可以很明顯的看到左上角的選項然後我們選擇它就可以了,然後在 Canvas 資料夾下在建立一個 Text 改名為 WinText 用來儲存我們的勝利文字的,也要將文字內容刪去,位置居中預設就行了,其他設定自定義。

誒呀,圖片加載出了點問題!

遊戲執行

從這兒起就要開始我們的指令碼編寫了,現在 Unity3D 主流指令碼編輯語言是 C#,不過像我現在用的 Unity 3D 2018.2的版本指令碼語言只剩下了 C#,所以推薦大家寫指令碼還是用 C# 來編寫,學過的朋友理解起來就很方便了,沒學過的朋友可以從網上找找相關教學視訊瞭解一下,不過有一點程式設計經驗的其實理解起來還是很簡單的,我會在下面指令碼中寫下相應註釋的,方便一些初學者理解的。

Unity官方有一個指令碼文件,在遇到什麼不懂得問題或者需要完成什麼操作指令碼忘了怎麼寫時可以進行查閱。

Unity官方指令碼文件

Player 的移動

選擇我們的 Player 物體檔案,在 Inspector 的下方點選 Add Component 在其中的輸入框中輸入 Rigidbody 回車確定選擇,即可給我們的 Player物體新增剛體元件,剛體元件的用處就是給物體新增物理屬性的,其中我們將 Angular Drag 的值改為0,意思是取消小球的摩擦力。

誒呀,圖片加載出了點問題!

還是點選 Add Component 在輸入框中輸入 PlayerController 選擇 New script 再點選下方的 Create and Add 即可給我們的 Player 掛載指令碼了,然後我在我們的 Assets 資料夾中建立一個 Scripts 資料夾用來儲存我們遊戲中的所有用到的指令碼檔案,將我們剛剛建立的指令碼檔案拖進此資料夾。

誒呀,圖片加載出了點問題!

雙擊我們的指令碼檔案,就打開了我們預設的指令碼編輯器來編輯我們的指令碼,我使用的是 visual studio 2017。

誒呀,圖片加載出了點問題!

下面就開始編輯我們的指令碼,來完成小球 Player 的移動。

指令碼檔名:PlayerController

程式碼如下:

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

public class PlayerController : MonoBehaviour {

//public 公共的,會使此變數顯示在 unity 編輯器中方便我們調節數值
//此處定義一個 speed 變數是為了控制 Player 的運動速度
public float speed;

public void FixedUpdate()
{
    //獲取橫向要使 Player 位移的量
    float moveHorizontal = Input.GetAxis("Horizontal");
    //獲取縱向要使 Player 位移的量
    float moveVertical = Input.GetAxis("Vertical");

    //定義一個新的三維向量,來確定 Player 的執行方向
    Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

    //給 Player 新增一個力使其運動,力的大小我們可以在 Unity 編輯器中編輯
    //這裡再乘以一個Time.deltaTime是為了使 Player 完成的是每秒移動 speed 米,而不是每幀 speed 米,你們可以試試將這個Time.detalTime刪去後 Player 的執行效果
    GetComponent<Rigidbody>().AddForce(movement * Time.deltaTime * speed);
  }
}

指令碼寫完後記得儲存一下,再來到我們的 Unity 編輯器中,選擇 Player 物體後你會發現在指令碼中多出來一個 Speed 項,這就是我們之前定義它為 public 公共項的作用了,我們將他設定值為120,然後點選 Unity 編輯器上方的播放按鈕執行,之後我們就可以按 W、A、S、D 鍵來控制我們的 Player 運動了。

誒呀,圖片加載出了點問題!

相機跟隨

讓相機跟隨 Player 一起運動,使相機和物體為關聯關係但不是父子級別的關係,若是父子關係由於 Player 是球體運動時會滾動,所以相機也會隨著 Player 的滾動而滾動,這不是我們需要的效果。

選擇 Main Camera 物體用上文同樣的方法新增 CameraController 指令碼檔案,然後拖至 Scripts資料夾中存放,雙擊指令碼檔案進行編輯。

指令碼檔名:Camera Controller

程式碼如下:

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

public class CameraController : MonoBehaviour {

//建立一個公共的遊戲物體,在Unity編輯器中可以將一個物體拖至指令碼處的 player 的框中,指令碼中就可以直接獲取此物體,就不需要查詢的步驟
//此處的功能就是將我們需要攝像機跟隨的物體新增進去,也就是 Player
public GameObject player;

//建立一個變數,用來儲存攝像機與物體 Player 未知的預設的差值
private Vector3 offSet;

private void Start()
{
    //我們給 offSet 賦值,值的的大小為攝像機的 Position 三維向量的值減去 物體 Position 三維向量的值,也就是相機與物體之間的距離
    offSet = transform.position - player.transform.position;
}
private void LateUpdate()
{
    //使我們的相機的位置永遠位於物體的位置+ offSet 這個差值
    transform.position = player.transform.position + offSet;
}
}

指令碼編寫完後我們來到 Unity3D編輯器,選擇 Main Camera 物體檔案後會發現在指令碼下方出現了一個叫 Player 的項,我們可以吧 Player 物體拖至後方的框子中,然後執行移動 Player 就會發現攝像機也在跟隨著 Player 一起運動。

誒呀,圖片加載出了點問題!

Pick Up 的自轉

這次我們要完成的是將 Pick Up 旋轉起來。

選擇 Prefabes 中的 Pickup 物體,新增名為 Rotation 的指令碼檔案後拖至 Scripts 資料夾中,然後雙擊我們的指令碼檔案編輯我們的指令碼。

誒呀,圖片加載出了點問題!

指令碼檔名: Rotation

程式碼如下:

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

public class Rotation : MonoBehaviour {
private void FixedUpdate()
{
    transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
}
}

回到 Unity 編輯器執行我們的遊戲就可以看到 Pickup 開始自己轉了起來。

UI 的控制

開啟我們的 PlayerController 指令碼,我們在其中編輯 UI 的控制指令碼。

指令碼檔名:PlayerController

程式碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//切記一定要呼叫 UI
using UnityEngine.UI;

public class PlayerController : MonoBehaviour {

//public 公共的,會使此變數顯示在 unity 編輯器中方便我們調節數值
//此處定義一個 speed 變數是為了控制 Player 的運動速度
public float speed;
//獲取我們建立的 CountText
public Text countText;
//獲取我們的建立的 WinText
public Text winText;

//定義個變數記錄我們的得分
private int count;

public void Start()
{
  //呼叫我們的自定義函式 SetCount
    SetCount();
    //初始化我們的winText裡的文字為空,功能相當於隱藏了此文字
    winText.text = "";
}

public void FixedUpdate()
{
    //獲取橫向要使 Player 位移的量
    float moveHorizontal = Input.GetAxis("Horizontal");
    //獲取縱向要使 Player 位移的量
    float moveVertical = Input.GetAxis("Vertical");

    //定義一個新的三維向量,來確定 Player 的執行方向
    Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

    //給 Player 新增一個力使其運動,力的大小我們可以在 Unity 編輯器中編輯
    //這裡再乘以一個Time.deltaTime是為了使 Player 完成的是每秒移動 speed 米,而不是每幀 speed 米,你們可以試試將這個Time.detalTime刪去後 Player 的執行效果
    GetComponent<Rigidbody>().AddForce(movement * Time.deltaTime * speed);
}

private void OnTriggerEnter(Collider other)
{
    //當 Player 碰到了物體的 Tag 名為 PickUp 的物體時執行 if 的程式
    //為何要加 Tag呢?因為 Player 在執行中會碰到很多東西,比如:地面、牆壁,這些都不是我想要銷燬的物體,所以我們給我們需要銷燬的物體添加個“名字”
    if (other.gameObject.tag == "PickUp")
    {
        //銷燬 Pickup
        Destroy(other.gameObject);
        //分數+1
        count += 1;
        //更新 CountText 的文字內容
        SetCount();
        //當我們的分數大於我們定義的 Pickup 的個數(因為我建立了8個 Pickup,所以我的是 count >= 8)
        if (count >= 8)
        {
            //給我們的 WinText 的文字內新增獲勝內容,其功能也就是顯示獲勝資訊
            winText.text = "You Win!";
        }
    }
}

public void SetCount()
{
    //使我們的 CountText 顯示分數,其格式為 Count:[分數]
    countText.text = "Count:" + count;
}
}

儲存我們的程式碼並開啟 Unity 編輯器,選擇 Player 物體後將我們的建立的 CountText 和 WinText 物體拖至 PlayerCOntroller 指令碼下方相對應的地方,然後執行我們的遊戲,此時我們的 Roll a ball 的遊戲已經制作完成了。

總結

  1. 我們寫完程式碼一定要記得將我們需要使用到的物體掛上,不然執行時沒有效果或者報錯。
  2. Tag 的新增一定要注意自己的大小寫,在指令碼新增中判斷物體的 Tag 時一定要與我們建立的 Tag 完全一樣。
  3. 其中游戲的實現可能會有很多種方法,自己可以翻閱 Unity 官方的指令碼文件然後去嘗試使用其他的一些方法來實現我們的遊戲。
  4. 如果自己有能力,可以嘗試改編遊戲加入自己的想法,然後一一去實現它,這樣對於我們的遊戲開發很有幫助。
  5. 遊戲開發其實很簡單,但是如果想要真正的在這個領域成為“大牛”級別的人物,還需要很多很多的努力,我們一起堅持,一起努力!

歡迎大家收藏我的部落格,我會努力更新更多的作品的,給自己加個油!