文章分類

顯示具有 Unity 標籤的文章。 顯示所有文章
顯示具有 Unity 標籤的文章。 顯示所有文章

2018年1月19日 星期五

[Unity] Unity入門教學(二) - 當物件撞上了物件

Unity入門教學(二)

在上次的物件移動中,球體之所以可以在地板上移動是因為球體跟地板這兩個物件中都帶有碰撞器(Collider)的零件,這個零件可以使物件實體化但並不具物理特性.

所有實體化的物件可以跟有剛體的物件產生碰撞的,預設的所有碰撞並不會觸發任何其他行為,在上一次的練習裡,一開始球體是會往下掉到地板上,當球體接觸到地板時,這兩者也只是接觸著而已,並沒有其他任何事情發生.

這次我們試著加入新的物件,讓球體碰撞該物件後,讓該物件消失.

首先在場景中新增一個Cube物件 (Game Object > 3D Object > Cube),把Position改為(2, 1, 2),或隨個人喜好.


接著在Cube裏加入一個Script,就命名為CollideCube好了.

開始編輯Script (滑鼠雙擊),把預設的Start跟Update兩個方法移除後,加入一個void OnCollisionEnter(Collision collision)的方法.

這個方法也是官方定義的,功能是用來偵測Collider的碰撞,這個方法通常是使用在被碰撞物件的身上. 當物件被碰撞時,會執行方法裡面的程式碼. 我們在裡面寫了一行Destroy(gameObject),Destroy是用來銷毀物件用,需要將你想銷毀的物件放進去執行就可以了,要注意的是放進去的資料型態一定是要GameObject才能執行. 試著存檔後執行看看吧.

附帶說明一下,OnCollision這系列會有三種方法可以使用,分別是OnCollisionEnter, OnCollisionStay, OnCollisionExit,分別代表著接觸到碰撞體的瞬間、碰撞後未分開及與碰撞體分開的瞬間這三種情況,可以視自己的需求使用. 在這邊也可以試試看把OnCollisionEnter改為OnCollisionExit,執行看看會有什麼不一樣吧.

大家在執行時有沒發現到,當我們使用碰撞使物件消失時,會有一點點的延遲產生,因為必須先讓球體撞到方塊後才會觸發摧毀方塊,這樣在這個遊戲上顯得有點不流暢,那麼該怎麼處理這種狀況呢?

我們先前提到Collider這個零件可以讓物件實體化,在Collider裡面有個設定叫做觸發器(IsTrigger)的選項,當這個選項被勾起時,這個物件將不再被實體化,而是變成了一個可觸發範圍,也就是這個物件會變成可被穿透的.

當觸發器被勾選時,原本在程式裡面所使用的OnCollision系列的方法自然就失效了,因為已經撞不到了,那該怎麼辦呢?? 官方另外提供了OnTrigger系列的方法可以使用,跟OnCollision系列一樣分為三個OnTriggerEnter、OnTriggerStay及OnTriggerExit,分別代表著剛接觸到這個觸發範圍的瞬間、停滯在觸發範圍內及離開觸發範圍的瞬間這三種狀況,在這裡,就讓大家自己試著去把碰撞改為觸發,親自體驗一下兩者的不同吧.


2018年1月18日 星期四

[Unity] Unity入門教學(一) - 讓物件動起來

Unity入門教學 (一)

在Unity的世界裡,每個專案(Project)都是由一個或多個場景(Scene)所組成,而每個場景則是由一個或多個物件(GameObject)所構成.

現在就讓我們來建立一個新的專案吧!

啟動Unity後,會看到如下圖的畫面.

點擊右上角的New

輸入專案名稱,指定好專案存放位置就可以點擊Create project建立專案了.

有了專案後,Unity會先幫我們建立一個預設的場景,在3D專案中會有一個定向光(Directional light)及一個攝影機(Main camera).

點擊場景中的物件,可以看到物件的內容(Inspector),也可以對物件內容做修改.

在物件中可以加入各式各樣的零件(Component),每個零件都有不一樣的功能,而每個物件一定有一個最基本的零件存在且不可移除,它就是Transform.

Transform的功能是用來表示每個物件在場景中的位置(Position)、旋轉角度(Rotation)以及大小(Scale).


定向光及攝影機都是由Transform加上其他零件所組成,比方說定向光 = Transform + light


接下來,讓我們試著建立新物件吧!

在Hierarchy裏點選右鍵 > 3D Object > Plane


一個3D平面就產生了,接著再產生一個Sphere

由於這兩個物件的Position是一樣的,所以會看到兩個物件重疊在一起,試著把Sphere的position中的Y值改成1吧,應該會看到下圖的畫面

