Related Posts Plugin for WordPress, Blogger...

3-23 Trigger To Move Main Camera

我的遊戲中的攝影機雖然是第三人稱固定視角,但並不是每一個角度都很好看。尤其是場景設計的時候,偏偏就覺得某些角度看過去的風景比較漂亮,比較符合我心目中的感覺,當然會希望玩家玩遊戲時也能看見相同角度的風景。從另一方面來說,玩家看不見的角度,就可以節省一些設計,專注在遊戲畫面中看得見的地方就好。

本章要來教大家如何在特定位置改變攝影機角度,由於遊戲仍然是第三人稱固定視角,所以不是讓玩家自己改變角度唷,而是將攝影機的角度改成設計師指定的角度。

首先在場景中建立一個Empty GameObject,取名為CameraTrigger。

拉到Project視窗中變成Prefab,然後再建立一個Script名稱為CameraTrigger。

將CameraTrigger的Script拉進同樣名為CameraTrigger的Prefab底下。

然後在CameraTrigger底下在建立一個Empty GameObject,名稱為Camera Socket。這個Camera Socket會用來記錄關卡設計師希望的鏡頭角度,當玩家經過Trigger後,程式便以Camera Socket中的Transform設定來移動鏡頭。

然後開始來撰寫CameraTrigger的程式碼吧!
CameraTrigger.cs:


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

public class CameraTrigger : MonoBehaviour {

 [SerializeField] int layerFilter = 0;
 [SerializeField] float triggerRadius = 5f;
 [SerializeField] float stopMoveDistance = 0.05f;
 [SerializeField] Transform cameraSocket;

 bool startMoveMainCamera = false;

 void Start () {
  SphereCollider sphereCollider = gameObject.AddComponent();
  sphereCollider.isTrigger = true;
  sphereCollider.radius = triggerRadius;
 }
 
 void OnTriggerEnter(Collider target)
 {
  if (target.gameObject.layer == layerFilter)
  {
   startMoveMainCamera = true;
  }
 }

 void Update(){
  if (startMoveMainCamera) {
   Vector3 cameraPos = Vector3.Lerp (Camera.main.transform.localPosition,
          cameraSocket.localPosition,
          Time.deltaTime);
   Quaternion cameraRot = Quaternion.Lerp (Camera.main.transform.localRotation,
                           cameraSocket.localRotation,
                           Time.deltaTime);
   Camera.main.transform.localPosition = new Vector3 (cameraPos.x, cameraPos.y, cameraPos.z);
   Camera.main.transform.localRotation = new Quaternion(cameraRot.x, cameraRot.y, cameraRot.z, cameraRot.w);
  }

  if (IsArrived ()) {
   startMoveMainCamera = false;
  }
 }

 bool IsArrived(){
  return Vector3.Distance (Camera.main.transform.localPosition, cameraSocket.localPosition) <= stopMoveDistance;
 }

 void OnDrawGizmos()
 {
  Gizmos.color = new Color(0, 255f, 0, .5f);
  Gizmos.DrawWireSphere(transform.position, triggerRadius);
 }
}


撰寫好以後,請按照下圖進行參數設定。Layer Filter的數字需設定成Player Layer的數字,本例子中我的Player Layer在第10層故設定為10,如對Layer Filter不太熟悉的話,請先閱讀之前的文章唷,我在Audio Trigger也是用類似的寫法:
3-3 Trigger Player Hit Animation And Audio On Radius
https://rpgcorecombat.blogspot.tw/2017/12/3-3-trigger-player-hit-animation-and.html

Trigger Radius是指設定半徑,請大家依照需求自行調整吧。Stop Move Distance是一個容錯值,主要原因為我使用Lerp函數計算攝影機的移動座標,所以攝影機最後的位置通常跟指定的位置會有一點點的誤差,不可能完全一樣,0.05是我覺得滿意又不會等太久的距離。

最後,就是把Camera Socket拉進參數中啦。徹底完成!以後CameraTrigger就是可以反覆使用的方便Prefab。

接下來就讓我們快速拉一個Camera Trigger吧,如下圖,我設定在玩家必定會經過的過道上,且綠色半徑覆蓋所有的走道範圍。

然後回到場景中,我先在遊戲模式中調整鏡頭角度,拉到如下圖我想要的樣子。

接著將目前Main Camera的Transform進行Copy Component,並結束遊戲模式,此時Main Camera的設定會自動變回來。

接著,到我們剛剛拉進場景的CameraTrigger底下的Camera Socket,使用Paste Component Value,這樣我們的設定就會紀錄進去了。

實際來玩玩看吧,通過走道之前的鏡頭畫面如下圖這樣。

玩家一旦經過,鏡頭開始自動移動和旋轉。

接著還是一連串的旋轉。

旋轉。

旋轉~ 定位完成!從這個角度玩家才能看見樸質的木橋、壯闊的瀑布、美麗的村莊呀!

留言