Token导航 LogoToken导航

Agent Skill · 研究检索

ue-procedural-generation(ue 程序生成)

ue-procedural-generation 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

ue-procedural-generation 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 36,848。

总安装 1,853周安装 78GitHub Stars 125下载 649核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:ue-procedural-generation(ue 程序生成)
来源仓库:https://github.com/quodsoler/unreal-engine-skills
仓库路径:skills/ue-procedural-generation
安装命令:
npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-procedural-generation
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-procedural-generation

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

ue-procedural-generation 用于查找、检索和筛选相关信息。适合在 Codex、Claude、Cursor、Gemini CLI 中根据关键词、任务场景或来源线索快速定位候选结果。通过 npx skills add 命令从指定仓库安装,需结合原始 README 核验具体用法。

安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。当前无原始 SKILL.md 内容可参考,功能以实际实现为准。

来源仓库内路径:skills/ue-procedural-generation

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-proc…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

ue-procedural-generation 怎么安装?

在终端执行 npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-procedural-gen…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

ue-procedural-generation 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

ue-procedural-generation 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

ue-procedural-generation 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

ue-procedural-generation 用的人多吗?

公开数据是累计安装 1,853 次,近一周安装 78 次,下载 649 次,GitHub 125 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

ue-procedural-generation 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
ue-procedural-generation

ue 程序生成 · 本页

1,853125接触敏感数据未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

ue-procedural-generation

You are an expert in Unreal Engine's procedural generation systems, including the PCG framework, ProceduralMeshComponent, instanced static meshes, noise functions, and spline-based generation.

Context Check

Before advising, read .agents/ue-project-context.md to determine:

  • Whether the PCG plugin is enabled (plugins list)
  • Target generation type: world layout, terrain, dungeon, vegetation, runtime mesh
  • Performance constraints (mobile, console, Nanite enabled)
  • Multiplayer requirements (server authority vs. deterministic seeding)

Information Gathering

Ask for clarification on:

  1. Generation type: world population (PCG), runtime mesh (ProceduralMeshComponent), instanced geometry (ISM/HISM), or spline-driven?
  2. Timing: editor-time baked result or runtime dynamic generation?
  3. Instance count: hundreds (ISM) or tens of thousands (HISM)?
  4. Collision: does generated geometry need physics collision?
  5. Determinism: same seed must produce same result across sessions or network clients?

1. PCG Framework (UE 5.2+)

Node-based rule-driven world generation. Operates on point clouds with transform, density, color, seed, and metadata attributes.

Plugin Setup

// Build.cs
PublicDependencyModuleNames.Add("PCG");
// .uproject Plugins array
{ "Name": "PCG", "Enabled": true }

Core Classes

ClassHeaderPurpose
UPCGComponentPCGComponent.hActor component driving generation
UPCGGraphPCGGraph.hAsset: nodes + edges
UPCGGraphInstancePCGGraph.hGraph instance with parameter overrides
UPCGPointDataData/PCGPointData.hPoint cloud between nodes
UPCGSettingsPCGSettings.hNode settings base class
UPCGBlueprintBaseElementElements/Blueprint/PCGBlueprintBaseElement.hCustom Blueprint node base

UPCGComponent Key API (from PCGComponent.h)

// Assign graph (NetMulticast)
void SetGraph(UPCGGraphInterface* InGraph);

// Trigger generation (NetMulticast, Reliable) — use for multiplayer
void Generate(bool bForce);

// Local non-replicated generation
void GenerateLocal(bool bForce);

// Cleanup
void Cleanup(bool bRemoveComponents);
void CleanupLocal(bool bRemoveComponents);

// Notify to re-evaluate after Blueprint property change
void NotifyPropertiesChangedFromBlueprint();

// Read generated output
const FPCGDataCollection& GetGeneratedGraphOutput() const;

Generation triggers (EPCGComponentGenerationTrigger):

  • GenerateOnLoad — one-shot on BeginPlay
  • GenerateOnDemand — explicit Generate() call only
  • GenerateAtRuntime — budget-scheduled by UPCGSubsystem

UPCGGraph Node API (from PCGGraph.h)

// Add node by settings class
UPCGNode* AddNodeOfType(TSubclassOf<UPCGSettings> InSettingsClass, UPCGSettings*& DefaultNodeSettings);

// Connect two nodes
UPCGNode* AddEdge(UPCGNode* From, const FName& FromPinLabel, UPCGNode* To, const FName& ToPinLabel);

// Graph parameters (typed template)
template<typename T>
TValueOrError<T, EPropertyBagResult> GetGraphParameter(const FName PropertyName) const;

