UE5C++代码自定义一个Mesh

直接展示效果图(通过4个点来绘制一个面)

 在UE5中创建一个自己的绘制MeshC++脚本继承自Actor

.h文件

// Fill out your copyright notice in the Description page of Project Settings.


#include "AMyProceduralMeshActor.h"

// Sets default values
AAMyProceduralMeshActor::AAMyProceduralMeshActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	// 创建 Procedural Mesh 组件并附加到 RootComponent
	ProceduralMesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("ProceduralMesh"));
	RootComponent = ProceduralMesh;
}

// Called when the game starts or when spawned
void AAMyProceduralMeshActor::BeginPlay()
{
	Super::BeginPlay();
	// 生成网格
}

// Called every frame
void AAMyProceduralMeshActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void AAMyProceduralMeshActor::GenerateMesh(int Index,TArray<FVector> WorldPoints)
{
	 // 清空之前的数据 
	    Vertices.Empty();;;
	    Triangles.Empty();
	    Normals.Empty();;
        UVs.Empty();
	    Colors.Empty();
	
	    // 将传入的世界坐标点添加到 Vertices 数组
	        for (const FVector& WorldPoint : WorldPoints)
	        {
	            // 将世界坐标点转换为相对于 Actor 的本地坐标
	            FVector LocalPoint = GetTransform().InverseTransformPosition(WorldPoint);
                Vertices.Add(LocalPoint);
	        }
	    // 生成三角形索引
	        for (int32 i = 1; i < Vertices.Num() - 1; ++i)
	        {
	            Triangles.Add(0);
                Triangles.Add(i);
	            Triangles.Add(i + 1);
	        }
	
	    // 计算法线
	// 计算法线
	FVector Normal = FVector::CrossProduct(Vertices[2] - Vertices[0], Vertices[1] - Vertices[0]).GetSafeNormal();
	for (int32 i = 0; i < Vertices.Num(); i++)
	{
		Normals.Add(Normal);
	}

	// 添加 UV 坐标
	for (int32 i = 0; i < Vertices.Num(); ++i)
	{
		// 这里简单地用顶点坐标作为 UV,你可以根据需要进行更复杂的映射
		UVs.Add(FVector2D(Vertices[i].X, Vertices[i].Y));
	}
	
	// 设置网格数据
	ProceduralMesh->CreateMeshSection(Index, Vertices, Triangles, Normals, UVs, Colors, TArray<FProcMeshTangent>(), false);

}

 .cpp文件

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ProceduralMeshComponent.h"
#include "AMyProceduralMeshActor.generated.h"

UCLASS()
class MYCPP_API AAMyProceduralMeshActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AAMyProceduralMeshActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	UFUNCTION(BlueprintCallable)
	void GenerateMesh(int Index,TArray<FVector> WorldPoints);

	// 存储面的顶点坐标
	TArray<FVector> Vertices;
	TArray<TArray<FVector>> Vertices1;
	// 存储面的三角形索引
	TArray<int32> Triangles;

	// 存储面的法线
	TArray<FVector> Normals;

	// 存储面的 UV 坐标
	TArray<FVector2D> UVs;

	// 存储面的颜色
	TArray<FColor> Colors;

	// Procedural Mesh 组件
	UProceduralMeshComponent* ProceduralMesh;
};

让我们来看看引擎里面是如何操作的

基于咱刚刚的c++类创建出他的蓝图类

创建一个结构体用来储存一个面的多个点位

打开蓝图创建我们需要的几个变量 一个是V3的数组,一个是我定义的一个面的数组。

先去遍历我们的面再去遍历我们的点的坐标储存起来传给我们的方法就行啦!

把我们的蓝图Actor丢到关卡里,在细节面板进行细节调整

这是一个面的空点位,如有多个面 在下面的索引自行添加

 最后对应的结就是这样的

  • 14
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值