2017年3月20日 星期一

[Unity 教學]第三課 Method 方法



課堂目標:認識Method(函式、方法)、撰寫註解,透過function將程式寫得更容易閱讀。
影片範例
  • 學會什麼叫做 Method (方法),並開始整理程式碼。
  • 讓Update變得更乾淨。
  • 開始學會編寫註解 // 、/* */
  • 在 main.cs 內新增一個方法叫做 restart 
  • 在 unity 裡面新增一個按鈕,點擊他會執行 restart。
  • 在 restart 加入一些程式碼,使 restart 執行時會把玩家送回起點。
  • 在canvas上面新增訊息,紀錄遊戲進行時間。
  • 在restart裡面加入時間會重算的功能。
什麼是 Method 方法,微軟C#手冊是這麼描述方法的:
  1. 方法是包含一系列陳述式的程式碼區塊。
  2. 程式會造成呼叫方法並指定任何所需的方法引數來執行陳述式。
看不太懂嗎?沒關係,我們透過 實作 的方式理解一下方法的用途。
開始囉!

首先進回到第二課的部分 [連結
上一次上課的完整程式碼如下....
using System.Collections.Generic;
using UnityEngine;

public class main : MonoBehaviour
{
 public float speed; 
 GameObject player;
 GameObject cameraObj;
 Vector3 camera2player;

 // Use this for initialization
 void Start ()
 {  

  player = GameObject.Find ("player");
  cameraObj = GameObject.Find ("cam");
  camera2player = cameraObj.transform.position - player.transform.position;
  speed = 0.5f;
 }

 // Update is called once per frame
 void Update ()
 {
  cameraObj.transform.position = player.transform.position + camera2player;

  if (Input.GetKey ("w")) {
   player.transform.position+= new Vector3 (0, 0, speed);
  }
  if (Input.GetKey ("s")) {
   player.transform.position += new Vector3 (0, 0, -speed);
  }
  if (Input.GetKey ("a")) {
   player.transform.position += new Vector3 (-speed, 0, 0);
  }
  if (Input.GetKey ("d")) {
   player.transform.position += new Vector3 (speed, 0, 0);
  }
 }
}
其實這段程式碼內已經包含了【兩個方法】,
分別是Start跟Update。這Start這個方法,在我們執行Unity時會呼叫一次
而Update這個方法,是在Unity執行時不斷的呼叫。

我們現在來建立一個我們自訂的方法,把它命名為【Control】 
並放在update的下面。

如果不懂Contorl是寫在那裡的,可能夠過下面這段影片會更清楚
void Contorl(){
   //這裡就是Contorl這個方法放置程式碼的地方!
}
這樣我們就建立了一個方法叫做Contorl
我們希望這個Contorl可以取代我們之前在Update裡面跟控制player有關的程式碼,
所以我們Contorl內將程式碼改寫一下變成下面這樣。
    void Contorl()
    {
        //這裡就是Contorl這個方法放置程式碼的地方!
        if (Input.GetKey("w"))
        {
            player.transform.position += new Vector3(0, 0, speed);
        }
        if (Input.GetKey("s"))
        {
            player.transform.position += new Vector3(0, 0, -speed);
        }
        if (Input.GetKey("a"))
        {
            player.transform.position += new Vector3(-speed, 0, 0);
        }
        if (Input.GetKey("d"))
        {
            player.transform.position += new Vector3(speed, 0, 0);
        }
    }
並且將原本update內的程式碼,改寫成下面這樣
 void Update()
    {
        cameraObj.transform.position = player.transform.position + camera2player;
        player.transform.position += new Vector3(0, 0, 0.6f);
        Contorl();
    }
上述步驟的影片如下:


改成這樣後代表當Unity執行Update這個方法時,
他會去執行Contorl這個方法。

接下來我們在創立一個方法叫做cameraFollow,
然後把Update內負責攝影機跟隨的程式碼剪下貼進去。
  void CameraFollow()
    {
        cameraObj.transform.position = player.transform.position + camera2player;
    }
然後我們在創立一個方法叫做playerGo,
然後把Update內負責讓player在遊戲執行後,會一直往前跑的程式碼剪下貼進去。
 void PlayerGo()
    {
        player.transform.position += new Vector3(0, 0, 0.6f);
    }
最後,我們再把剛剛建立的camerFollow跟playerGo放到update裡面去,
使這兩個方法會被呼叫。

現在,你的Update會看起來像下面這樣
    void Update()
    {
         CameraFollow(); 
         PlayerGo();
         Contorl(); 
    }

 上述步驟的影片


改寫成這樣之後,我們的Update看起來就變得非常清爽!
只剩下三個方法在裡面。

這樣的好處是我們可以很容易看出在Update這段程式碼,
進行了那些事情。

就以本教學為例,我們進行了
CameraFollow(); //攝影機更隨
PlayerGo();        //角色持續往前衝
Contorl();          //透過鍵盤控制角色前進後退

完整main.cs程式碼(包含註解)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class main : MonoBehaviour
{
    public float speed;     //遊戲速度
    GameObject player;      //玩家物件
    GameObject cameraObj;   //攝影機物件
    Vector3 camera2player;  //攝影機與玩家相對距離

    // 遊戲起始
    void Start()
    {
        player = GameObject.Find("player");
        cameraObj = GameObject.Find("cam"); //遊戲攝影機我們有從新命名為cam
        camera2player = cameraObj.transform.position - player.transform.position;
        speed = 0.5f;
    }

    // 遊戲主迴圈
    void Update()
    {
        cameraFollow();
        PlayerGo();
        Contorl();
    }

    //攝影機跟隨
    void cameraFollow()
    {
        cameraObj.transform.position = player.transform.position + camera2player;
    }

    //角色持續往前衝
    void PlayerGo()
    {
        player.transform.position += Vector3.forward * speed;
    }

    //遊戲控制
    void Contorl()
    {
        if (Input.GetKey("w"))
        {
            player.transform.position += new Vector3(00, speed);
        }
        if (Input.GetKey("s"))
        {
            player.transform.position += new Vector3(00-speed);
        }
        if (Input.GetKey("a"))
        {
            player.transform.position += new Vector3(-speed, 00);
        }
        if (Input.GetKey("d"))
        {
            player.transform.position += new Vector3(speed, 00);
        }
    }
}
下載連結

課堂挑戰:
  • 當玩家進行遊戲超過10秒時,遊戲自動前進的速度變成初始的一半速。

4 則留言:

  1. 最下面的影片要有權限才能看耶...
    另外建議程式碼可以上色 會更清楚
    上網搜尋:blogger 顯示程式碼

    回覆刪除
    回覆
    1. 影片權限已經調整好了唷!感謝回報問題(並成為本站第一個留言者)
      程式碼上色部分我在研究看看,謝謝提醒囉!

      刪除
  2. 课堂挑战这个想不出来 能给出答案吗

    回覆刪除
    回覆
    1. 首先把挑戰分成兩個部分:
      1. 試著寫個計時器吧! 目的是用來判斷遊戲是否到達十秒了?
      2. 試著寫個 Method 方法 ,剛方法被觸發時會將 speed*=0.5f

      刪除