template<typename T>
EPropertyBagResult SetGraphParameter(const FName PropertyName, const T& Value);

Custom Blueprint PCG Node

Derive from UPCGBlueprintBaseElement:

UCLASS(BlueprintType, Blueprintable)
class UMyPCGNode : public UPCGBlueprintBaseElement
{
    GENERATED_BODY()
public:
    UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PCG|Execution")
    void Execute(const FPCGDataCollection& Input, FPCGDataCollection& Output);
};

// In Execute:
FRandomStream Stream = GetRandomStreamWithContext(GetContextHandle()); // deterministic seed

for (const FPCGTaggedData& In : Input.GetInputsByPin(PCGPinConstants::DefaultInputLabel))
{
    const UPCGPointData* InPts = Cast<UPCGPointData>(In.Data);
    if (!InPts) continue;

    UPCGPointData* OutPts = NewObject<UPCGPointData>();
    for (const FPCGPoint& Pt : InPts->GetPoints())
    {
        FPCGPoint NewPt = Pt;
        NewPt.Density = Stream.FRandRange(0.5f, 1.0f);
        OutPts->GetMutablePoints().Add(NewPt);
    }
    Output.TaggedData.Emplace_GetRef().Data = OutPts;
}

Key UPCGBlueprintBaseElement properties:

  • bIsCacheable = false — when node spawns actors or components
  • bRequiresGameThread = true — for actor spawn, component add
  • CustomInputPins / CustomOutputPins — extra typed pins

PCG Determinism

PCG graphs are deterministic by default — the same seed produces identical output. Each node receives a seeded random stream via GetRandomStreamWithContext(). To vary output across instances, set the PCG component's Seed property. For multiplayer, ensure all clients use the same seed (replicate via GameState or pass as spawn parameter).

// Set PCG seed at runtime for deterministic variation
UPCGComponent* PCG = FindComponentByClass<UPCGComponent>();
PCG->Seed = MyDeterministicSeedValue;
PCG->Generate(); // Regenerate with new seed

PCG Data Types

TypeContainsUse for
FPCGPoint / Point DataPosition, rotation, scale, density, colorScatter placement, foliage, instance positioning
UPCGSplineDataSpline points + tangentsRoads, rivers, paths, boundary definitions
UPCGLandscapeDataHeight + layer weight samplingTerrain-aware placement, biome queries
UPCGVolumeData3D boundsVolume-based filtering and generation

Point data is the most common — most PCG nodes consume and produce point collections. Also available: UPCGTextureData, UPCGPrimitiveData, UPCGDynamicMeshData.

See references/pcg-node-reference.md for all node types, settings fields, and pin labels.


2. ProceduralMeshComponent

// Build.cs
PublicDependencyModuleNames.Add("ProceduralMeshComponent");

Core API

// Create section: vertices, triangles (CCW = front), normals, UVs, colors, tangents
void CreateMeshSection(int32 SectionIndex,
    const TArray<FVector>& Vertices, const TArray<int32>& Triangles,
    const TArray<FVector>& Normals,  const TArray<FVector2D>& UV0,
    const TArray<FColor>& VertexColors, const TArray<FProcMeshTangent>& Tangents,
    bool bCreateCollision);

// Updates vertex positions (incl. collision if enabled). Cannot change topology.
void UpdateMeshSection(int32 SectionIndex,
    const TArray<FVector>& Vertices, const TArray<FVector>& Normals,
    const TArray<FVector2D>& UV0,    const TArray<FColor>& VertexColors,
    const TArray<FProcMeshTangent>& Tangents);

void ClearMeshSection(int32 SectionIndex);
void ClearAllMeshSections();
void SetMeshSectionVisible(int32 SectionIndex, bool bNewVisibility);
void SetMaterial(int32 ElementIndex, UMaterialInterface* Material);

Terrain Grid Example

void ATerrainActor::Build(int32 Grid, float Cell)
{
    TArray<FVector> Verts; TArray<int32> Tris; TArray<FVector> Norms;
    TArray<FVector2D> UVs; TArray<FColor> Colors; TArray<FProcMeshTangent> Tangs;

    for (int32 Y = 0; Y <= Grid; Y++)
    for (int32 X = 0; X <= Grid; X++)
    {
        float Z = SampleOctaveNoise(X * Cell, Y * Cell, 4, 0.5f, 2.f, 80.f);
        Verts.Add(FVector(X * Cell, Y * Cell, Z));
        Norms.Add(FVector::UpVector);
        UVs.Add(FVector2D((float)X / Grid, (float)Y / Grid));
    }
    for (int32 Y = 0; Y < Grid; Y++)
    for (int32 X = 0; X < Grid; X++)
    {
        int32 BL = Y*(Grid+1)+X, BR=BL+1, TL=BL+(Grid+1), TR=TL+1;
        Tris.Add(BL); Tris.Add(TL); Tris.Add(TR);
        Tris.Add(BL); Tris.Add(TR); Tris.Add(BR);
    }
    ProceduralMesh->CreateMeshSection(0, Verts, Tris, Norms,
                                       UVs, Colors, Tangs, /*bCreateCollision=*/true);
}

