在很多的解謎類遊戲中,場景中往往會有很多密室,玩家需要在不同的房間中來回穿梭,除了第三人稱攝像頭外,我們也可以通過在不同的房間中佈置不同的Camera,然後當角色到達指定房間後開啟對應的Camera來處理。類似的效果如下圖:
從Gif中可以看出,當我們的角色到達不同的房間時,我們的Camera會自動實現切換來觀察我們的角色。在以往,我們可能需要自己來寫一些觸發器來判斷角色到了哪個房間,然後開啟指定的Camera。但是有了Cinemachine後,我們就不需要那麼麻煩的敲程式碼了,同樣只需簡單的進行一些設定,Cinemachine就會替我們自動實現上述的功能。
在該案例中,我們需要使用到Cinemachine的Clear Shot功能,接下來就先讓我們來了解下Clear Shot。
Demo:https://github.com/luckyWjr/Demo Cinemachine資料夾下的DemoClearShot
Clear Shot Camera屬於一種管理類的Camera,在其根目錄下會有一個或多個VirtualCamera,ClearShot會從中選擇出針對被觀察目標的最好畫面品質的VirtualCamera。因此當場景中有很多Camera的時候使用該功能,可以保證我們的畫面都可以清楚的看見我們的目標。
至於如何鑑別哪個VirtualCamera的畫面品質更好,就需要用到我們上一篇文章所提到的Cinemachine Collider。它會分析畫面中的障礙物得到ShotQuality的數值,以及根據我們設定的optimal target distance的數值等作參考,根據這些資訊選出最好的作為當前Live狀態的VirtualCamera。如果這些數值相同,那麼會根據每個VirtualCamera在ClearShot中所設定的優先順序(priority)來選擇。
因此ClearShot下的每個VirtualCamera都必須帶有Cinemachine Collider的元件,不過我們也可以通過給ClearShot Camera自身新增Cinemachine Collider來代替,這樣就不需要給各個VirtualCamera新增了。
此外,我們依舊可以給ClearShot中每個VirtualCamera制定他們間的混合效果。
在Unity工具列中,選擇Cinemachine->Create ClearShot Camera,可以建立我們的ClearShot Camera:
建立好後場景中會生成一個CM ClearShot,同時在其根目錄下會預設生成一個VirtualCamera:
我們可以在ClearShot下繼續新增VirtualCamera,在CinemachineClearShot元件中會自動識別它們,同時可以在此處設定每個VirtualCamera的優先順序,值越大,優先順序越高。
這裡會有一個黃色小警告的標準,在元件最上面同時也給出了對應的提示:
這個問題就是我們前面所提到的,必須要需要給ClearShot或者ClearShot所包含的所有VirtualCamera新增Cinemachine Collider。
由於ClearShot本身也是繼承於CinemachineVirtualCameraBase,因此其屬性基本與VirtualCamera相似,如下圖:
這裡就不過多的介紹了,可以檢視本系列的第一篇文章。
需要注意的是,ClearShot的Look At和Follow屬性。若VirtualCamera自身設定了這兩個屬性,那麼就會使用VirtualCamera自身設定的值。若VirtualCamera沒有設定,則使用ClearShot設定的值。
我們首先建立一個簡單的場景用來測試,然後新增一個膠囊體來當作我們的角色,同時給角色設定一個不同的Layer與我們的牆體作區分,例如本案例中的樣子:
然後我們新增一個ClearShot Camera,預設的VirtualCamera就可以看向我們角色當前的位置。然後在ClearShot下新增一些新的VirtualCamera,分別放置在各個房間中,看向屬於自己的房間。由於ClearShot的工作原理是根據障礙物而計算的畫面品質來選擇當前的VirtualCamera。因此我們要儘量保證每個房間的VirtualCamera在轉動過程中視線不會看見別的房間。例如我們角色從房間A跑到房間B的時候,此時房間A的相機還是能很清楚的看見在房間B的角色,那麼ClearShot就不會啟動房間B的VirtualCamera了。測試的時候我們可以把牆弄得高一點。
注:我們可以先在Scene視窗中調整好視角,然後再建立VirtualCamera,這樣VirtualCamera的畫面就會和我們當前Scene視窗中的畫面一致。或者先建立好VirtualCamera,然後調整好Scene視窗的視角,接著選中我們的VirtualCamera,點選工具列中的GameObject->Align With View來調整我們的相機位置。
接著,我們來設定我們的ClearShot。我們先為其新增CinemachineCollider,並且刪除子VirtualCamera帶有的CinemachineCollider元件。同時將ClearShot的Look At設定為我們的角色,先不要設定Follow屬性,否則這些VirtualCamera都會跟著角色移動而脫離原本我們擺放的位置。
若想要每個房間內的Camera可以跟著角色移動,但是又不跟著跑到別的房間,我們可以給每個VirtualCamera新增CinemachineConfiner元件來處理。CinemachineConfiner可以給VirtualCamera新增一個活動範圍,是Camera只能在這個範圍內移動,具體的後續介紹。
上述步驟做好後,我們就可以移動我們的角色來觀察相機的切換效果了,具體效果就像文章最開始的Gif類似。
從上一篇CinemachineCollider提到這個屬性,到這一篇也提到了。那麼這個屬性到底有什麼用呢?
我們先來看下面這種情況:
我們的角色從房間A到了房間B,但是由於此時房間A的相機仍然可以很清晰的看見我們的角色,因此導致房間B的相機無法被啟動。那麼如何可以在這種情況下,啟動我們房間B的相機呢?此時就可以運用到我們的Optimal Target Distance屬性了。
前面介紹該屬性的時候,說到當目標到Camera的距離越接近我們設定的值,則評分越高。這個評分就會影響到我們ClearShot的選擇。上面例子中,當角色進入房間B時,此刻它距離房間B的Camera明顯是更近的,假設此時距離為3。那麼我們將Optimal Target Distance的值設定為3,在來看看情況,就會發現當角色房間B時,雖然兩個Camera都可以很清楚的看見角色,但是房間B的Camera到角色的距離與3更接近,所以就會啟用房間B的Camera。效果圖如下:
不過由於開啟Optimal Target Distance功能會造成一定的效能壓力,我們可以使用Priority來更好的解決這個問題。
上述情況除了可以通過設定Optimal Target Distance來解決外,我們還可以通過設定ClearShot中不同VirtualCamera的Priority屬性來解決。
同樣的道理,當房間A和房間B的Camera都可以清晰的看見角色時,也就是ShotQuality的值相同的情況下ClearShot會優先選擇Priority值更高的那個VirtualCamera。因此我們只需要將房間B的VirtualCamera的Priority值設定的比房間A的高,就可以實現上述情況,角色進入房間B時,啟用房間B的Camera了。
Clear Shot可以幫助我們在多個Camera中選擇效果最好的Camera來顯示。但是由於即使沒有使用到的VirtualCamera,也是會一直看向我們的目標,並且計算著ShotQuality,因此肯定會有一定的消耗。若在複雜場景中,且Clear Shot下有多個VirtualCamera,必然會造成一定的效能壓力,因此需要看情況使用。