這時候試著點擊畫面上方的播放鍵,會發現....完全沒事情發生呢,因為目前的物件都只有外型跟碰撞器,並沒有其他零件讓它們可以有其他功能,所以接下來我們要試著要在物件裡加入新的零件了.

點擊Hierarchy中的Sphere物件,在它的Inspector點擊下方的Add Component,幫Sphere加入剛體(Rigidbody).





再點一次播放鍵試試看

現在Sphere會直接往下掉了,這是由於在它身上我們加入了剛體,這個零件主要是讓物件具有物理特性,像是重力、質量、阻力、受力及碰撞等等.

再來進入這篇的主題了,要如何讓物件動起來呢?答案是我們可以透過將腳本(Script)當成零件加進物件中,讓物件照著我們寫的腳本去動作就可以了.

在Sphere中加入新的零件,我們這次選擇New Script


命名腳本名稱及使用的程式語言,Unity目前只支援C Sharp及 Java Script兩種,筆者使用的是C Sharp. 點選Create and Add.


Inspector下方就多了一個Script 零件了


接著我們要開始編輯剛剛產生的腳本檔案,產生出來的檔案都會在Project這個視窗底下的Assets區裡面,我們可以看到剛產生的腳本,請點擊兩下開啟.


順利開啟後會看到下圖的程式碼,這是每個Script產生時Unity會預先寫好的東西.


接著就要開始寫腳本了,沒有程式基礎的朋友們也不用太緊張,我們會一步一步地教學跟說明喔.

在寫任何腳本前,先思考一下這個腳本到底要做什麼? 想清楚後,依序在腳本內寫好每個步驟,腳本就完成了,就如同現實生活中你想做的每件事,其實都是有分解動作的,比方說你想喝一杯水,那麼首先你必須先取得這杯水,再用手拿起來往嘴巴倒或是透過吸管吸取,最後吞嚥. 你可能覺得這不是大家都知道的事嗎? 沒錯,這是大家都知道的事,也就是所謂的邏輯,邏輯並沒有你想的那麼困難,你只是被邏輯這兩個字所誤導了.

我們現在希望能夠 讓玩家透過鍵盤去操控Sphere,讓它能在Plane上移動,那麼這件事會需要有哪些步驟呢??

1. 取得Sphere的剛體:剛體代表著Sphere的物理特性,也就是要對它施力的話,必須是施力在剛體上.

2. 取得外部輸入:取得鍵盤按鍵輸入的數據,才能去計算到底要對剛體施多大的力.

3. 對剛體施力:透過前面取得的零件跟數據,計算出力的大小並施加在剛體上.

將動作分解好後,一步一步做做看吧!

1. 取得Sphere的剛體



首先,先大概知道一下每個腳本是由一個或多個Class組成,而每個Class底下可以有一個或多個Method. Class跟Method的內容都是被定義在大括弧{}內. Method可以設定被呼叫後會不會回傳結果,需要的話就會在Method名稱前面加上回傳結果的資料型態,不需回傳的話就設定為void即可.

在上圖中就可以看到有一個叫MoveSphere的class,而裡面包含了一個全域變數rb跟一個不需回傳結果的方法Start.

什麼是全域變數呢?? 簡單來說,宣告在class內且method外的變數,都可以讓class內的method使用,所以我們叫它做全域變數.

void Start() 這個方法是官方定義的腳本生命週期的其中一個,其他生命週期中的方法可以參考這裏. void Start() 這個方法只有在物件初始化完畢後會執行一次,所以我們可以在void Start()裡面去取得剛體. 取得的方法是gameObject.GetComponent<Rigidbody>(),這裡需要注意的地方有三個:

1. 在腳本中小寫的gameObject代表著掛載這個腳本的物件,所以當用gameObject.getComponent<Rigidbody>()時,是指取得目前這個物件底下的Rigidbody零件.

2. getComponent<>()的<>裡面是可以替換成各種零件,像是getComponent<Rigidbody>(),getComponent<Sprite>().

3. 如果想取得的零件是script,<>裡面需要放置script name,像是getComponent<MoveSphere>();

2. 外部輸入

透過Input.GetAxis("Horizontal") 及 Input.GetAxis("Vertical"),我們可以取得水平及垂直軸的輸入狀況,預設是透過鍵盤的上下(垂直)左右(水平)四個方向鍵來輸入,取得的輸入數值範圍會介於-1~1之間,型態是float,就是你持續按了上方向鍵時,輸入得值最大就是1,反之是-1.


在上圖中,我們先建立一個void FixedUpdate() 這個方法,這個方法也是官方定義的,這個方法會週期性的執行,間隔時間預設是0.02sec,可以透過Edit > Project Setting > Time去修改.


