0. 序
不知道为什么我的chunk放在游戏里面巨慢无比,开始游戏都要好久,然后内存直接爆一半。
(20210624加 去掉tick函数即可,看油管上一个小哥这么做的,确实加快了)
他这个chunk是参考前面cube的。
本文纯做记录,不做过多讲解,详情看B站老李视屏 https://www.bilibili.com/video/BV1sE411473f?share_source=copy_web
1. 创建Chunk类
2.代码
头文件
// 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 "Chunk.generated.h"
//UENUM(BlueprintType)
//enum class EBlockType : uint8
//{
// None = 0,
// Dirt = 1,
// Grass = 2,
// Gravel = 3,
//};
UENUM(BlueprintType)
enum class EFaceType1 : uint8
{
Up,
Down,
Right,
Left,
Forward,
Back
};
UCLASS()
class NEWWORLD_API AChunk : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AChunk();
UPROPERTY(BlueprintReadWrite, EditAnywhere)
UMaterialInterface* material;
UPROPERTY(BlueprintReadOnly)
UProceduralMeshComponent* produralMesh;
UPROPERTY(BlueprintReadWrite, EditAnywhere)
int32 ChunkElements = 16;
UPROPERTY(BlueprintReadWrite, EditAnywhere)
int32 VoxelSize = 100;
TArray<FVector> Vertices;
TArray<int32> Triangles;
TArray<FVector> Normals;
TArray<FVector2D> UV0;
TArray<FLinearColor> VertexColors;
TArray<FProcMeshTangent> Tangents;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void OnConstruction(const FTransform& transform) override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// 方块销毁
UFUNCTION()
void BuildBlock(FVector wPos);
// 方块销毁
UFUNCTION()
void BuildFace(EFaceType1 facetype, FVector center, FVector up, FVector right, bool reversed);
// 方块销毁
UFUNCTION()
void BuildChunk();
};
.cpp文件
// Fill out your copyright notice in the Description page of Project Settings.
#include "Chunk.h"
// Sets default values
AChunk::AChunk()
{
// 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;
}
// Called when the game starts or when spawned
void AChunk::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AChunk::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AChunk::OnConstruction(const FTransform& transform)
{
produralMesh = NewObject<UProceduralMeshComponent>(this, "produralMesh");
produralMesh->RegisterComponent();
RootComponent = produralMesh;
produralMesh->SetWorldTransform(transform);
BuildChunk();
}
void AChunk::BuildChunk()
{
for (int i = 0; i < ChunkElements; i++)
{
for (int j = 0; j < ChunkElements; j++)
{
BuildBlock(FVector(i*VoxelSize,j*VoxelSize,0));
}
}
//更新
produralMesh->ClearAllMeshSections();
produralMesh->CreateMeshSection_LinearColor(0, Vertices, Triangles, Normals, UV0, VertexColors, Tangents, true);
}
void AChunk::BuildBlock(FVector wPos)
{
BuildFace(EFaceType1::Up, wPos + FVector(0, 0, 100), FVector::ForwardVector, FVector::RightVector, false);
BuildFace(EFaceType1::Down, wPos + FVector(0, 0, 0), FVector::ForwardVector, FVector::RightVector, true);
BuildFace(EFaceType1::Forward, wPos + FVector(100, 0, 0), FVector::UpVector, FVector::RightVector, true);
BuildFace(EFaceType1::Back, wPos + FVector(0, 0, 0), FVector::UpVector, FVector::RightVector, false);
BuildFace(EFaceType1::Right, wPos + FVector(0, 100, 0), FVector::ForwardVector, FVector::UpVector, true);
BuildFace(EFaceType1::Left, wPos + FVector(0, 0, 0), FVector::ForwardVector, FVector::UpVector, false);
}
void AChunk::BuildFace(EFaceType1 facetype, FVector center, FVector up, FVector right, bool reversed)
{
int index = Vertices.Num();
Vertices.Add(center);
Vertices.Add(center + up * 100);
Vertices.Add(center + up * 100 + right * 100);
Vertices.Add(center + right * 100);
if (reversed)
{
Triangles.Add(index + 0);
Triangles.Add(index + 1);
Triangles.Add(index + 2);
Triangles.Add(index + 2);
Triangles.Add(index + 3);
Triangles.Add(index + 0);
}
else
{
Triangles.Add(index + 1);
Triangles.Add(index + 0);
Triangles.Add(index + 2);
Triangles.Add(index + 3);
Triangles.Add(index + 2);
Triangles.Add(index + 0);
}
const FVector2D bUVs[] = { FVector2D(0.0,0.0),FVector2D(0.0,1.0), FVector2D(1.0,1.0), FVector2D(1.0,0.0) };
UV0.Append(bUVs, ARRAY_COUNT(bUVs));
}