虚幻5 Unrealsharp EditorTick + Nanite雪地踩坑记录

虚幻5 UnrealSharp EditorTick + Nanite 雪地踩坑记录

最近在使用 UE5 和 UnrealSharp 结合开发时,遇到了一些在编辑器内实时更新(EditorTick)以及 Nanite 细分材质(针对雪地交互)相关的坑。这篇文章主要记录一下我是如何在 UnrealSharp 环境下实现 Editor 里的实时 Tick,以及解决 Nanite 雪地顶点偏移导致的奇怪阴影问题,希望能帮到遇到同类问题的朋友。


一、如何使用 UnrealSharp 在 Editor 中进行 Tick

在开发一些编辑器工具或者需要实时反馈的关卡交互(比如拖动雪地上的物体实时生成雪地轨迹)时,我们需要 Actor 在 Editor 环境下(未点击运行 Play 时)也能执行更新逻辑。

在 UnrealSharp 中实现这一功能,可以通过继承 AEditorUtilityActor 并借助定时器来完成。

核心实现步骤

  1. 继承特定基类 :确保你的类继承自 AEditorUtilityActor。
  2. 开启 Tick 权限 :在构造函数中,强制开启编辑器下的 Tick 相关属性:
    • AllowTickBeforeBeginPlay = true;
    • ActorTickEnabled = true;
    • TickableWhenPaused = true;
  3. 设置循环定时器 :在 Run 方法或者构造函数或者自己写个UFunction(CallInEditor = true)函数(然后再编辑器调用)中,通过 SystemLibrary.SetTimer 设置一个高频的定时任务(例如模拟 60 帧更新的 1 / 60f)。
  4. 暴露编辑器函数 :使用 [UFunction(CallInEditor = true)] 标记你的更新函数,使其能在编辑器环境下被正确调用。

完整代码示例

以下是实现雪地物体实时捕获更新的 C# 脚本:

csharp 复制代码
using UnrealSharp;
using UnrealSharp.Attributes;
using UnrealSharp.Engine;
using ManagedPlayground;
using UnrealSharp.Niagara;
using UnrealSharp.Blutility;
using UnrealSharp.CoreUObject;

namespace ManagedSharpProject;

[UClass]
public class ASnowObject : AEditorUtilityActor
{
    [UProperty(DefaultComponent =true, RootComponent =true)]
    public UStaticMeshComponent Mesh { get; set; }
    [UProperty(PropertyFlags.EditAnywhere | PropertyFlags.BlueprintReadWrite)]
    public ASceneCapture2D SceneCapture { get; set; }

    public ASnowObject() {
        AllowTickBeforeBeginPlay = true;
        ActorTickEnabled = true;
        TickableWhenPaused = true;
        SystemLibrary.SetTimer(SnowUpdate, 1 / 60f, true);
    }
    public override void Run() {
        base.Run();
        PrintString("SnowObject Run");
        SystemLibrary.SetTimer(SnowUpdate, 1 / 60f, true);
    }

    [UFunction(CallInEditor = true)]
    public void Start() {
        PrintString("SnowObject Start");
        SystemLibrary.SetTimer(SnowUpdate, 1 / 60f, true);
    }
    float sumTime = 0;
    FTransform LastTransform;

    [UFunction(CallInEditor = true)]
    public  void SnowUpdate() {
        if(ActorTransform == LastTransform) {
            return;
        }
        LastTransform = ActorTransform;

        if (!SceneCapture)
            return;
        var comp = SceneCapture.GetComponentByClass<USceneCaptureComponent2D>();
        comp.ShowOnlyActors.Add(this);
        SystemLibrary.SetTimerForNextTick(this, "DisableSnowUpdate");
    }
    [UFunction(CallInEditor = true)]
    public void DisableSnowUpdate() 
    { 
        if (!SceneCapture)
            return;
        var comp = SceneCapture.GetComponentByClass<USceneCaptureComponent2D>();
        comp.ShowOnlyActors.Remove(this);
    }
    
}

二、避坑指南:Nanite 细分后的雪地顶点偏移阴影异常

在使用 UE5.3+ 开启 Nanite 细分(Tessellation)制作雪地脚印或轨迹时,你可能会遇到一个很让人头疼的问题:雪地材质在进行顶点偏移(World Position Offset / Displacement)后,投射或接收的阴影看起来非常奇怪,甚至出现破面和黑斑。

经过反复测试,解决这个问题的核心在于如何控制偏移量:

  • 🚫 错误做法:直接修改细分的 Magnitude (位移强度)
    很多人为了控制雪坑的深度,会直接在材质节点里去拉伸 Displacement 的 Magnitude 节点。这会导致 Nanite 几何体在生成阴影缓存时无法正确匹配偏移后的物理位置,从而产生极度不自然的阴影错位。
  • ✅ 正确做法:手动计算偏移程度
    不要修改细分 magnitude 。保持细分的 Magnitude 恒定或者使用默认的安全值。如果需要控制雪地不同区域(比如被踩下的区域)的凹陷程度,应该在材质逻辑中,通过手动计算顶点的高度差,直接作用于 World Position Offset (世界位置偏移) 。通过 Mask 或者渲染目标(SceneCapture 捕获的轨迹)去影响 WPO 的计算结果,这样引擎在处理 Nanite 阴影时能够得到更准确的法线和位置反馈。
相关推荐
mengzhi啊2 天前
UE5 沙漠添加植物,然后在湖泊游泳。关键词:湖泊使用蓝图的重叠事件,湖泊的碰撞偏移。所有的物体都可以使用蓝图来使用它
ue5
Zhichao_979 天前
【UE5.8】VS2026安装
ue5
DolitD10 天前
UE像素流与云渲染技术方案对比分析
3d·云原生·ue5·云计算·图形渲染
Дерек的学习记录11 天前
Unreal Engine 5:第三人称运动系统和人物动画
开发语言·学习·ue5
努力学习的小廉14 天前
UE5 入门系列(三):核心框架类全解析
ue5
平行云15 天前
建筑BIM/3D可视化轻量级实时评审与分享方案
unity·ue5·3dsmax·实时云渲染·云桌面·云游戏·建筑bim
BugPhysician20 天前
影之刃零首发UE崩溃排查:着色器缓存、虚拟内存与驱动版本
ue5·影之刃零·影之刃零报错·影之刃零进不去·ue崩溃·ue引擎崩溃·ue5引擎崩溃
电子云与长程纠缠22 天前
UE5魂系游戏开发教程05
开发语言·学习·游戏·ui·ue5
fanfan_hongyun22 天前
UE5.1 蓝图调用C++方法
ue5
易知微EasyV数据可视化22 天前
UE5 中接入 GDAL:从vcpkg编译到插件打包
ue5