视觉效果组件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:表示是否有摄像机在前一帧中剔除了效果。