Visual Effect 组件 API
为了在场景中创建 Visual Effect Graph 的实例,Unity 使用了 Visual Effect 组件。Visual Effect 组件附加到场景中的游戏对象,并引用定义视觉效果的 Visual Effect Graph。这允许您在不同的位置和方向创建不同的效果实例,并独立控制每种效果。为了控制运行时效果,Unity 提供了 C# API,用来修改 Visual Effect 组件和设置 Property 重写。
本文档提供了常见用例并介绍使用组件 API 时应考虑的最佳实践。
设置 Visual Effect Graph
要在运行时更改 Visual Effect Graph,请将新的 Visual Effect Graph 资源分配给 effect.visualEffectAsset
属性。当您更改 Visual Effect Graph 时,组件会重置其某些属性的值。
重置的值有:
- Total Time:当您更改图形时,API 会调用
Reset()
函数将此值设置为 0.0f。 - Event Attributes:该组件丢弃所有事件 Event Attribues。
不重置的值有:
- Exposed Property Overrides:如果新的 Visual Effect Graph 资源所公开的属性与先前资源的属性具有相同的名称和类型,则不会重置该属性的值。
- Random Seed 和 Reset Seed On Play Value。
- 默认事件重写。
- 渲染设置重写。
控制播放状态
您可以使用该 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。 - 将默认事件重新发送到 Visual Effect Graph。
- 将
- Play Rate:
effect.playRate = value
。Unity 不会序列化此更改。
默认事件
当 Visual Effect 组件(或它附加到的 GameObject)启用时,它会发送一个 Event 到图形。默认情况下,此事件为 OnPlay
,这是 Spawn Contexts 的标准开头。
可以通过以下方式更改默认事件:
在 Visual Effect Inspector 中,更改 **Initial Event Name* 字段。
- 在组件 API 中:
initialEventName ="MyEventName";
。 - 在组件 API 中:
initialEventID = Shader.PropertyToID("MyEventName");
。 *使用 ExposedProperty Helper 类。
随机种子控制
每个效果实例都有其随机种子的设置和控件。您可以修改种子以影响 Visual Effect Graph 使用的随机值。
resetSeedOnPlay = true/ false
:控制 Unity 是否在您每次调用ReInit()
函数时都计算新的随机种子。这会导致 Visual Effect Graph 使用的每个随机值与之前模拟中的值不同。startSeed = intSeed
:设置一个手动种子,Random Number 运算符用它为此视觉效果创建随机值。如果将resetSeedOnPlay
设置为true
,Unity 将忽略此值。
属性接口
要访问已公开属性的状态和值,您可以在 Visual Effect 组件 中使用多种方法。大多数 API 方法允许通过以下方法访问该属性:
string
属性名称。这很容易使用,但属于最不优化的方法。int
属性 ID。要从字符串属性名称生成此 ID,请使用Shader.PropertyToID(string name)
。这是最优化的方法。- ExposedProperty Helper 类。此类结合了字符串属性名称提供的易用性,以及整数属性 ID 的效率。
检查已公开的属性
您可以检查组件的 Visual Effect Graph 是否包含特定的公开属性。为此,您可以使用以下组中与属性类型相对应的方法:
HasInt(property)
HasUInt(property)
HasBool(property)
HasFloat(property)
HasVector2(property)
HasVector3(property)
HasVector4(property)
HasGradient(property)
HasAnimationCurve(property)
HasMesh(property)
HasTexture(property)
HasMatrix4x4(property)
对于每个方法,如果 Visual Effect Graph 包含与您传入的名称或 ID 相同的正确类型的公开属性,则该方法返回 true
。否则该方法返回 false
。
获取公开属性的值
组件 API 允许您在组件的 Visual Effect Graph 中获取公开属性的值。为此,您可以使用以下组中与属性类型相对应的方法:
GetInt(property)
GetUInt(property)
GetBool(property)
GetFloat(property)
GetVector2(property)
GetVector3(property)
GetVector4(property)
GetGradient(property)
GetAnimationCurve(property)
GetMesh(property)
GetTexture(property)
GetMatrix4x4(property)
对于每个方法,如果 Visual Effect Graph 包含与您传入的名称或 ID 相同的正确类型的公开属性,则该方法返回属性的值。否则,该方法返回属性类型的默认值。
设置公开属性的值
组件 API 允许您在组件的 Visual Effect Graph 中设置公开属性的值。为此,您可以使用以下组中与属性类型相对应的方法:
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 允许您在运行时将事件发送到组件的 Visual Effect Graph。为此,请使用以下任一方法:
SendEvent(eventNameOrId)
SendEvent(eventNameOrId, eventAttribute)
eventNameOrId
参数可以是以下类型之一:
string
属性名称。这很容易使用,但属于最不优化的方法。int
属性 ID。要从字符串属性名称生成此 ID,请使用Shader.PropertyToID(string name)
。这是最优化的方法。- ExposedProperty Helper 类。此类结合了字符串属性名称提供的易用性,以及整数属性 ID 的效率。
可选的 eventAttribute
参数向事件附加一个 Event Attribute Payload。它们的有效负载提供 Graph 通过事件处理的数据。
备注:当您发送一个事件时,Visual Effect 组件会在它的下一个 Update() 中处理它,这发生在下一帧。
事件属性
事件属性是附加到事件的属性,可以由 Visual Effect Graph 进行处理。要创建和存储事件属性,请使用 VFXEventAttribute
类。Visual Effect 组件负责创建 VFXEventAttribute
类的实例,并根据当前分配的 Visual Effect Graph 创建它们。
创建事件属性
要创建“VFXEventAttribute”,请使用 Visual Effect 组件的“CreateVFXEventAttribute()”方法。如果您想多次发送具有相同属性的同一事件,请存储“VFXEventAtrribute”,而不是每次发送事件时都创建一个新事件。当您将事件发送到 Visual Effect Graph 时,Unity 会在其当前状态下创建 EventAttribute 的副本并发送该副本。这意味着,在您发送事件后,您可以安全地修改 EventAttribute,而不会影响发送到 Visual Effect Graph 的信息。
设置属性的有效负载
创建事件属性后,您可以使用类似于属性接口部分 中所述 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 类。此类结合了字符串属性名称提供的易用性,以及整数属性 ID 的效率。
生命周期和兼容性
创建事件属性时,它与当前分配给 Visual Effect 组件的 Visual Effect Graph 资源兼容。这意味着您可以使用相同的 VFXEventAttribute
将事件发送到同一图形的其他实例。如果将 Visual Effect 组件的 visualEffectAsset
属性更改为另一个图形,则不能再使用相同的 VFXEventAttribute
向其发送事件。
如果您想在同一个场景中管理多个 Visual Effect 实例并希望共享事件有效负载,您可以存储一个 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);
}
调试
每个 Visual Effect 组件都包含以下调试属性:
aliveParticleCount
:整个效果中活动粒子的数量。
备注*:该组件每秒异步计算此值,这意味着结果可能是在您访问此属性前一秒渲染的帧期间的活动粒子数。
culled
:指示是否有任何摄像机剔除了前一帧中的效果。