視覺效果組件API
爲了在場景中創建一個視覺效果圖(Visual Effect Graph)的實例,Unity使用了視覺效果組件(Visual Effect component)。視覺效果組件附加到場景中的遊戲對象,並引用定義了視覺效果的視覺效果圖。這允許您在不同的位置和方向創建不同的效果實例,並獨立地控制每個效果。爲了在運行時控制效果,Unity提供了c# API,你可以使用它來修改視覺效果組件和設置屬性(Property)覆蓋。
本文檔展示了常見的用例,並描述了在使用組件API(component API)時需要考慮的良好實踐。
設置一個視覺效果圖
要在運行時更改視覺效果圖,請分配一個新的視覺效果圖資產給effect.visualEffectAsset屬性。當您更改視覺效果圖時,組件將重置其某些屬性的值。
重置的值爲:
- 總時間:當您更改圖形時,API調用Reset()函數,該函數將此值設置爲0.0f。
- 事件屬性:組件丟棄所有事件屬性Attribues。
沒有重置的值是:
- 暴露的屬性重載(Exposed Property Overrides):如果新的視覺效果圖資產暴露了與前一個資產的屬性具有相同名稱和類型的屬性,則此屬性的值不會重置。
- 隨機種子和播放時重置的種子。
- 默認事件重載。
- 渲染設置重載。
控制播放狀態
你可以使用API來控制效果回放。
通用控制:
Play :播放——使用effect.Play(),如果需要事件屬性則使用effect.Play(eventAttribute)。
Stop :停止——使用effect.Stop(),如果需要事件屬性則使用effect.Stop(eventAttribute)。
Pause :暫停——使用effect.pause = true或者effect.pause = false。Unity不會序列化這個變化。
Step :步驟——使用effect.AdvanceOneFrame ()。這隻有在effect.pause被設置爲true纔有效。
Reset Effect :重置效果——使用effect.Reinit()
- 將總時間(TotalTime)重置爲0.0f。
- 將默認事件重新發送到視覺效果圖。
Play Rate :播放率——使用effect.playRate = value。Unity不會序列化這個變化。
默認事件
當視覺效果組件(或它所連接的GameObject)啓用時,它將向圖形發送一個事件(Event)。默認情況下,這個事件是OnPlay,這是生成環境(Spawn Contexts)的標準起點。
您可以通過以下方式更改默認事件:
- 在“視覺效果檢查器(Visual Effect Inspector)”上,更改初始事件名稱字段。
- 在組件API中:initialEventName = "MyEventName";。
- 在組件API中:initialEventID = Shader.PropertyToID("MyEventName");。
- 使用曝光屬性助手類(ExposedProperty Helper Class)。
隨機種子的控制
每個效果實例都有隨機種子的設置和控制。您可以修改種子以影響視覺效果圖使用的隨機值。
- resetSeedOnPlay = true/false:控制每次調用ReInit()函數時Unity是否計算一個新的隨機種子。這導致視覺效果圖使用的每個隨機值都不同於之前的模擬。
- startSeed = intSeed:手動設置隨機數操作符用於爲該視覺效果創建隨機值的種子。如果resetSeedOnPlay設置爲true,則Unity將忽略此值。
屬性接口
要訪問公開屬性的狀態和值,您可以在視覺效果組件中使用多個方法。大多數API方法允許通過以下方法訪問該屬性:
- 字符串(string)的屬性名。這很容易使用,但卻是最不優化的方法。
- 整型(
int
)的屬性ID。要從字符串屬性名生成此ID,請使用Shader.PropertyToID(string name)。這是最優化的方法。 - 屬性助手類(ExposedProperty Helper Class)。這結合了字符串屬性名的易用性和整數屬性ID的效率。
檢查暴露的屬性
您可以檢查組件的視覺效果圖是否包含特定的公開屬性。要做到這一點,你可以使用來自以下組對應的屬性類型的方法:
HasInt(property)
HasUInt(property)
HasBool(property)
HasFloat(property)
HasVector2(property)
HasVector3(property)
HasVector4(property)
HasGradient(property)
HasAnimationCurve(property)
HasMesh(property)
HasTexture(property)
HasMatrix4x4(property)
對於每個方法,如果視覺效果圖包含正確類型的暴露屬性,且具有與傳入的名稱或ID相同的名稱或ID,則該方法返回true。否則方法返回false。
獲取公開屬性的值
組件API允許您在組件的視覺效果圖中獲取公開屬性的值。要做到這一點,你可以使用來自以下組對應的屬性類型的方法:
GetInt(property)
GetUInt(property)
GetBool(property)
GetFloat(property)
GetVector2(property)
GetVector3(property)
GetVector4(property)
GetGradient(property)
GetAnimationCurve(property)
GetMesh(property)
GetTexture(property)
GetMatrix4x4(property)
對於每個方法,如果視覺效果圖包含正確類型的公開屬性,並且具有與傳入的名稱或ID相同的名稱或ID,則該方法將返回該屬性的值。否則,該方法將返回屬性類型的默認值。
設置公開屬性的值
組件API允許您在組件的視覺效果圖中設置公開屬性的值。要做到這一點,你可以使用來自以下組對應的屬性類型的方法:
SetInt(property,value)
SetUInt(property,value)
SetBool(property,value)
SetFloat(property,value)
SetVector2(property,value)
SetVector3(property,value)
SetVector4(property,value)
SetGradient(property,value)
SetAnimationCurve(property,value)
SetMesh(property,value)
SetTexture(property,value)
SetMatrix4x4(property,value)
每個方法都用傳入的值覆蓋相應屬性的值。
重置屬性覆蓋和默認值
組件API允許您將屬性重寫回其原始值。爲此,使用ResetOverride(property)方法。
事件
發送事件
組件API允許您在運行時將事件發送到組件的視覺效果圖。爲此,請使用以下方法之一:
SendEvent(eventNameOrId)
SendEvent(eventNameOrId, eventAttribute)
eventNameOrId參數可以是以下類型之一:
- 字符串(string)的屬性名。這很容易使用,但卻是最不優化的方法。
- 整型(
int
)的屬性ID。要從字符串屬性名生成此ID,請使用Shader.PropertyToID(string name)。這是最優化的方法。 - 屬性助手類(ExposedProperty Helper Class)。這結合了字符串屬性名的易用性和整數屬性ID的效率。
可選的eventAttribute參數將事件屬性有效負載附加到事件。它們的有效負載提供了圖形使用事件處理的數據。
注意:當您發送事件時,Visual Effect組件將在下一幀中處理它的下一個 Update()。
事件屬性
事件屬性是附加到事件上的屬性,可以通過視覺效果圖進行處理。要創建和存儲事件屬性,請使用VFXEventAttribute
類。視覺效果組件負責創建VFXEventAttribute
類的實例,並根據當前分配的視覺效果圖創建它們。
創建事件屬性
要創建VFXEventAttribute,請使用視覺效果組件的CreateVFXEventAttribute()方法。如果希望多次發送具有相同屬性的相同事件,應該存儲VFXEventAtrribute,而不是每次發送事件時都創建一個新事件。當您將一個事件發送到一個視覺效果圖時,Unity會創建一個EventAttribute當前狀態的副本併發送副本。這意味着,在發送事件之後,您可以安全地修改EventAttribute,而不會影響發送到視覺效果圖的信息。
設置屬性的有效負載
創建事件屬性之後,使用與屬性接口部分中描述的Has/Get/Set屬性方法類似的API來設置屬性有效負載。
- Has :
HasBool
,HasVector3
,HasFloat
,... 檢查屬性是否存在. - Get :
GetBool
,GetVector3
,GetFloat
,... 獲取屬性的值. - Set :
SetBool
,SetVector3
,SetFloat
,... 設置屬性的值.
有關完整的屬性API文檔,請參閱Unity腳本參考中的VFXEventAttribute。
屬性名或ID可以是以下類型之一:
- 字符串(string)的屬性名。這很容易使用,但卻是最不優化的方法。
- 整型(
int
)的屬性ID。要從字符串屬性名生成此ID,請使用Shader.PropertyToID(string name)。這是最優化的方法。 - 屬性助手類(ExposedProperty Helper Class)。這結合了字符串屬性名的易用性和整數屬性ID的效率。
生命週期和兼容性
當您創建一個事件屬性時,它與當前分配給視覺效果組件的視覺效果圖形資產兼容。這意味着您可以使用相同的VFXEventAttribute將事件發送到相同圖的其他實例。如果將可視化效果組件的visualEffectAsset屬性更改爲另一個圖形,則不能再使用相同的VFXEventAttribute向其發送事件。
如果您希望在同一個場景中管理多個視覺效果實例,並希望共享事件有效負載,那麼可以存儲一個VFXEventAttribute,並在所有實例上使用它。
示例(在MonoBehaviour中)
VisualEffect visualEffect;
VFXEventAttribute eventAttribute;
static readonly ExposedProperty positionAttribute = "Position"
static readonly ExposedProperty enteredTriggerEvent = "EnteredTrigger"
void Start()
{
visualEffect = GetComponent<VisualEffect>();
// Caches an Event Attribute matching the
// visualEffect.visualEffectAsset graph.
eventAttribute = visualEffect.CreateVFXEventAttribute();
}
void OnTriggerEnter()
{
// Sets some Attributes
eventAttribute.SetVector3(positionAttribute, player.transform.position);
// Sends the Event
visualEffect.SendEvent(enteredTriggerEvent, eventAttribute);
}
調試
每個視覺效果組件包含以下調試屬性:
- aliveParticleCount:整個效應中活粒子的數目。
注意:組件每秒鐘異步計算該值,這意味着結果可能是在訪問該屬性前一秒內渲染的幀中的活粒子數。
- culled:表示是否有攝像機在前一幀中剔除了效果。