Cinemachine——磁力吸實現&CinemachineTargetGroup

陈侠云發表於2024-10-24

image
視角“聚焦”是遊戲過場動畫中常見的功能,Cinemachine實現這個功能,讓我們看看具體怎麼使用吧。透過Package Manager匯入Cinemachine外掛,在匯入Cinemachine Sample後,我們可以在Assets資料夾下Cinemachine/2.6.17(這個是你下載的cinemachine版本號)/Cinemachine Example Scenes/Scenes/CameraMagnets中看具體的Demo。

Cinemachine TargetGroup元件

image
使用Cinemachine目標組(Target Group)可以將多個GameObject視為一個單一的“注視”目標。透過目標組和組合演算法(Group Composer),可以輕鬆管理多個物件的攝像機視角。

以下是在Unity中建立一個使用目標組的虛擬攝像機的步驟:

建立目標組攝像機:在Unity選單中選擇 Cinemachine > Create Target Group Camera。這樣Unity會在場景中新增一個新的虛擬攝像機和一個目標組。

設定虛擬攝像機的目標:新建立的虛擬攝像機的跟隨(Follow)和注視(Look At)目標會指向這個新目標組。

選擇目標組物件:在層級皮膚(Hierarchy)中,選擇新建立的目標組物件。

新增新項:在檢查器(Inspector)中,點選“+”符號以向目標組中新增一個新項。

分配GameObject:在新項中分配一個GameObject,並編輯其權重(Weight)和半徑(Radius)屬性。

新增更多GameObject:如果需要向目標組中新增更多GameObject,可以重複步驟3和4。

透過以上步驟,你可以輕鬆地管理多個GameObject,讓攝像機更好地聚焦於這些目標。

Position Mode

計算目標組的位置的方法。

Group Center

使用包含目標組內所有專案的軸對齊包圍盒(Axis-Aligned Bounding Box,AABB)的中心點來計算目標組的位置。這種方法的步驟如下:

定義包圍盒:首先,計算一個軸對齊包圍盒,它能夠包含目標組內所有的GameObject。這個包圍盒是一個矩形立方體,邊界平行於座標軸。

找到最小和最大點:

最小點:找出所有目標的最小X、Y和Z座標,形成一個點(minPoint)。
最大點:找出所有目標的最大X、Y和Z座標,形成另一個點(maxPoint)。
計算中心點:透過將最小點和最大點的座標相加,然後除以2,計算出包圍盒的中心點。公式如下:

image

返回結果:計算得出的中心點就是目標組的位置,可以用作攝像機的注視點或其他需要引用的位置。

透過這種方式,可以確保目標組的位置能夠包圍並涵蓋所有相關的GameObject,使得攝像機能夠更好地對齊視角。

Group Average

使用目標組內專案位置的加權平均值來計算目標組的位置,這種方法考慮了各個專案的重要性或影響力。具體步驟如下:

獲取目標位置和權重:首先,收集目標組內所有GameObject的位置(例如,世界座標)和它們各自的權重(Weight)。

計算加權和:

將每個目標的位置乘以其對應的權重,得到加權位置。
將所有加權位置相加,得到總的加權和。
公式為:
image
計算總權重:將所有目標的權重相加,得到總權重。

公式為:
image
計算加權平均位置:將加權和除以總權重,得到加權平均位置。公式為:
image
返回結果:最終得出的加權平均位置就是目標組的位置,可以用作攝像機的注視點或其他需要引用的位置。

Rotation Mode

計算目標組的旋轉的方法。

Manual

使用目標組變換(Transform)中的旋轉屬性(Rotation)值來計算目標組的位置是推薦的設定。這種方法的步驟如下:

獲取目標組的旋轉值:首先,訪問目標組物件的變換元件,找到其中的旋轉屬性。這通常以四元數(Quaternion)或尤拉角(Euler Angles)的形式表示。

應用旋轉:根據旋轉屬性的值,計算目標組在世界座標系中的方向。這一方向決定了攝像機的朝向或注視點的方向。

保持一致性:使用目標組的旋轉屬性可以確保在場景中,攝像機或其他物件始終保持與目標組相一致的方向,從而增強視覺效果的一致性。

推薦使用:使用目標組的旋轉屬性是推薦的設定,因為它可以自動適應目標組內物件的位置變化,確保攝像機的視角始終正確對齊。

透過這種方式,可以方便地管理多個GameObject的旋轉,使得整體效果更加自然和流暢。

Group Average

對目標組內專案的朝向(Orientation)進行加權平均是一種計算目標組整體方向的方法。這種方法考慮了各個專案的旋轉屬性和它們的重要性。具體步驟如下:

獲取朝向和權重:首先,收集目標組內所有GameObject的朝向資訊,通常以四元數(Quaternion)或尤拉角(Euler Angles)的形式表示,並獲取它們各自的權重(Weight)。

轉換為四元數:如果使用的是尤拉角,先將每個目標的朝向轉換為四元數,以便於後續的計算。

計算加權和:

將每個目標的朝向(四元數)乘以其對應的權重,得到加權朝向。
將所有加權朝向相加,得到總的加權和。
公式為:
image

計算總權重:將所有目標的權重相加,得到總權重。

公式為:
image
計算加權平均朝向:將加權和除以總權重,得到加權平均朝向。注意,這一步通常需要對結果進行歸一化,以確保朝向表示的有效性。

返回結果:最終得出的加權平均朝向就是目標組的整體方向,可以用作攝像機的朝向或其他需要引用的方向。

Target&Weight&Radius

  • weight:在計算平均時給該專案多少權重。權重不能為負。
  • radius:該專案的半徑,用於計算包圍盒。半徑不能為負。

VirtualCamera設定

CinemachineVirtualCamera的Follow屬性,需要指向擁有TargetGroup元件的gameObject

TargetGroup權重調整

接下來我們就可以自己實現程式碼,在每一幀根據與目標距離調整 TargetGroup 中每個item的權重,就可以實現磁力吸效果了,看看官方提供的程式碼:

public class CameraMagnetTargetController : MonoBehaviour
{
    public CinemachineTargetGroup targetGroup;

    private int playerIndex;
    private CameraMagnetProperty[] cameraMagnets;
    // Start is called before the first frame update
    void Start()
    {
        cameraMagnets = GetComponentsInChildren<CameraMagnetProperty>();
        playerIndex = 0;
    }

    // Update is called once per frame
    void Update()
    {
        for (int i = 1; i < targetGroup.m_Targets.Length; ++i)
        {
            float distance = (targetGroup.m_Targets[playerIndex].target.position - 
                              targetGroup.m_Targets[i].target.position).magnitude;
            if (distance < cameraMagnets[i-1].Proximity)
            {
                targetGroup.m_Targets[i].weight = cameraMagnets[i-1].MagnetStrength * 
                                                  (1 - (distance / cameraMagnets[i-1].Proximity));
            }
            else
            {
                targetGroup.m_Targets[i].weight = 0;
            }
        }
    }
}

相關文章