关于 ue-niagara-effects
面向 UE 5.8 的 Niagara 与 C++ 游戏逻辑集成编码技能,涵盖系统生成和控制、用户数据传入、数据通道、模拟缓存及效果性能管理。
主要功能
- 01生成并控制 Niagara 系统
- 02设置运行时用户参数
- 03绑定数据接口与数组
- 04发布和读取 Niagara Data Channels
- 05使用模拟缓存与组件池
适用场景
- 01根据游戏事件触发命中特效
- 02将持续轨迹附加到组件
- 03向 Niagara 传递游戏数据
- 04录制并回放特效模拟
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ quodsoler/ unreal-engine-skills --skill ue-niagara-effects安装后在 Claude Code 中输入/ue-niagara-effects确认已加载。
附带文件references/niagara-data-interfaces.mdreferences/niagara-parameter-types.md
详细介绍
UE Niagara 特效
目标引擎:UE 5.8。下方 API 已根据 5.8 头文件验证;较旧的形式列在“已弃用 — 请勿使用”下。
Niagara 随 Niagara 插件提供(Engine/Plugins/FX/Niagara,默认启用)。游戏代码通过 UNiagaraFunctionLibrary 和 UNiagaraComponent 生成并驱动系统,通过数据接口和 Niagara Data Channels 向其馈送结构化数据,并通过组件池化和 UNiagaraEffectType 可扩展性控制开销。将 "Niagara" 添加到模块的 PublicDependencyModuleNames;如果要继承 UNiagaraDataInterface,还需添加 "NiagaraCore"。
上下文
如果 .agents/ue-project-context.md 存在,请阅读它(模块名称、约定、已启用的插件、GAS/网络设置)。如果该文件不存在,也请继续。
根据请求和代码库确定相关领域。只有在两种合理解读会导致代码不同的情况下才提问。
| 请求涉及…… | 转到 |
|---|---|
| 资源、发射器和组件之间的关系 | 系统和组件模型 |
| 触发特效、附加拖尾 | 生成系统 |
| 激活、重置、暂停、跳转 | 生命周期控制 |
| 向特效传入浮点数、颜色、向量 | 设置用户参数 |
| 骨骼网格体/静态网格体、曲线、数组、纹理 DI | 数据接口 |
| 向 Niagara 脚本公开游戏专用数据 | 自定义数据接口 |
| 将游戏事件传入 Niagara、VFX 间消息传递 | Niagara Data Channels |
| 确定特效何时结束 | 完成回调 |
| 录制和回放模拟 | 模拟缓存 |
| 低开销的高数量发射器 | 轻量级发射器 |
| 生成开销、复用、预热 | 组件池化 |
| 剔除、Tick 顺序、确定性 | 可扩展性和 Tick 行为 |
| Build.cs 和包含项 | 构建设置 |
系统和组件模型
UNiagaraSystem asset; holds TArray<FNiagaraEmitterHandle>
└── FNiagaraEmitterHandle GetEmitterBase() -> UNiagaraEmitterBase
├── UNiagaraEmitter ENiagaraEmitterMode::Standard (stateful, scripted)
└── UNiagaraStatelessEmitter ENiagaraEmitterMode::Stateless (lightweight)
UNiagaraComponent runtime instance; GetSystemInstanceController()
作者在 Niagara 编辑器中将参数放入 User. 命名空间,即可向 C++ 公开这些参数。只有 User.* 参数可在运行时覆盖;System.*、Emitter.*、Particle.* 和 Module.* 均为模拟内部参数。
无需打开编辑器即可查看资源公开的内容:
#include "NiagaraFunctionLibrary.h"
// FNiagaraUserParameterInfo: ParameterName, ParameterType, TypeName.
const TArray<FNiagaraUserParameterInfo> Params = UNiagaraFunctionLibrary::GetAllUserParameters(ImpactSystem);
// FNiagaraMinimalEmitterInfo: EmitterName, bIsEnabled, bIsLightweight, UsedRendererMaterials, UsedRendererMeshes.
const TArray<FNiagaraMinimalEmitterInfo> Emitters = UNiagaraFunctionLibrary::GetAllEmitters(ImpactSystem);
生成系统
#include "NiagaraComponent.h"
#include "NiagaraFunctionLibrary.h"
// One-shot at a world location. Returns nullptr on dedicated servers and when the
// pre-cull check rejects the spawn, so always null-check.
UNiagaraComponent* ImpactVFX = UNiagaraFunctionLibrary::SpawnSystemAtLocation(
this, // const UObject* WorldContextObject
ImpactSystem, // UNiagaraSystem*
HitLocation, // FVector Location
FRotator::ZeroRotator, // FRotator Rotation
FVector(1.0f), // FVector Scale
/*bAutoDestroy=*/ true,
/*bAutoActivate=*/ true,
ENCPoolMethod::AutoRelease,
/*bPreCullCheck=*/ true);
if (ImpactVFX)
{
ImpactVFX->SetVariableVec3(FName("User.HitNormal"), HitNormal);
ImpactVFX->SetVariableLinearColor(FName("User.HitColor"), DamageColor);
}
附加的持久特效。请注意参数顺序:此处 bAutoDestroy 位于 bAutoActivate 之前。
UNiagaraComponent* TrailVFX = UNiagaraFunctionLibrary::SpawnSystemAttached(
TrailSystem,
WeaponMesh, // USceneComponent* AttachToComponent
FName("MuzzleSocket"), // FName AttachPointName
FVector::ZeroVector,
FRotator::ZeroRotator,
EAttachLocation::SnapToTarget,
/*bAutoDestroy=*/ false,
/*bAutoActivate=*/ true,
ENCPoolMethod::ManualRelease,
/*bPreCullCheck=*/ true);
另一个 SpawnSystemAttached 重载会在 Rotation 后插入 FVector Scale,随后参数顺序为 LocationType, bAutoDestroy, PoolingMethod, bAutoActivate, bPreCullCheck。请有意选择其中一个重载;两者很容易混淆。
如果希望使用具名字段,而非冗长的参数列表,SpawnSystemAtLocationWithParams 和 SpawnSystemAttachedWithParams 接受一个 FFXSystemSpawnParameters 结构体(Particles/ParticleSystemComponent.h)。该结构体包含 EPSCPoolMethod PoolingMethod,而非 ENCPoolMethod。
如果某个特效需要在同一个 Actor 上重复播放,请自行持有组件,而不是每次事件都生成一个:
// Header:
UPROPERTY(VisibleAnywhere, Category = "VFX")
TObjectPtr<UNiagaraComponent> EngineTrailVFX;
// Constructor:
EngineTrailVFX = CreateDefaultSubobject<UNiagaraComponent>(TEXT("EngineTrailVFX"));
EngineTrailVFX->SetupAttachment(GetRootComponent());
EngineTrailVFX->SetAutoActivate(false);
// Gameplay. SetAsset resets existing override parameters unless you opt out,
// so re-apply User parameters after a swap or pass false.
EngineTrailVFX->SetAsset(BoostTrailSystem, /*bResetExistingOverrideParameters=*/ true);
EngineTrailVFX->Activate(/*bReset=*/ true);
生命周期控制
NiagaraComp->Activate(/*bReset=*/ false); // resume
NiagaraComp->Activate(/*bReset=*/ true); // restart from scratch
NiagaraComp->Deactivate(); // stop spawning, let particles drain
NiagaraComp->DeactivateImmediate(); // kill particles now
NiagaraComp->ResetSystem(); // restart from time 0
NiagaraComp->ReinitializeSystem(); // full re-init; more expensive than ResetSystem
NiagaraComp->SetPaused(true);
NiagaraComp->SetAutoDestroy(true);
// Warm-up: advance age before the effect becomes visible.
NiagaraComp->SetDesiredAge(2.5f);
NiagaraComp->SeekToDesiredAge(2.5f);
// Deterministic stepping for cutscenes and tests.
NiagaraComp->AdvanceSimulation(/*TickCount=*/ 30, /*TickDeltaSeconds=*/ 0.0166f);
设置用户参数
Setter 接受包含命名空间前缀的 FName。如果名称或类型与资源不匹配,它们不会执行任何操作,也不会发出提示。
NiagaraComp->SetVariableFloat(FName("User.DamageAmount"), 150.0f);
NiagaraComp->SetVariableInt(FName("User.ProjectileCount"), 12);
NiagaraComp->SetVariableBool(FName("User.bIsCritical"), bIsCriticalHit);
NiagaraComp->SetVariableVec2(FName("User.UVOffset"), FVector2D(0.5, 0.25));
NiagaraComp->SetVariableVec3(FName("User.TargetDirection"), AimDirection);
NiagaraComp->SetVariableVec4(FName("User.CustomData"), FVector4(1.0, 0.5, 0.0, 1.0));
NiagaraComp->SetVariableLinearColor(FName("User.TintColor"), FLinearColor::Red);
NiagaraComp->SetVariableQuat(FName("User.Orientation"), GetActorQuat());
NiagaraComp->SetVariableMatrix(FName("User.LocalToTarget"), TargetMatrix);
// Positions go through the LWC-aware setter, not SetVariableVec3.
NiagaraComp->SetVariablePosition(FName("User.WorldOrigin"), WorldSpaceOrigin);
// Object-valued parameters.
NiagaraComp->SetVariableObject(FName("User.TargetMesh"), TargetMeshComponent);
NiagaraComp->SetVariableActor(FName("User.SourceActor"), this);
NiagaraComp->SetVariableMaterial(FName("User.FXMaterial"), DynamicMaterial);
NiagaraComp->SetVariableStaticMesh(FName("User.ScatterMesh"), ScatterMesh);
NiagaraComp->SetVariableTexture(FName("User.FlowMap"), FlowTexture);
NiagaraComp->SetVariableTextureRenderTarget(FName("User.SceneRT"), SceneRenderTarget);
// Getters report success through an out parameter and are [[nodiscard]].
bool bIsValid = false;
const float CurrentRate = NiagaraComp->GetVariableFloat(FName("User.EmitRate"), bIsValid);
| 命名空间前缀 | 可从 C++ 设置 |
|---|---|
User. | 是 — 唯一可在运行时覆盖的命名空间 |
System. | 否 — 由引擎拥有(Age、DeltaTime、ExecutionState) |
Emitter. | 否 — 每个发射器的模拟状态 |
Particle. | 否 — 每个粒子的模拟状态 |
Module. | 否 — 仅供堆栈节点内部使用 |
完整的 C++ 到 Niagara 类型对照表、数组函数库矩阵以及池化方法值,请参阅 niagara-parameter-types.md。
数据接口
数据接口是 UNiagaraDataInterface 子类,会以 DI 类型的 User.* 参数形式公开。使用 UNiagaraFunctionLibrary 中的类型化辅助函数绑定;这些函数将参数名称作为 const FString& 接收。
UNiagaraFunctionLibrary::OverrideSystemUserVariableSkeletalMeshComponent(
NiagaraComp, TEXT("User.SourceMesh"), GetMesh());
UNiagaraFunctionLibrary::SetSkeletalMeshDataInterfaceFilteredBones(
NiagaraComp, TEXT("User.SourceMesh"), { FName("hand_l"), FName("hand_r") });
UNiagaraFunctionLibrary::SetSkeletalMeshDataInterfaceSamplingRegions(
NiagaraComp, TEXT("User.SourceMesh"), { FName("UpperBody") });
UNiagaraFunctionLibrary::OverrideSystemUserVariableStaticMeshComponent(
NiagaraComp, TEXT("User.ScatterMesh"), ScatterMeshComponent);
UNiagaraFunctionLibrary::SetTextureObject(NiagaraComp, TEXT("User.FlowTexture"), FlowTexture);
数组 DI 是每帧推送游戏数据的主力。这些辅助函数接收 FName:
#include "NiagaraDataInterfaceArrayFunctionLibrary.h"
TArray<FVector> Waypoints = BuildWaypoints();
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayVector(
NiagaraComp, FName("User.Waypoints"), Waypoints);
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayFloatValue(
NiagaraComp, FName("User.HeatData"), /*Index=*/ 5, /*Value=*/ 0.9f, /*bSizeToFit=*/ false);
需要直接修改 DI 对象时,获取该对象:
#include "NiagaraDataInterfaceCurve.h"
UNiagaraDataInterfaceCurve* CurveDI =
UNiagaraFunctionLibrary::GetDataInterface<UNiagaraDataInterfaceCurve>(
NiagaraComp, FName("User.SpeedCurve"));
if (CurveDI)
{
CurveDI->Curve.Reset();
CurveDI->Curve.AddKey(0.0f, 0.0f);
CurveDI->Curve.AddKey(1.0f, 500.0f);
#if WITH_EDITORONLY_DATA
CurveDI->UpdateLUT(); // editor-only
#endif
// With bUseLUT (default true) CPU and GPU both sample the LUT baked at cook time
// (NiagaraDataInterfaceCurve.cpp:182), so key edits only take effect in cooked builds
// if the DI was authored with bUseLUT off.
}
非模板重载 GetDataInterface(UClass* DIClass, UNiagaraComponent*, FName) 适用于类仅在运行时才确定的情况。内置 DI 目录(含头文件路径、属性和模拟目标支持)见 niagara-data-interfaces.md。
自定义数据接口
继承 UNiagaraDataInterface(NiagaraDataInterface.h)。函数列表属于仅限编辑器的数据:重载函数 GetFunctionsInternal(TArray<FNiagaraFunctionSignature>& OutFunctions) const 声明在 #if WITH_EDITORONLY_DATA 内;此外,还需要 GetVMExternalFunction 来绑定 CPU 实现,以及 Equals / CopyToInternal 来确保实例能够正确比较和复制。GPU 支持还需实现 ProvidePerInstanceDataForRenderThread 和 PerInstanceDataPassedToRenderThreadSize。完整类模板见 niagara-data-interfaces.md。
Niagara 数据通道
数据通道是游戏代码与 Niagara 之间,以及彼此独立的系统之间受支持的桥梁。通道是描述负载的 UNiagaraDataChannelAsset;写入器发布元素,Niagara 发射器和游戏代码读取元素。
#include "NiagaraDataChannelAccessContext.h"
#include "NiagaraDataChannelAccessor.h"
#include "NiagaraDataChannelAsset.h"
#include "NiagaraDataChannelFunctionLibrary.h"
void AMyProjectile::ReportImpact(const FVector& ImpactPoint, const FVector& ImpactNormal)
{
const FNiagaraDataChannelSearchParameters SearchParams(GetRootComponent());
UNiagaraDataChannelWriter* Writer = UNiagaraDataChannelLibrary::WriteToNiagaraDataChannel(
this,
ImpactChannel, // UPROPERTY() TObjectPtr<UNiagaraDataChannelAsset>
SearchParams,
/*Count=*/ 1,
/*bVisibleToGame=*/ false,
/*bVisibleToCPU=*/ true,
/*bVisibleToGPU=*/ true,
TEXT("MyProjectileImpact"));
if (Writer)
{
Writer->WritePosition(FName("Position"), 0, ImpactPoint);
Writer->WriteVector(FName("Normal"), 0, ImpactNormal);
}
}
在游戏端读取:
void AMyProjectile::DrainImpacts()
{
const FNiagaraDataChannelSearchParameters SearchParams(GetRootComponent());
UNiagaraDataChannelReader* Reader = UNiagaraDataChannelLibrary::ReadFromNiagaraDataChannel(
this, ImpactChannel, SearchParams, /*bReadPreviousFrame=*/ true);
for (int32 Index = 0; Reader && Index < Reader->Num(); ++Index)
{
bool bValid = false;
const FVector Position = Reader->ReadPosition(FName("Position"), Index, bValid);
if (bValid)
{
SpawnDecalAt(Position);
}
}
}
SubscribeToNiagaraDataChannel(WorldContextObject, Channel, SearchParams, UpdateDelegate, UnsubscribeToken) 会在发布新元素时触发 FOnNewNiagaraDataChannelPublish 回调;其 FNiagaraDataChannelUpdateContext 包含 Reader、FirstNewDataIndex、LastNewDataIndex 和 NewElementCount。每次订阅都应使用保存的令牌调用 UnsubscribeFromNiagaraDataChannel 取消订阅。
UNiagaraDataChannelLibrary 还提供 GetDataChannelElementCount、单元素读写函数 ReadFromNiagaraDataChannelSingle / WriteToNiagaraDataChannelSingle,以及使用 FNDCAccessContextInst 而非 FNiagaraDataChannelSearchParameters 的 _WithContext 变体。搜索参数重载属于旧路径,不支持较新的通道类型;对于新通道,请优先使用上下文变体。
完成回调
OnSystemFinished 是 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnNiagaraSystemFinished, class UNiagaraComponent*, PSystem),因此处理函数必须是在类主体中声明的 UFUNCTION()。
// MyVFXComponent.h
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "MyVFXComponent.generated.h"
class UNiagaraComponent;
class UNiagaraSystem;
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class MYGAME_API UMyVFXComponent : public UActorComponent
{
GENERATED_BODY()
public:
void PlayBurst(UNiagaraSystem* System, const FVector& Location);
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
protected:
UFUNCTION()
void HandleVFXFinished(UNiagaraComponent* FinishedComponent);
UPROPERTY(Transient)
TObjectPtr<UNiagaraComponent> ActiveVFX;
};
// MyVFXComponent.cpp
#include "MyVFXComponent.h"
#include "NiagaraComponent.h"
#include "NiagaraFunctionLibrary.h"
void UMyVFXComponent::PlayBurst(UNiagaraSystem* System, const FVector& Location)
{
ActiveVFX = UNiagaraFunctionLibrary::SpawnSystemAtLocation(
this, System, Location, FRotator::ZeroRotator, FVector(1.0f),
/*bAutoDestroy=*/ false, /*bAutoActivate=*/ true, ENCPoolMethod::ManualRelease);
if (ActiveVFX)
{
ActiveVFX->OnSystemFinished.AddDynamic(this, &UMyVFXComponent::HandleVFXFinished);
}
}
void UMyVFXComponent::HandleVFXFinished(UNiagaraComponent* FinishedComponent)
{
FinishedComponent->OnSystemFinished.RemoveDynamic(this, &UMyVFXComponent::HandleVFXFinished);
FinishedComponent->ReleaseToPool();
ActiveVFX = nullptr;
}
void UMyVFXComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if (ActiveVFX)
{
ActiveVFX->OnSystemFinished.RemoveDynamic(this, &UMyVFXComponent::HandleVFXFinished);
ActiveVFX->ReleaseToPool(); // ManualRelease components leak unless released
ActiveVFX = nullptr;
}
Super::EndPlay(EndPlayReason);
}
模拟缓存
UNiagaraSimCache 会记录模拟帧并以确定性方式回放,适用于电影制作、网络可见的主角特效和回归测试。
#include "NiagaraComponent.h"
#include "NiagaraSimCache.h"
#include "NiagaraSimCacheFunctionLibrary.h"
UNiagaraSimCache* Cache = UNiagaraSimCacheFunctionLibrary::CreateNiagaraSimCache(this);
FNiagaraSimCacheCreateParameters CreateParameters;
UNiagaraSimCache* OutCache = nullptr;
UNiagaraSimCacheFunctionLibrary::CaptureNiagaraSimCacheImmediate(
Cache, CreateParameters, NiagaraComp, OutCache,
/*bAdvanceSimulation=*/ false, /*AdvanceDeltaTime=*/ 0.01666f);
// Play a cache back on any component running the same system, then hand control
// back to the live simulation.
NiagaraComp->SetSimCache(Cache, /*bResetSystem=*/ true);
NiagaraComp->ClearSimCache(/*bResetSystem=*/ true);
UNiagaraSimCache 提供 IsCacheValid()、CanRead(UNiagaraSystem*)、GetNumFrames()、GetStartSeconds() 和 GetDurationSeconds()。持有自身状态的数据接口可通过 INiagaraSimCacheCustomStorageInterface 参与其中。
轻量级发射器
发射器有两种模式,由 FNiagaraEmitterHandle::GetEmitterMode() 返回:ENiagaraEmitterMode::Standard(UNiagaraEmitter,完整脚本模拟)和 ENiagaraEmitterMode::Stateless(UNiagaraStatelessEmitter,固定成本的解析式发射器,不带逐粒子模拟缓冲区)。无状态发射器在 Niagara 编辑器中创建,CPU 和内存开销要低得多;对于环境特效和高实例数量的特效,请优先使用它们。
UNiagaraStatelessEmitter 位于模块内部的 Internal/Stateless/NiagaraStatelessEmitter.h,因此游戏模块无法包含它。像驱动其他系统一样,通过 UNiagaraComponent 和 User. 参数驱动无状态发射器。要从游戏代码中检测它们,请读取 UNiagaraFunctionLibrary::GetAllEmitters 返回的 FNiagaraMinimalEmitterInfo 中的 bIsLightweight。
组件池化
每次生成调用中的 ENCPoolMethod 都会选择池化行为:None(创建全新组件)、AutoRelease(完成时自动归还;不要在生成所在帧之后继续保留该指针)和 ManualRelease(由你调用 ReleaseToPool())。ManualRelease_OnComplete 和 FreeInPool 是隐藏的内部状态。
#include "NiagaraComponentPool.h"
#include "NiagaraWorldManager.h"
// Prime one world before a gameplay-critical moment. Call the pool directly:
// FNiagaraWorldManager::PrimePool / PrimePoolForAllWorlds are not NIAGARA_API
// (NiagaraWorldManager.h:236-238) and fail to link from a game module.
if (FNiagaraWorldManager* WorldMan = FNiagaraWorldManager::Get(GetWorld()))
{
WorldMan->GetComponentPool()->PrimePool(ExplosionSystem, GetWorld());
}
池容量是资产上的系统级属性(UFXSystemAsset 中的 MaxPoolSize、PoolPrimeSize,Particles/ParticleSystem.h:126,135);预热会创建 min(PoolPrimeSize, MaxPoolSize) 个组件,而 PoolPrimeSize 默认为 0,因此需设置该值,否则预热不会生效(NiagaraComponentPool.cpp:285)。全局 CVar:FX.NiagaraComponentPool.Enable、FX.NiagaraComponentPool.KillUnusedTime、FX.NiagaraComponentPool.CleanTime、FX.NiagaraComponentPool.Validation。
可扩展性与 Tick 行为
NiagaraComp->SetAllowScalability(true); // let the scalability manager cull this instance
NiagaraComp->SetTickBehavior(ENiagaraTickBehavior::UsePrereqs);
ENiagaraTickBehavior | 含义 |
|---|---|
UsePrereqs | 在附加关系和数据接口前置条件满足后执行 Tick。最安全,也是默认值。 |
UseComponentTickGroup | 忽略前置条件;使用组件自身的 Tick 组。 |
ForceTickFirst | 在第一个 Tick 组执行 Tick。 |
ForceTickLast | 在最后一个 Tick 组执行 Tick。 |
可扩展性配置位于分配给系统的 UNiagaraEffectType 中:SystemScalabilitySettings、EmitterScalabilitySettings、CullReaction、UpdateFrequency 和实例化的 SignificanceHandler。这些配置由数据驱动;无需针对各个平台编写 C++。
CPU 与 GPU 模拟:CPU 模拟支持所有数据接口,并可读取回数据;GPU 模拟可扩展到数量高得多的实例,但支持的数据接口较少,且若没有显式的读取回数据路径,则无法读取回数据。
确定性:对于必须在客户端之间保持一致的效果,请在 UNiagaraSystem 资产上启用固定 Tick(bFixedTickDelta / FixedTickDeltaTime,可通过 HasFixedTickDelta() 和 GetFixedTickDeltaTime() 读取),并使用 CPU 模拟。装饰性效果仅应在客户端运行——使用 IsRunningDedicatedServer() 为生成调用添加保护条件。
遮挡:SetOcclusionQueryMode(ENiagaraOcclusionQueryMode) / GetOcclusionQueryMode() 控制每个组件的遮挡查询(Default、AlwaysEnabled、AlwaysDisabled)。
Niagara Fluids(5.8 中为 Beta)新增了 GPU 流体和气体求解器,但每帧成本很高;请仅将其用于核心展示效果。
构建设置
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "Niagara", "NiagaraCore" });
只有在从 UNiagaraDataInterface 派生时才需要 "NiagaraCore"。游戏模块无法包含 Internal/ 下的头文件(例如 Internal/DataInterface/NiagaraDataInterfaceStaticMesh.h)。
已弃用 — 请勿使用
| 不要发出 | 在 5.8 中使用 | 来源 |
|---|---|---|
SetNiagaraVariableFloat(const FString&, float) 以及其他所有 SetNiagaraVariable* FString setter | SetVariableFloat(FName, float) 以及匹配的 SetVariable* FName setter | Public/NiagaraComponent.h 中的 UE_DEPRECATED(5.3) |
UNiagaraDataInterface::GetFunctions(TArray<FNiagaraFunctionSignature>&) | #if WITH_EDITORONLY_DATA 内的 GetFunctionsInternal(TArray<FNiagaraFunctionSignature>&) const | Classes/NiagaraDataInterface.h 中的 UE_DEPRECATED(5.4) |
UNiagaraDataInterface::RequiresDistanceFieldData() | RequiresGlobalDistanceField() | Classes/NiagaraDataInterface.h 中的 UE_DEPRECATED(5.4) |
UNiagaraDataInterface::ReadsEmitterParticleData(const FString&) | GetEmitterReferencesByName() | Classes/NiagaraDataInterface.h 中的 UE_DEPRECATED(5.4) |
不带参数的 UNiagaraDataInterface::PostCompile() | 接受所属系统的 PostCompile 重载 | Classes/NiagaraDataInterface.h 中的 UE_DEPRECATED(5.7) |
UNiagaraDataInterface::IsUsedByCPUEmitter() / IsUsedByGPUEmitter() | IsUsedWithCPUScript() / IsUsedWithGPUScript() | Classes/NiagaraDataInterface.h 中的 UE_DEPRECATED(5.3) |
UNiagaraComponent::GetSystemInstance() | GetSystemInstanceController() | Public/NiagaraComponent.h 中的 UE_DEPRECATED(5.0) |
| 抽象的或名称含 submix 的音频数据接口基类 | UNiagaraDataInterfaceAudioSpectrum 或 UNiagaraDataInterfaceAudioOscilloscope,二者各自都有 USoundSubmix* Submix 属性 | Classes/NiagaraDataInterfaceAudio*.h 中只有三个具体的音频 DI |
将 ENCPoolMethod::FreeInPool 作为生成参数 | None、AutoRelease 或 ManualRelease | Public/NiagaraComponentPoolMethodEnum.h 中的 UMETA(Hidden) |
常见错误
**以为没有通向 Niagara 的 C++ 事件路径:**实际上是有的。对于从游戏逻辑发送到 Niagara 的事件,请使用 Data Channels(UNiagaraDataChannelLibrary),不要切换 User. bool 并寄希望于生成脚本在正确的 tick 采样它。
**每个 tick 都生成一个组件:**在 Tick 中调用 SpawnSystemAtLocation 会每帧创建并销毁一个组件。请只创建一次组件,或仅在离散事件中使用 ENCPoolMethod::AutoRelease 生成。
**命名空间或类型错误:**对 Color 参数调用 SetVariableFloat(FName("Emitter.Speed"), 300.f) 和 SetVariableVec3 都会静默失败。作者必须将值公开为 User.Speed,setter 必须与定义的类型匹配;世界位置则应通过 SetVariablePosition 传入,以正确处理 LWC。
**忽略生成调用的返回值:**在专用服务器上以及预剔除检查拒绝生成时,返回值为 nullptr。操作组件前请先检查是否为空。
**在类外定义上使用 UFUNCTION():**该宏仅在 UCLASS 主体内有意义。在 .cpp 定义上方标记了 UFUNCTION() 的 OnSystemFinished 处理函数无法绑定;应像上文所示,在头文件中声明它。
**持有指向 AutoRelease 组件的指针:**系统完成后,池会立即回收该组件,之后访问并不安全。如果需要长期持有句柄,请使用 ManualRelease 和 ReleaseToPool()。
将数据接口当作组件处理:UpdateLUT() 属于 WITH_EDITORONLY_DATA,必须加以保护;而 MarkRenderStateDirty() 并不存在——UNiagaraDataInterface 派生自 UObject。数组变更会在下一个模拟 tick 被识别;曲线键值变更则只有在曲线 DI 的 bUseLUT 关闭时才会被识别。
相关技能
ue-materials-rendering— 粒子材质、动态材质实例、馈入 DI 的渲染目标ue-actor-component-architecture— 组件创建、附加、激活和生命周期ue-animation-system— 驱动网格采样 DI 的骨骼网格体插槽、通知和骨骼数据ue-gameplay-abilities— 由 GameplayCue 驱动的效果生成和技能范围内的 VFX 所有权ue-audio-system— 音频数据接口背后的声音子混音和频谱分析ue-async-threading— 从后台任务向 DI 馈入数据时的渲染线程和任务图规则ue-procedural-generation— 生成数组和样条线 DI 所使用的点数据和样条线数据ue-sequencer-cinematics— Level Sequences、播放、电影摄影机和 Movie Render Graph