接著我們在FixUpdated裡面宣告了兩個float的變數,分別去接收Input.GetAxis得到的值,得到後再新增個三維向量變數 Vector3 movement,這個Vector3是要拿來當作對剛體施加的力,由於是3D,所以我們把水平軸的值放到Vector3的x,垂直軸則放在Vector3的z,注意喔,不是放在y而是z.

3. 施力

我們先設定一個全域變數speed,資料型態是int,且在前面加上public,這樣代表這個全域變數是對外開放的,一但設定了之後,在Inspector裏就可以指定該變數的值,如下圖.


再來就是對剛體施力了,我們先前已經先拿到了剛體rb,所以直接輸入rb.AddForce(),再把施力大小放進()裏,就完成了,在上一個步驟我們定義力量大小是movement,將movement乘上speed放進()裏,在Inspector設定剛剛的speed後存檔並播放,試著使用方向鍵移動看看吧!

最後完成的程式碼如下圖.



2017年6月4日 星期日

[Unity]筆記: 目標直線追隨移動

目標直線追隨移動

在Unity中,要做到對目標追隨移動有兩種基本方法可以使用,Lerp及MoveTowards.

在Vector系列的類別中,都內含著上述兩個方法.

Lerp

用來取得兩點間線性插值的方法,語法為new Vector3 newPosition = Vector3.Lerp(Vector3 起點, Vector3 終點, float 比例) .

其中比例的值為一個浮點數,範圍為0~1,可以想像成0%~100%,當比例 <= 0 時,相當於不動,即newPosition = 起點; 反之,如果比例 >= 1時,newPosition = 終點. 所以一般使用時將比例控制在0~1之間,可以適當地得到兩個點之間某個比例的位置.

MoveTowards

用來取得兩點間的某個點的位置,語法為new Vector3 newPosition = Vector3.MoveTowards(Vector3 起點, Vector3 終點, float 距離) .

其中距離的值為一個浮點數,無範圍限制,主要就是看你希望每一次期望取得離終點多遠的距離.


下面是利用Lerp來實作的一個簡單的物件追隨範例:

public class CameraFollower : MonoBehaviour {

    public Transform target;
    private float smoothing = 5f;
    private Vector3 offset;
    // Use this for initialization
    void Start () {
        offset = transform.position - target.position;
    }
    
    // Update is called once per frame
    void FixedUpdate () {
        Vector3 camPosition = target.position + offset;
        transform.position = Vector3.Lerp (transform.position,camPosition,smoothing*Time.deltaTime);
    }
}



2017年5月30日 星期二

[Unity]筆記: 2D碰撞

2D碰撞

在遊戲中,碰撞行為是不可或缺的,而在Unity中,我們可以透過內建的幾個簡單元件配合特定的script method就可以達成.

在碰撞行為中,可以分為主動與被動,就是衝撞與被撞的物件,而這兩者在實作上是有區別的.

在衝撞物件中,我們需要在物件的inspector中加入兩個新元件,Rigidbody2D與Collider,這兩個元件都可以在Physics 2D中找到.

Rigidbody2D: 

即2D剛體,用來處理物理運算用的元件,如重力,摩擦係數及碰撞等等. 

在剛體中有個Body type,是用來決定碰撞的主要因素,Body type可以分為下列三種:

1. Dynamic:

    Dynamic具所有物理特性(Gravity, Forces),可以碰撞任何BodyType,相對的資源消耗       就會比其他body type來得多.

2. Kinematic:

    Kinematic不具Gravity及Forces等特性,僅能碰撞Dynamic type,無法碰撞Kinematic       及Static type,所以這種type消耗的資源相對低很多.

3. Static:

    Static大概就是等同於沒有剛體,也就是僅能碰撞Dynamic type.

Collider2D: 

碰撞器,用來定義可碰撞範圍及碰撞器材質等,在Unity中預設了Box Collider 2D, Circle Collider 2D, Edge Collider 2D及Polygon Collider 2D供開發者使用,而這幾種Collider的差別只在於預設範圍不同而已.


被撞的元件中,僅僅只需要碰撞器及一小段script就可以做到被碰撞的效果,該script method 如下:

(當碰撞器一開始發生碰撞時)
void OnCollisionEnter2D(Collision2D collision){
}

(當碰撞器保持在碰撞狀態)
void OnCollisionEnter2D(Collision2D collision){
}

(當碰撞器剛脫離碰撞時)
void OnCollisionEnter2D(Collision2D collision){
}

2016年9月24日 星期六

[Unity] 筆記: 2D物件移動

Unity物件移動

在Unity中,有兩種方式可以使物體移動,一種是對物體施力,而另一種則是直接強制改變座標位置 .

利用2D剛體(Rigidbody2D)移動物件 (施力)


Rigidbody2D.AddForce(Vector2 Force,ForceMode2D mode)


