• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

做个小工具显示UE里地形的高度图和权重图

武飞扬头像
YakSue
帮助1

目标

做一个小工具来显示UE里 Landscape(启用编辑层)的高度图和权重图。

要显示高度图和权重图,本身是不难的。不过这里想要不修改引擎源码。所以是在外部(比如项目工程模块,或插件模块)做了事情。

地形高度图和权重图的数据结构

可在 LandscapeComponent.h 中观察到数据结构。

在启用编辑层的情况下,数据在LayersData中,每个编辑层对应一个GUID

UPROPERTY()
TMap<FGuid, FLandscapeLayerComponentData> LayersData;

每个 FLandscapeLayerComponentData包含一个FHeightmapData和一个FWeightmapData

USTRUCT(NotBlueprintable)
struct FLandscapeLayerComponentData
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	FHeightmapData HeightmapData;

	UPROPERTY()
	FWeightmapData WeightmapData;

	bool IsInitialized() const { return HeightmapData.Texture != nullptr || WeightmapData.Textures.Num() > 0;  }
};

FHeightmapData包含一个贴图:

USTRUCT(NotBlueprintable)
struct FHeightmapData
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	UTexture2D* Texture;
};

FWeightmapData包含多个贴图(因为可能有很多权重层):

USTRUCT(NotBlueprintable)
struct FWeightmapData
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	TArray<UTexture2D*> Textures;
	
	UPROPERTY()
	TArray<FWeightmapLayerAllocationInfo> LayerAllocations;

	UPROPERTY(Transient)
	TArray<ULandscapeWeightmapUsage*> TextureUsages;
};

小工具

流程和之前一样,先定义一个UObject。

为了能在Detail面板看到相关的贴图,这里将原来的结构体换成了新的后缀为 _vis 的结构体,并将UProperty加上VisibleAnywhere。然后,提供一个按钮,也就是FindLandscapeTextures()函数,触发后找到世界中的地形,并将其数据复制过来。(目前,只观察第一个找到的地形的第一个Component)

代码如下:

LandscapeTextureWatcher.h

#pragma once

#include "UObject/Object.h"
#include "Landscape/Classes/LandscapeComponent.h"

#include "LandscapeTextureWatcher.generated.h"

USTRUCT(NotBlueprintable)
struct FWeightmapData_vis
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(VisibleAnywhere)
	TArray<UTexture2D*> Textures;
	
	UPROPERTY(VisibleAnywhere)
	TArray<FWeightmapLayerAllocationInfo> LayerAllocations;

	UPROPERTY(Transient)
	TArray<ULandscapeWeightmapUsage*> TextureUsages;
};

USTRUCT(NotBlueprintable)
struct FHeightmapData_vis
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(VisibleAnywhere)
	UTexture2D* Texture;
};

USTRUCT(NotBlueprintable)
struct FLandscapeLayerComponentData_vis
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(VisibleAnywhere)
	FHeightmapData_vis HeightmapData;

	UPROPERTY(VisibleAnywhere)
	FWeightmapData_vis WeightmapData;

	bool IsInitialized() const { return HeightmapData.Texture != nullptr || WeightmapData.Textures.Num() > 0;  }
};

UCLASS(Blueprintable)
class ULandscapeTextureWatcher : public UObject
{
	GENERATED_UCLASS_BODY()
public:
	
	//按钮,点击后就把地形的纹理数据拿来
	UFUNCTION(CallInEditor)
	void FindLandscapeTextures();

	//要观察的地形纹理数据:
	UPROPERTY(VisibleAnywhere)
	TMap<FGuid, FLandscapeLayerComponentData_vis> LayersData;
};

学新通

LandscapeTextureWatcher.cpp

#include "LandscapeTextureWatcher.h"
#include "Kismet/GameplayStatics.h"
#include "Editor.h"
#include "LandscapeInfo.h"
#include "Landscape/Classes/Landscape.h"

ULandscapeTextureWatcher::ULandscapeTextureWatcher(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{}

void ULandscapeTextureWatcher::FindLandscapeTextures()
{
	//得到World
	const UWorld* World = GEditor->GetEditorWorldContext().World();

	//找地形:
	TArray<AActor*> OutActors;
	UGameplayStatics::GetAllActorsOfClass(World, ALandscape::StaticClass(), OutActors);
	//没找到则直接返回
	if (OutActors.Num() == 0)
		return;
	//找到则用第一个Landscape:
	ALandscape* Landscape = (ALandscape*)OutActors[0];

	if (Landscape->LandscapeComponents.Num() == 0)
		return;
	//使用第一个Component:
	ULandscapeComponent* LandscapeComponent = Landscape->LandscapeComponents[0];

	//遍历所有layer,填入数据
	LandscapeComponent->ForEachLayer([&](const FGuid& LayerGuid, FLandscapeLayerComponentData& LayerData)
	{
		FLandscapeLayerComponentData_vis data;
		data.HeightmapData.Texture = LayerData.HeightmapData.Texture;
		data.WeightmapData.Textures = LayerData.WeightmapData.Textures;
		LayersData.Add(LayerGuid, data);
	});
}
学新通

然后,仿照之前第(3)步,显示其Detail面板。

效果

开启编辑层功能创建地形,注意只创建一个Component(因为暂时只观察第一个Component)
创建两个编辑层,并且使用的地形材质有五个权重层。
结果如下:
学新通
虽然上面看到贴图是黑的,但是因为Alpha通道是0,可以直接打开贴图关闭alpha通道看效果。

高度图:
学新通

权重图,可以看出每层各占一个通道:
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgakief
系列文章
更多 icon
同类精品
更多 icon
继续加载