mcpField
U
ue-niagara-effects

ue-niagara-effects

github.com/quodsoler开发4191.2k 次安装4 周前更新
代码仓库

关于 ue-niagara-effects

面向 UE 5.8 的 Niagara 与 C++ 游戏逻辑集成编码技能,涵盖系统生成和控制、用户数据传入、数据通道、模拟缓存及效果性能管理。

主要功能

  1. 01生成并控制 Niagara 系统
  2. 02设置运行时用户参数
  3. 03绑定数据接口与数组
  4. 04发布和读取 Niagara Data Channels
  5. 05使用模拟缓存与组件池

适用场景

  1. 01根据游戏事件触发命中特效
  2. 02将持续轨迹附加到组件
  3. 03向 Niagara 传递游戏数据
  4. 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 setterSetVariableFloat(FName, float) 以及匹配的 SetVariable* FName setterPublic/NiagaraComponent.h 中的 UE_DEPRECATED(5.3)
UNiagaraDataInterface::GetFunctions(TArray<FNiagaraFunctionSignature>&)#if WITH_EDITORONLY_DATA 内的 GetFunctionsInternal(TArray<FNiagaraFunctionSignature>&) constClasses/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 或 ManualReleasePublic/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

评论

支持 Markdown