虚幻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 阴影时能够得到更准确的法线和位置反馈。
相关推荐
吴梓穆17 小时前
UE5 .uproject右键菜单没有Generate Visual Studio Project Files
ide·ue5·visual studio
电子云与长程纠缠3 天前
UE5制作六边形包裹球体效果
开发语言·python·ue5
平行云5 天前
实时云渲染平台数据通道,支持3D应用文件上传下载分享无缝交互
linux·unity·云原生·ue5·gpu算力·实时云渲染·像素流送
吴梓穆7 天前
UE5 材质参数集
ue5·材质
weixin_404679317 天前
虚幻5 学习笔记
笔记·学习·ue5
吴梓穆7 天前
UE5 PBR模式半透明效果
ue5
晴夏。9 天前
UE和unlua对于同一个对象的协同处理
ue5
归真仙人10 天前
【UE】Lightmass可执行文件已经过时
ue5·游戏引擎·ue4·虚幻·unreal engine
DoomGT11 天前
Design - 一些免费图标网站
ue5·ue4·虚幻·虚幻引擎·unreal engine