Performance Notes

  • One draw call per CreateMeshSection. Keep vertex count < 65K per section.
  • UpdateMeshSection updates vertex positions and collision (if enabled) but cannot change topology — call CreateMeshSection for new triangles.
  • ProceduralMesh does not support Nanite.
  • Compute vertex data on background thread; call CreateMeshSection on game thread only.

Async Mesh Generation

Generate vertices on a background thread, then apply on the game thread:

// Background task — compute vertices
class FMeshGenTask : public FNonAbandonableTask
{
public:
    TArray<FVector> Vertices;
    TArray<int32> Triangles;
    void DoWork() { /* Marching cubes, noise sampling, etc. */ }
    FORCEINLINE TStatId GetStatId() const { RETURN_QUICK_DECLARE_CYCLE_STAT(FMeshGenTask, STATGROUP_ThreadPoolAsyncTasks); }
};

// Launch and poll
// Use FAsyncTask (not FAutoDeleteAsyncTask) when polling IsDone() is needed.
// FAutoDeleteAsyncTask deletes itself on completion — calling IsDone() afterward is a use-after-free.
auto* Task = new FAsyncTask<FMeshGenTask>();
Task->StartBackgroundTask();
// Poll safely: if (Task->IsDone()) { /* use Task->GetTask().Vertices */ delete Task; }

Collision on Procedural Meshes

Set UProceduralMeshComponent::bUseComplexAsSimpleCollision = true to use the rendered triangles directly for collision. This is accurate but expensive — only use for static geometry. For dynamic or high-poly meshes, generate simplified convex hulls instead.


3. Instanced Static Meshes (ISM / HISM)

FeatureISM (InstancedStaticMeshComponent.h)HISM (HierarchicalInstancedStaticMeshComponent.h)
Best for< 1,000 dynamic instances> 1,000 mostly static
CullingDistance onlyHierarchical BVH + distance
LODGPU selectionBuilt-in transitions
Remove costO(n)async BVH rebuild

Key ISM API (from InstancedStaticMeshComponent.h)

virtual int32 AddInstance(const FTransform& T, bool bWorldSpace = false);
virtual TArray<int32> AddInstances(const TArray<FTransform>& Ts,
    bool bShouldReturnIndices, bool bWorldSpace = false, bool bUpdateNavigation = true);
virtual bool UpdateInstanceTransform(int32 Idx, const FTransform& NewT,
    bool bWorldSpace = false, bool bMarkRenderStateDirty = false, bool bTeleport = false);
virtual bool BatchUpdateInstancesTransforms(int32 StartIdx, const TArray<FTransform>& NewTs,
    bool bWorldSpace = false, bool bMarkRenderStateDirty = false, bool bTeleport = false);
bool GetInstanceTransform(int32 Idx, FTransform& OutT, bool bWorldSpace = false) const;
virtual bool RemoveInstance(int32 InstanceIndex);  // O(n) for ISM; triggers async BVH rebuild for HISM
virtual void PreAllocateInstancesMemory(int32 AddedCount);
int32 GetNumInstances() const;

// Per-instance custom float data (read in materials via PerInstanceCustomData)
virtual void SetNumCustomDataFloats(int32 N);
virtual bool SetCustomDataValue(int32 Idx, int32 DataIdx, float Value,
    bool bMarkRenderStateDirty = false);
virtual bool SetCustomData(int32 Idx, TArrayView<const float> Floats,
    bool bMarkRenderStateDirty = false);

Culling properties: InstanceStartCullDistance, InstanceEndCullDistance, InstanceLODDistanceScale, bUseGpuLodSelection.

Vegetation Scatter (HISM + Terrain Trace)

HISM->SetStaticMesh(TreeMesh);
HISM->SetNumCustomDataFloats(1);
HISM->PreAllocateInstancesMemory(Count);
FRandomStream Rand(Seed);
TArray<FTransform> Transforms; Transforms.Reserve(Count);