對物件的中心(世界座標)施加力量使物件移動,該移動力量會受剛體質量(Mass)跟線性阻力(Linear Drag)以及其接觸到的碰撞器(collider)摩擦係數所影響,也就是說當質量阻力及摩擦係數越大時,所需施加的力量也需要更大.


        
在方法中的參數Force,是一個二維向量(具有方向的量),在程式中可以用 new Vector(x,y)來宣告,其中x,y都是float.

另一個參數ForceMode2D是個ForceMode2D型別的參數,可分為Force及Impulse兩種,在程式中直接以ForceMode2D宣告就可以.

Force mode: 對物件施加具方向性的力,同AddForce基本定義.
Impluse mode: 對物件施加一個脈衝力,該力量一樣具有方向性.

ForceMode2D是optional參數,沒有加入這個參數時,預設就是Force mode.

Script範例:

float horizontal = Input.GetAxis ("Horizontal");

rb2D.AddForce (new Vector2(horizontal,0));
rb2D.AddForce (new Vector2(horizontal,0),
ForceMode2D.Force);
rb2D.AddForce (new Vector2(horizontal,0),ForceMode2D.Impulse);


Rigidbody2D.AddForceAtPosition(Vector2 Force, Vector2 Position, ForceMode mode)


從世界座標中的特定位置(Position)與物件中心形成一個虛擬力矩,然後對特定位置施加力量造成物件移動同時也產生扭力使物件旋轉,移動力量跟AddForce一樣會受質量跟阻力及碰撞器摩擦係數影響,而旋轉的扭力會受到角度阻力(Angular Drag)所影響.


在方法中的參數Force,是一個二維向量(具有方向的量),在程式中可以用 new Vector(x,y)來宣告,其中x,y都是float.

Position也是一個二維向量,不過在這邊只用來表示位置,並不具方向性,在程式中可以用 new Vector(x,y)來宣告,其中x,y都是float.

ForceMode2D的部分與AddForce中一樣.

Script範例:

float horizontal = Input.GetAxis ("Horizontal");

rb2D.AddForceAtPosition (
new Vector2(horizontal,0),new Vector2(-1f,1f))
rb2D.AddForceAtPosition (new Vector2(horizontal,0),new Vector2(-1f,1f)
                         ,ForceMode2D.Force);
rb2D.AddForceAtPosition (new Vector2(horizontal,0),new Vector2(-1f,1f)
                         ,ForceMode2D.Impulse);     



Rigidbody2D.AddRelativeForce(Vector2 Force, ForceMode mode)


與AddForce作用相同,唯一不同的是AddForce, AddForceAtPosition都是對世界座標系統作用,而AddRelativeForce則是對本地座標系統作用.下圖左方為物件旋轉前,右圖為旋轉後,當物件旋轉後,本地座標會跟著旋轉,此時施力方向與旋轉前就不一樣了.



在方法中的參數Force,是一個二維向量(具有方向的量),在程式中可以用 new Vector(x,y)來宣告,其中x,y都是float.

另一個參數ForceMode2D是個ForceMode2D型別的參數,可分為Force及Impulse兩種,在程式中直接以ForceMode2D宣告就可以.

ForceMode2D的部分與AddForce中一樣.

Script範例

float horizontal = Input.GetAxis ("Horizontal");

rb2D.AddRelativeForce (new Vector2 (horizontal, 0));
rb2D.AddRelativeForce (new Vector2 (horizontal, 0), ForceMode2D.Force);
rb2D.AddRelativeForce (new Vector2 (horizontal, 0), ForceMode2D.Impulse);



Rigidbody2D.AddTorque(float torque, ForceMode2D mode)


對物件的世界座標中心Z軸(因為是2D平面)施加扭力,torque > 0 時,會逆時針扭動,反之則順時針扭動.

在方法中的參數Torque,是float.

ForceMode2D的部分與AddForce中一樣.

Script範例

float horizontal = Input.GetAxis ("Horizontal");

rb2D.AddTorque (horizontal*2);
rb2D.AddTorque (horizontal*2 , ForceMode2D.Force);
rb2D.AddTorque (horizontal*2 , ForceMode2D.Impulse);



Rigidbody2D.MovePosition(Vector2 Position)

透過將物件直接位移到指定位置達到移動的效果,不受剛體其他參數影響.


Rigidbody2D.MoveRotation(float Angular)

透過改變物件角度達到旋轉的效果,不受剛體其他參數影響,Angular > 0 時,物件旋轉方向為逆時針,反之為順時針.


利用Transform移動物件 (改變座標)

Transform是每個物件都會有的元件,其中包含了物件的位置(Postion),旋轉角度(Rotation)以及大小(Scale).

transform.position

