當你玩遊戲的時候,大多數的狀況中你應該可以發現不管在甚麼情況下都能看到角色,或是遊戲中的過場動畫能夠跟實際遊戲進行無縫銜接,你會不會好奇這是怎麼做到的呢?
要做到這件事有幾種作法,其中一種就是自己建構程式以實現想要的攝影機運鏡方式。
而另一個比較容易上手的方式,則是使用Unity提供的Cinemachine模組。
本篇文章中將會對於如何使用Cinemachine以實現「在特定範圍內跟著角色移動的2D攝影機」做說明,首先我們從Cinemachine的介紹開始。
Cinemachine是甚麼?
Cinemachine是一個用以控制攝影機行為的Unity內建模組。
它可以快速地實現各種類型的攝影機行為,並且可以為攝影機增加各種功能以實現預期的拍攝效果,讓開發者不用重頭開始實作攝影機的程式。
Cinemachine安裝教學
要使用2017.1以及之後版本的Unity,才能夠使用Cinemachine。
1. 開啟Unity後,我們點擊Window按鈕以打開選單,選擇Package Manager視窗。
2. 在Package Manager視窗中找到Cinemachine後,按下右下角的Install鍵以匯入專案。
如此就完成了安裝!
如何使用Cinemachine
新增所需物件與元件
安裝完成後,在Unity編輯器上方會新增Cinemachine選單。
點擊Cinemachine按鈕以打開選單,再選擇Create 2D Camera,以新增2D的虛擬相機。
新增完成後,場景上會新增CM vcam1物件,且在Main Camera物件身上也自動新增了Cinemachine Brain元件。
我們先來說說甚麼是Virtual Camera
Virtual Camera就是讓我們將規劃好攝影機將要在哪個位置拍攝、怎麼拍攝的所有鏡頭中,將其中一個鏡頭的相關資訊紀錄在這個物件上。
我們可以用電影的拍攝來做比喻。拍攝電影時,會需要拍攝不同的鏡頭,有的可能會在離主角很遠的位置好將群眾與主角拍在一起,也有的可能會是靠近主角進行拍攝,這就是位置的不同。
而怎麼拍攝則是可以想像是在拍攝這個鏡頭的時候,攝影機要做哪些事,像是要不要晃動、要晃多大力、晃多久這些,或是要怎麼構圖,角色要在畫面的哪個位置等等。
關於怎麼拍攝的這些設定或功能,可以用Virtual Camera元件本身或是其子元件來實現。
那Main Camera身上的Cinemachine Brain元件呢
Cinemachine Brain主要是會追蹤場景中的每一個虛擬相機,並使Unity攝影機按照代表「當前的鏡頭,也就是當前使用的虛擬續影機」上的「設定」來表現。
如何使用準備好的物件
設定要優先執行哪個虛擬攝影機的設定
我們接下來就來說明使用Cinemachine基本的設定與做法。
1. Unity攝影機在遊戲中的虛擬攝影機之間,要怎麼決定按照哪個虛擬攝影機的設定表現。
2. 如何從當前的虛擬攝影機切換成想要的虛擬攝影機。
我們將先從決定Unity攝影機要按照哪個虛擬攝影機的設定表現開始。
首先我們再新增一個虛擬相機,並讓它的位置與先前的虛擬相機有區別。
之後我們看到新增的虛擬相機的Cinemachine Virtual Camera元件,並設定其Priority欄位的數值大於10。
我們可以看到Unity Camera現在是按照Priority數字較大的虛擬攝影機來表現
Priority欄位是用來讓Brain決定,要優先讓Unity Camera做出哪個虛擬相機的行為,數字越高越優先。
這樣就能讓Cinemachine Brain元件知道要讓攝影機執行哪個虛擬攝影機的設定。
但是這樣也會產生新的問題,那就是要怎麼從較優先的虛擬攝影機轉換到較不優先的虛擬攝影機呢。
這就是我們第二件要說明的事情,以下將會說一個我自己比較常見的作法。
如何切換成想要的虛擬攝影機的兩種方法
就像剛才說的,我們可以藉由改變虛擬攝影機的優先順序以決定要使用哪個鏡頭。
所以我們可以在玩家做了某些事後,改變優先順序的數值以切換要用的鏡頭。
第一種切換方式
我們先在Project視窗新增CamSwitch腳本。
打開編輯器,然後在Class的那一行程式上方增加using Cinemachine;如此我們才能使用Cinemachine的程式。
再宣告兩個public的CinemachineVirtualCamera類型的變數。
然後我們在Start設定一開始要使用哪個虛擬攝影機,然後在Update根據玩家的輸入決定要用哪個虛擬攝影機。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class CamSwitcher_SetPriority : MonoBehaviour
{
public CinemachineVirtualCamera cam1, cam2;
void Start()
{
cam1.m_Priority = 10;
cam2.m_Priority = 0;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
cam1.m_Priority = 10;
cam2.m_Priority = 0;
}
else if (Input.GetMouseButtonDown(1))
{
cam1.m_Priority = 0;
cam2.m_Priority = 10;
}
}
}
按下Ctrl+S儲存後,回到Unity。將兩個虛擬攝影機物件從Hireachy視窗點住併拖曳進變數的欄位中。
按下執行按鈕開始測試,可以看到兩個虛擬相機根據我們的操作而啟用或不啟用,Main Camera也隨之改變它的位置與設定。
第二種切換方式
接下來,我們再來說說另一種切換的方式。
我們按下執行鍵,在Hierachy視窗中點擊後來新增的虛擬相機物件,並取消勾選在Inspector視窗中物件名字左側的勾選欄位。
我們可以看到Scene視窗中Unity Camera逐漸移動到之前新增的虛擬相機的位置。
如果再勾選它的話,,Unity Camera會再移動到後來新增的虛擬相機的位置。
這個欄位是用來顯示物件是否啟用和手動設定要啟用或是不啟用物件的
啟用的意思就像是手機的開關機一樣,手機開機的狀況,我們才能用它來打電話或上網,而關機的時候,你雖然有這個東西,但卻沒有辦法用它做任何事。
接下來,我們就在程式中實作要怎麼用程式控制啟用或不啟用物件吧
我們新增另一個腳本CamSwitcher_SetActive,在其中宣告兩個public的GameObject類型的變數。
在Start裡,我們先設定其中一個物件是不啟用的,用SetActive(value)。
在Update裡,根據玩家按下滑鼠左鍵或右鍵,決定要啟用哪個虛擬相機物件。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamSwitcher_SetActive : MonoBehaviour
{
public GameObject cam1, cam2;
void Start()
{
cam1.SetActive(true);
cam2.SetActive(false);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
cam1.SetActive(true);
cam2.SetActive(false);
}
else if (Input.GetMouseButtonDown(1))
{
cam1.SetActive(false);
cam2.SetActive(true);
}
}
}
按下Ctrl+S儲存後,回到Unity。將兩個物件拖曳進變數的欄位中。
然後記得先把另一個腳本元件關起來,找到物件身上的該元件,然後取消勾選其名稱左側的欄位。
再按下執行按鈕,開始測試,可以看到兩個虛擬相機根據我們的操作而啟用或不啟用,Main Camera也隨之改變它的位置與設定。
如何讓攝影機跟隨角色
那雖然知道了要怎麼改變啟用的虛擬攝影機,但它現在還是不會跟隨角色移動。
我們現在就來設定讓攝影機進行跟隨。
我們看到Virtual Camera元件的Follow欄位,我們點擊Hierachy視窗中的角色,並將它拖曳進欄位中。
再去操作角色後,可以看到現在攝影機能夠跟著移動了。
然而當我們移動到場景邊界時,攝影機會因為跟隨角色移動,而拍攝到場景外的畫面。
使用Cinemachine來快速實現指定區域內的鏡頭跟隨
我們希望在攝影機跟隨玩家到遊戲場景的邊界時,不要拍攝到邊界以外的畫面。讓攝影機拍攝的範圍被限制住。
要做到這件事,我們可以使用之前說的Virtual Camera擁有的功能來實現。
要用這些功能呢,要打開Virtual Camera元件最下方的選單來選擇想要的功能。
在這些功能中,想要實現我們想要的效果,要選擇Cinemachine Confine。
點擊選項後,它將會在虛擬攝影機物件身上再加上一個Confiner元件。
以下我們將說明使用這個元件的流程。
1. 我們將會用一個Collider2D作為攝影機能移動的範圍的邊界。
2. 調整好Collider2D做的邊界後,我們再將該Collider2D元件拖曳進Confiner的Bounding Shape 2D欄位即可。
而要特別注意的是,該欄位要求我們要用Polygon或Composite的Collider 2D來做為邊界。
Composite Collider 2D跟Box Collider2D那些不太一樣,它是會將數個Collider合併成一個大Collider來使用。
這裡我們會使用Composite Collider。理由是因為我們想要的是一個長方形的範圍,所以我覺得用Box Collider 2D來做比較方便,最後再用Composite Collider來把它合併起來就好。
我們先新增一個空物件,然後給它附加上Box Collider2D元件,再根據遊戲場景調整它的大小。
調整好後,再為該物件附加上Composite Collider 2D元件,而這也會自動為物件附加上Rigidbody 2D元件,因為使用Composite Collider 2D需要此元件。
我們勾選Box Collider2D的Used By Composite,讓它得以被Composite使用。
並且設定Rigidbody2D的Body Type為Static,因為我們不需要此物件有任何物理上的行為。
設定好後,我們把該Composite元件拖曳進Confiner2D的欄位中。
再來我們執行遊戲,然而我們卻沒有看到角色,讓我們看到Scene視窗檢查遊戲場景是發生了甚麼。
我們可以在Scene視窗中看到角色在攝影機能拍攝到的畫面外,這是因為角色被用來限制攝影機移動範圍的Collider給擠出去了。
我們需要作為攝影機範圍用的Collider,但我們又不希望攝影機範圍的Collider與角色身上的Collider發生碰撞。
要解決這個問題,我們需要先幫作為攝影機範圍的物件新增一個屬於它的Layer,並為其進行設定。
我們在Inspector視窗中,點擊物件名稱下方的Layer以打開選單,再點擊選單最下方的Add Layer以新增Layer。
之後在顯示的頁面中的空白欄位中,輸入CameraBound,以新增Layer。
再在Hierachy視窗中點擊攝影機範圍物件,並為它設定Layer。
再來要打開Project Setting視窗
找到Project Setting視窗中的Physic2D頁面。
找到Physic2D頁面最下方的Layer Collision Matrix。
我們把Camera Bound跟其他Layer相交集的勾選欄位給取消。這代表讓這兩個Layer的物件不會發生碰撞。
好了後,再點擊遊玩按鈕,就可以看到角色不會被擠到攝影機限制範圍的物件外面了。現在不論角色前往何處,攝影機也不會超出設定的邊界。
結論
至此我們就完成一開始的目標”如何使用Cinemachine以實現在特定範圍內跟著角色移動的2D攝影機”。
這只是各種遊戲中的其中一種攝影機行為,如果想要更了解如何使用Cinemachine的話,可以回到Unity的Package Manager視窗Cinemachine那裡。
在頁面中的資訊下方有一個Samples的三角形,可以點擊以展開它的內容。
點擊展開的內容中的Import按鈕,以匯入Unity關於Cinemachine如何使用的各種範例。
可以去看看範例是怎麼做的,來學習要如何實現想要的攝影機行為。