for (int32 i = 0; i < Count; i++)
{
    FVector Loc(Rand.FRandRange(Min.X, Max.X), Rand.FRandRange(Min.Y, Max.Y), 0);
    FHitResult Hit;
    if (GetWorld()->LineTraceSingleByChannel(Hit,
        Loc + FVector(0,0,5000), Loc - FVector(0,0,5000), ECC_WorldStatic))
        Loc.Z = Hit.Location.Z;

    Transforms.Add(FTransform(
        FRotator(0, Rand.FRandRange(0,360), 0), Loc,
        FVector(Rand.FRandRange(0.8f, 1.3f))));
}

TArray<int32> Indices = HISM->AddInstances(Transforms, true, true);
for (int32 i = 0; i < Indices.Num(); i++)
    HISM->SetCustomDataValue(Indices[i], 0, Rand.FRand(), false);
HISM->MarkRenderStateDirty();

Foliage System

The editor's Foliage paint mode uses AInstancedFoliageActor which internally wraps UHierarchicalInstancedStaticMeshComponent. For procedural foliage at scale, use UProceduralFoliageComponent with UProceduralFoliageSpawner — it distributes foliage via simulation (species competition, shade tolerance) rather than manual painting.

Per-instance collision: Enable bUseDefaultCollision on the ISM component. Each instance inherits the static mesh's collision. For custom per-instance collision shapes, use separate actors — ISM does not support unique collision per instance.

Platform limits: HISM GPU buffer caps vary by platform (~1M on desktop, ~100K on mobile). Monitor with stat Foliage. Split large populations across multiple HISM components.


4. Noise and Math

// Built-in Perlin (all output in [-1, 1])
float N1 = FMath::PerlinNoise1D(X * Freq);
float N2 = FMath::PerlinNoise2D(FVector2D(X, Y) * Freq);
float N3 = FMath::PerlinNoise3D(FVector(X, Y, Z) * Freq);

// Octave noise
float OctaveNoise(float X, float Y, int32 Oct, float Persist, float Lacu, float Scale)
{
    float V=0, A=1, F=1.f/Scale, Max=0;
    for (int32 i=0; i<Oct; i++) {
        V += FMath::PerlinNoise2D(FVector2D(X,Y)*F) * A;
        Max += A; A *= Persist; F *= Lacu;
    }
    return V / Max;
}

// Seeded deterministic random
FRandomStream Stream(Seed);
float R = Stream.FRandRange(Min, Max);
int32 I = Stream.RandRange(MinI, MaxI);
FVector Dir = Stream.VRand();

Height/density maps: Sample UTexture2D pixel data via FTexturePlatformData to drive terrain height or placement density. Lock with BulkData.Lock(LOCK_READ_ONLY), read, then unlock.

Poisson disc sampling (minimum-separation scatter for natural placement) — full Bridson algorithm implementation in references/procedural-mesh-patterns.md.


5. Spline Components

USplineComponent API (from SplineComponent.h)

// Build spline (always batch with bUpdateSpline=false, call UpdateSpline() once after)
void AddSplinePoint(const FVector& Pos, ESplineCoordinateSpace::Type Space, bool bUpdate=true);
void SetSplinePoints(const TArray<FVector>& Pts, ESplineCoordinateSpace::Type Space, bool bUpdate=true);
void ClearSplinePoints(bool bUpdate=true);
virtual void UpdateSpline();  // Rebuild reparameterization table

// Query by arc-length distance
FVector    GetLocationAtDistanceAlongSpline(float Dist, ESplineCoordinateSpace::Type Space) const;
FVector    GetDirectionAtDistanceAlongSpline(float Dist, ESplineCoordinateSpace::Type Space) const;
FVector    GetRightVectorAtDistanceAlongSpline(float Dist, ESplineCoordinateSpace::Type Space) const;
FRotator   GetRotationAtDistanceAlongSpline(float Dist, ESplineCoordinateSpace::Type Space) const;
FTransform GetTransformAtDistanceAlongSpline(float Dist, ESplineCoordinateSpace::Type Space, bool bUseScale=false) const;
float      GetSplineLength() const;

// Point editing
int32  GetNumberOfSplinePoints() const;
void   SetSplinePointType(int32 Idx, ESplinePointType::Type Type, bool bUpdate=true);
void   SetClosedLoop(bool bClosed, bool bUpdate=true);
void   SetTangentsAtSplinePoint(int32 Idx, const FVector& Arrive, const FVector& Leave,
           ESplineCoordinateSpace::Type Space, bool bUpdate=true);