改變或取得物件座標,回傳及代入值皆為三維向量(Vector3),在處理2D物件時,記得保持z軸座標.

Script範例

Debug.Log(transform.position); //印出物件目前位置
transform.position = new Vector3(1,1,0); //給予物件新的位置

transform.position.set(float x, float y, float z)


改變物件座標,直接給定三個軸向的位置即可.

Script範例

transform.position.set(1,2,0);

transform.position.axis

用來取得物件位置的某個軸向數值,取得的數值為float型態.

Script範例

float x = transform.position.x;
float y = transform.position.y;
float z = transform.position.z;

transform.rotation

改變或取得物件的旋轉參數,回傳及代入值皆為四元數(Quaternion).

Script範例

Debug.Log(transform.rotation);
transform.rotation = Quaternion.Euler(1,1,1);
transform.rotation = Quaternion.Euler(new Vector3(1,1,1));


transform.RotateAround(Vector3 Point, Vector3 Axis, float Angle)

使物件針對某個點(Point)上的某個軸(Axis)旋轉,Point及Axis皆為三維向量,Angle為float.

Script範例

transform.RotateAround (new Vector3 (1, 1, 0), new Vector3 (0, 0, 1), horizontal);

2016年7月21日 星期四

[Unity][PlayMaker] 練習九 : 資料型態轉換

資料型態


這邊我們先簡單介紹一下先前以及這次會用到的資料型態 :

int (整數) :就是沒有小數點的數字啦~int的範圍可以在-2147,483,648 ~ 2147,483,647之間

float (浮點數) :就是最多可以到小數點第六位的數字,範圍在1E-37 ~ 1E37之間

vector3 (3維向量) :就是有XYZ三個軸的向量,無限制範圍 ((吧?

vector2 (2維向量) :就是只有XY兩個軸的向量,應該也是無限制範圍((吧?

(向量 :具有方向及大小的量,你試著畫出X = 1, Y = 2的座標,然後從(0,0)連過去(1,2),連出來的那條線就是向量了,具方向又有長度)

String (字串) :就是文字.

boolean (布林值) :只有包含兩個狀態的值,例如true/false,yes/no或是on/off.


資料轉換練習

這次的練習我們會用到整數與字串的轉換,再將字串顯示在畫面上用來做計數器,請大家試著照著影片練習一下吧~




試著應用到其他不同地方吧~下次再會XD

[Unity][PlayMaker] 練習八 : 物體碰撞

碰撞與觸發

先前我們提到過觸發,是指當物件進入某個有形或無形的範圍時的進,出及停留可以自動發動某些我們期望的行為.

那麼碰撞呢?碰撞是指兩個無法互相穿透的物件互相接觸到時,就叫碰撞. 碰撞時依然可以觸發某些我們期望的行為,而除了這些行為以外,還會視這兩個物件的剛體設定產生一些物理影響,比方說A物件比B物件重,當A物件移動去推擠B物件時,B物件就會被A物件推著走.


物體碰撞練習


接著請試著照影片練習一下簡單的的碰撞行為吧~





記得要練習才是王道~不要看過就算了QQ

[Unity][PlayMaker] 練習七 : 預製物件

預製物件

預製物件,顧名思義就是事先準備好在場景中所需要使用到的物件,包括物件的相關動作邏輯等等,然後將做好的物件轉換成預製物件,如此一來就可以在任意場景中量產該物件. 

舉例來說,在一款射擊遊戲中,敵方角色不斷出現,這時候的敵方角色並不是設計者先準備好一堆物件在特定位置上隱藏著,等時間到才解除隱藏,而是先做好敵方角色的預製物件,等到場景滿足特定條件時才會生成並出現在畫面上.

那麼,這兩種做法的差異性在哪裡呢?答案是系統效能. 事先產生好放在特定位置等待,這種做法在遊戲一開始系統就會被這些還不需要使用到的物件佔用掉許多資源,反而造成遊戲效能變差. 事先做好預製物件的話,在場景需要這些物件時才會被生成,如此一來資源就可以有效地被利用.

蛤?還是看不懂嗎?你家倉庫本來只能放一個月的所有日常用品的備品,結果某天你買了一年份的衛生紙塞滿了倉庫,結果導致你沒地方放其他東西的備品,大概是這種概念.


預製物件練習

接下來就可以開始照著影片練習如何預製物件,很簡單也很方便der!!



謝謝大家收看,記得多練習!!

2016年7月20日 星期三

[Unity][PlayMaker] 練習六 : 物件移動-自動

自動移動

所謂的自動移動,就是指物件有自己固定或隨機的自發行為,不需要透過人為去操作,最簡單的一種就是指定目標移動.

自動移動的運用幾乎在所有遊戲都可以看得到,像是NPC的移動或是攝影機切換視角都會用到.


自動移動練習


這次的練習很簡單,我們會建立一個物件自動在兩個定點間規律移動,接著請大家試著照著影片實作看看吧!!




謝謝大家~

2016年7月13日 星期三

[Unity][PlayMaker] 練習五 : 全域事件與物件隱藏

物件消失

在畫面上使物件消失(指看不到),大致上有三種方式 : 描繪(Render)失效,物件失效以及摧毀(Destroy)物件.

描繪失效

物件在畫面上可以被看見,主要是依賴描繪元件 (Render component),描繪元件中有許多設定,這個以後再慢慢介紹,當描繪元件失效時,物件本身無法以任何可視形式出現在畫面中,但是在這種情況下,物件本身還是存在於場景中,也就是它的其他元件功能還是健在的.
描繪失效將在這次的練習中介紹給大家使用.

物件失效

物件失效,會使物件中所有元件一併失效,當然也包括狀態機及成像. 在這種狀況下,物件是可以透過其他物件重新啟用,但是無法靠自己.,然而物件的所有參數也都不會因此被改變.物件失效我們在練習一的電燈開關裡面就有應用到了.

摧毀物件

摧毀物件,顧名思義就是毀屍滅跡了,在場景中被摧毀的物件就永遠消失了,所以它的任何功能跟設定也就跟著消失了.


全域事件觸發隱藏物件


在這次的練習中,我們將會練習之前提到過的全域事件來透過觸發器控制物件的描繪失效,請大家照著影片練習唷!



下一回會跟大家介紹如何讓物件自動移動,謝謝大家!

2016年7月9日 星期六

[Unity][PlayMaker] 練習四 : 觸發器

觸發器

今天要跟大家介紹的是觸發器的基本概念,什麼是觸發器呢?

簡單的說,就是用來偵測物件之間彼此有沒接觸到的一個機制,這機制又分三種狀況.

進入期

當A物件剛碰觸到B物件,但是還沒完全被B物件涵蓋時,稱為進入期.

滯留期

當A物件完全被B物件所涵蓋時,稱為滯留期.

離開期

當A物件剛離開B物件,但是還沒有完全脫離B物件時,稱為離開期.


觸發器練習

這次的練習,我們主要會針對上述的三種狀況做練習,請照著下面影片練習看看吧!



下一回,將會為大家介紹讓物件消失的幾種方式以及全域事件的使用,謝謝!!

2016年7月1日 星期五

[Unity][PlayMaker] 練習三 : 物件移動-手動

物件移動-手動

這次要教大家的是如何透過鍵盤去控制物件的移動.

在這次練習開始之前,要先跟大家介紹區域變數,全域變數,區域事件以及全域事件.

什麼是變數?

變數可以指在電腦記憶體裏存在值的被命名的存儲空間。

簡單來說,就是有個東西用來存放特定的值. 舉例來說,有個叫做Name的變數,我在裡面放了Tom,那這個變數就等於Tom,可以讀作 Name = Tom. 在PlayMaker裡最常會用到的就是座標跟位移 (就是指物件每次要移動的單位).

在這次練習中,我們會取得一個向量(就是有方向性的值),然後將它存放在一個向量變數中.

區域變數

只能在某個物件內使用的變數就叫做區域變數,比方說你在攝影機裡設定的區域變數,就不能拿到攝影機以外的物件使用或修改.

全域變數

所有在同一個Scene(場景)上出現的物件都可以通用的變數就叫做全域變數. 比方說你在攝影機裡設定了一個全域變數,這個變數是可以被其他物件(像是光源)直接拿來使用或修改.

區域事件

事件在之前的練習中出現過了,其代表的就是某個過渡的觸發點,觸發後就會依據過渡目標而進入下一個狀態,而只能在某個物件內使用的事件就叫做區域事件,規則與區域變數一樣,該物件以外的任何物件都無法觸發.

全域事件

所有在同一個Scene(場景)上出現的物件都可以通用的事件就叫做全域事件. 規則與全域變數一樣,該場景上所有物件都是可以觸發它的.

物件移動練習

請參考下面影片練習


這次的練習完之後,是不是越來越有Fu了?下一次的練習會開始教大家觸發器的使用,謝謝!

2016年6月29日 星期三

[Unity][PlayMaker] 練習二 : 寶箱開關

寶箱開關練習

這個練習基本上算是上一個練習的延伸變化,主要是讓大家開始試著去使用Asset Store中的免費套件,以及當加入了動畫播放時需要注意的事項.

可學習技能 :

Animation => Play Animation


接著我們可以透過下面影片來學習如何控制寶箱的動作


謝謝大家的收看,下次再會!


2016年6月27日 星期一

[Unity][PlayMaker] 練習一 : 燈光開關

設計概念

在使用PlayMaker設計狀態機前,對於新手來說需要先了解一下基本的設計概念及流程,分別是(1)載點  (2)狀態  (3)事件  (4)行為.

載點

載點是指狀態機所掛載的地方,狀態機必須掛載於GameObject中,要特別注意當操作行為中會有Active或是Destroy這種會讓GameObject停用或銷毀的情況下,載點是否適合掛載在某個GameObject中,因為一旦GameObject停用或銷毀時,它所掛載的狀態機也會一併停用或銷毀,就可能導致最後執行結果不如你所預期.

狀態

狀態是指當你在設計某個功能時,該功能中可被預期的所有狀態.簡單舉兩個例子,(1)當我們想做出一個電燈開關時,試著去想想看電燈開關這個功能裡面可能會有哪些狀態呢?答案是兩個,開跟關.(2)當你想設計一個瑪力歐時,我們可預期到他一定會有移動,加速,跳躍,蹲下等這些行為,也就是至少會需要四個狀態.

事件

狀態移動到下一個狀態所需的連結可以稱為事件.狀態本身是死的,必須透過觸發事件才能夠轉移到其他狀態.以電燈開關為例,電燈的開跟關兩個狀態代表的其實只有電燈是明或滅,光只有狀態並沒辦法讓你可以讓兩者之間做切換,所以我們必須加入打開電燈以及關閉電燈這兩個事件來讓開跟關兩個狀態之間可以切換.

行為

當前面三項都完成後,確定狀態能夠透過事件並如你預期的做切換時,最後我們才會去考慮在各個狀態上實際應該發生的事情,而這些事情我們稱做行為.以電燈開關來說,在開跟關這兩個狀態中必須發生的事情,就是去控制光源,當狀態是開,必須讓光源啟用或是產生出來,而當狀態是關的時候,則必須把光源銷毀或是停用.


燈光開關練習


可習得技能:

GUI => GUI button
UnityObject => Set property


接著我們可以透過下面影片來學習到底怎麼去實作一個簡單的燈光開關




今天的教學到這邊結束,希望大家會喜歡,謝謝!!

2016年6月22日 星期三

[Unity][PlayMaker] PlayMaker安裝與介紹

PlayMaker安裝與介紹

在安裝之前,我們先來介紹一下為什麼要使用PlayMaker好了.

PlayMaker是一款以有限狀態機的方式來實作及呈現遊戲的Unity外掛程式,透過有限狀態機,在開發遊戲邏輯時可以很明確且很簡單的加入你所預期發生的行為,因為不需要寫任何程式. 

狀態機


蛤?什麼是有限狀態機?這個可能很多人聽都沒聽過,在這邊簡單說明一下.

有限狀態機簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的模型.

狀態機的動作主要分四大類,分別是進入,退出,輸入及轉移.

我們試著從下圖來瞭解一下狀態機的動作.


1. 當開始執行時,會由初始狀態輸入N這個數值到狀態1.
2. 狀態1會判斷N大於1或是小於1,若大於1則移動到狀態2,小於1則直接到狀態3.
3. 狀態2會判斷N+1之後是否大於5,若大於5,則移動到狀態3,小於5則將N+1送回狀態1.
4. 狀態3會直接輸出N到狀態4,因為狀態4沒有任何往其他地方的箭頭,所以到這邊結束.


上面例子中,狀態跟狀態之間依據不同條件切換,就是狀態機的基本概念了,你可以清楚看到在系統中可能會發生的所有狀況,當在PlayMaker中實作時,還可以清楚看到目前處於哪個狀態中,等到下一篇開始正式教學時會有清楚的例子讓大家看.


[2016.06.26追記 >>

由於測試教學時發現原本的有限狀態機說明太過理論化,所以追加一個簡單的應用說明,希望能更淺顯易懂.


上圖中是一假設我們創立了一個人物,我們預期他應該要有站立,蹲下,行走以及跳躍等動作,於是圖中會有四個狀態分別對應到我們預期的動作,由於這些動作是我們所事先預期的,所以這個人物會擁有的狀態一開始就被我們限制,所以稱為有限狀態,

在圖中,我們設定五個不同按鍵分別代表著四個方向以及跳躍,我們開始試著說明這張圖.

1. 當遊戲開始時,角色預設的狀態是站立的.
2. 當玩家按下A或D時,這時候狀態會由站立切換到行走,這時候角色會移動.
3. 當角色行走時,若玩家按下了空白鍵,狀態會由行走切換至跳躍,跳躍完會自動回到站立狀態,若此時A或D並未放開,狀態會立即從站立切換到行走.
4. 在站立狀態中若是按下S,則狀態會從站立切換到蹲下,若是S鍵沒放開的情況下,將會一直持續在蹲下狀態,也就是角色無法做其他任何事情(因為狀態無法切換).

<<2016.06.26追記]



PlayMaker安裝

先前文章中已經提過如何安裝Unity,接著我們要來安裝PlayMaker.

PlayMaker的取得方式有兩種,一種是透過Unity上的Assets Store,另一種則是直接在PlayMaker官網上取得. 順帶說明一下,這外掛是要錢的.

官網取得:

http://www.hutonggames.com/

到官網頁面上會看到下圖,點選2










緊接著會看到下方畫面,點選玩playMaker



最後就會看到購物清單畫面,選擇自己需要的方案,接著去結帳後就可以下載PlayMaker assets package.




















取得Assets package後,在Unity專案中,找到Project區塊,在Assets區點擊右鍵,選擇Import Package > Custom Package.


然後就可以選擇要匯入的Assets Package. 選擇PlayMaker.unitypackage,然後open.


全選後,點選Import.


畫面上方選單會出現PlayMaker的選項,選擇Install後會看到下方一連串畫面.






安裝完畢後,點選PlayMaker > PlayMaker Editor.


看到下方的編輯器畫面就算安裝完畢嚕.


Unity Asset Store取得 :

在Unity上方選單中點選Windows > Asset Store,將會開啟Store頁面.

輸入PlayMaker,按下搜尋(放大鏡).


下圖是搜尋結果,我們需要的是第一個,點擊後可以進入購買頁面.


因為我的帳號已經購買過了,所以會直接看到Import按鈕,之後的操作跟由官方取得後安裝程序是一樣的,就不多敘述了.



今天的介紹到這邊,接下來的教學,個人期望是由影片的方式來呈現,希望可以幫到真心想學習卻苦無門路的人.


2016年6月11日 星期六

[Unity] 介面基礎介紹

介面基礎介紹

概要


Unity專案建立好後,初始畫面如下,主要分為Hierarchy(物件階層),Scene(場景),Game(遊戲畫面),Project(專案資產區),Console(操控台)及Inspector(物件檢視器)等區塊.


Scene(場景區)


首先介紹Scene視窗,Scene顧名思義就是架設遊戲內容的地方,可以把它想像成拍片現場.每個Scene都是由許多的GameObject(遊戲物件)所組成,而GameObject則是由許多的Component(元件)所組成. 簡單的說,Scene就是用來裝GameObject的容器,GameObject是用來裝Component的容器.

在Scene底下有些小工具,初學者最需要知道的大概就是2D/3D的切換,點擊圖中2D字樣,就可以切換成3D模式,當然不管在哪個模式中都是可以使用2D/3D物件的,其他功能等以後的教學有使用到時我們再另外做介紹.


Game(遊戲畫面)

Game視窗就是用來呈現實際遊戲進行時的畫面,通常在開發時會將Scene跟Game兩個視窗並排呈現,在開發期間會比較方便.

底下依然有幾個功能可以使用,Free Aspect(自由視角)這裏可以切換Game視角的比例大小;Maximize on Play(執行最大化)顧名思義就是當程式執行時,會以全螢幕方式呈現Game; Stat(狀態),點擊時可以看到Game的資源使用概況,不過初學者就先跳過吧,才不會一開始就覺得太過複雜而感到挫折QQ.




Hierarchy(物件階層)

這一區主要是用來管理物件之間的關係,物件階層是指物件跟物件之間有從屬關係,舉一個簡單的例子來說,車子是由許多的零組件湊起來的,這些零組件包含引擎,輪胎,車身等等,在這裏,車子就是主物件,而那些零組件則是他的子物件.




Project Assets(專案資產區) 


舉凡圖片,音檔,程式以及場景等在Unity中都是以Asset(資產)來總稱,就連你開發完的專案都是以Asset package(資產包)的方式匯出,這區就是用來管理資產的匯入/匯出及其他管理功能


Console(操控台)

有過程式開發經驗的人應該不用我多解釋,不過對於新手來說,只要記得這邊就是看Log(日誌)的地方就可以了,日誌?就是程式運行中系統會拋出來的訊息或是人為在程式中設定呈現出來的訊息.






Inspector(物件檢視區)

物件檢視區,顧名思義就是檢視及設定物件內的Component(元件)參數,這些元件如Transform(可變),Render(成像),Collider(對撞機)等等.圖中因為在系統中並沒有特地點擊任何物件,所以看起來一片空白,各位可以試著點擊物件階層中的任意物件,就可以看到裡面的元件及參數了.


這次的介紹就到此,接下來的教學會以PlayMaker這個插件為主,希望能讓不懂程式的人也可以輕鬆上手Unity,謝謝!!