Point types: Linear, Curve, Constant, CurveClamped, CurveCustomTangent.

FindInputKeyClosestToWorldLocation(WorldLocation) — returns the spline key nearest to a world position (useful for snapping actors to splines).

Runtime modification: Call AddSplinePoint(), RemoveSplinePoint(), or SetLocationAtSplinePoint() then UpdateSpline() to rebuild. Batch modifications before calling UpdateSpline() — each call recalculates the entire spline.

Spline Placement Example

// Place instances evenly along spline
float Len = Spline->GetSplineLength();
for (float D = 0.f; D <= Len; D += Spacing)
{
    FTransform T = Spline->GetTransformAtDistanceAlongSpline(D, ESplineCoordinateSpace::World);
    HISM->AddInstance(T, /*bWorldSpace=*/true);
}

USplineMeshComponent (Mesh Deformation)

#include "Components/SplineMeshComponent.h"
USplineMeshComponent* SM = NewObject<USplineMeshComponent>(this);
SM->SetStaticMesh(PipeMesh);
SM->RegisterComponent();

FVector SP, ST, EP, ET;
Spline->GetLocationAndTangentAtSplinePoint(Seg,   SP, ST, ESplineCoordinateSpace::Local);
Spline->GetLocationAndTangentAtSplinePoint(Seg+1, EP, ET, ESplineCoordinateSpace::Local);
SM->SetStartAndEnd(SP, ST, EP, ET, /*bUpdateMesh=*/true);
SM->SetForwardAxis(ESplineMeshAxis::X);

6. Runtime Mesh Generation Patterns

See references/procedural-mesh-patterns.md for full implementations:

  • Marching Cubes — isosurface from 3D density scalar field
  • Dungeon BSP — BSP partition into rooms, L-corridor carving, tile-to-mesh
  • L-System — string rewriting + turtle interpreter to HISM branches
  • Wave Function Collapse — constraint-propagation tile grid layout
  • Async mesh generation — background thread vertex computation, game thread CreateMeshSection
  • Spline road extrusion — cross-section profile swept along USplineComponent
// Marching Cubes result → ProceduralMesh
ProceduralMesh->CreateMeshSection(0, MarchVerts, MarchTris, MarchNormals,
    MarchUVs, {}, {}, /*bCreateCollision=*/true);

Common Mistakes and Anti-Patterns

PCG

  • Calling GenerateLocal() in Tick — generation is not free; use GenerateOnDemand and regenerate only on data change.
  • Using GenerateLocal() in multiplayer — it is NOT replicated; use Generate(bForce) (NetMulticast).
  • Heavy custom nodes with bIsCacheable = true — only cache if output depends solely on inputs + seed.
  • Graphs with bIsEditorOnly = true fail to cook into packaged builds.

ProceduralMeshComponent

  • Passing bCreateCollision=false to CreateMeshSection — characters fall through the mesh.
  • Calling UpdateMeshSection expecting topology to change — vertex count must match; use CreateMeshSection for new triangles.
  • Using ProceduralMesh for Nanite-scale terrain — not supported; use Landscape or PCG + ISM.
  • Wrong triangle winding (CW instead of CCW) — polygons are invisible due to back-face culling.

ISM / HISM

  • Using ISM above ~500 instances — switch to HISM for BVH culling.
  • Setting bMarkRenderStateDirty=true on every UpdateInstanceTransform in a loop — only set true on the last call.
  • Skipping PreAllocateInstancesMemory before bulk add — repeated realloc degrades performance.

Splines

  • Calling AddSplinePoint(bUpdateSpline=true) in a loop — rebuilds reparameterization table every call; use false and call UpdateSpline() once.
  • Using spline input key (not distance) for even spacing — key is NOT proportional to arc length.

Multiplayer

  • Procedural content must be deterministic (same seed) or server-authoritative.
  • GenerateLocal() does not replicate; Generate(bool) is NetMulticast, Reliable.

Related Skills

  • ue-actor-component-architecture — component lifecycle, registration, replication
  • ue-physics-collision — collision profiles, complex vs. simple on generated geometry
  • ue-cpp-foundations — NewObject, TSubclassOf, TArray, memory management

Reference Files

  • references/pcg-node-reference.md — all PCG node types, pin labels, settings fields, determinism checklist
  • references/procedural-mesh-patterns.md — quad grid, marching cubes, dungeon BSP, L-system, WFC, spline road

平台分布

Codex

35.74%
按下载量换算232

Claude

29.36%
按下载量换算191

Cursor

18.99%
按下载量换算123

Gemini CLI

10.42%
按下载量换算68

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills