Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
BLaZeKiLL committed Jun 2, 2021
0 parents commit fe4f612
Show file tree
Hide file tree
Showing 22 changed files with 3,049 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Content/** filter=lfs diff=lfs merge=lfs -text
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Binaries
DerivedDataCache
Intermediate
Saved
.vscode
.vs
*.VC.db
*.opensdf
*.opendb
*.sdf
*.sln
*.suo
*.xcodeproj
*.xcworkspace
Empty file added Config/DefaultEditor.ini
Empty file.
28 changes: 28 additions & 0 deletions Config/DefaultEngine.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@


[/Script/EngineSettings.GameMapsSettings]
GameDefaultMap=/Engine/Maps/Templates/Template_Default.Template_Default


[/Script/HardwareTargeting.HardwareTargetingSettings]
TargetedHardwareClass=Desktop
AppliedTargetedHardwareClass=Desktop
DefaultGraphicsPerformance=Maximum
AppliedDefaultGraphicsPerformance=Maximum

[/Script/Engine.RendererSettings]
r.GenerateMeshDistanceFields=True
r.DynamicGlobalIlluminationMethod=1
r.ReflectionMethod=1
r.Shadow.Virtual.Enable=1

[/Script/WorldPartitionEditor.WorldPartitionEditorSettings]
bEnableWorldPartition=False
bEnableConversionPrompt=True
CommandletClass=Class'/Script/UnrealEd.WorldPartitionConvertCommandlet
[/Script/Engine.Engine]
+ActiveGameNameRedirects=(OldGameName="TP_Blank",NewGameName="/Script/UE5VoxelTutorial")
+ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/UE5VoxelTutorial")
+ActiveClassRedirects=(OldClassName="TP_BlankGameModeBase",NewClassName="UE5VoxelTutorialGameModeBase")
3 changes: 3 additions & 0 deletions Config/DefaultGame.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

[/Script/EngineSettings.GeneralProjectSettings]
ProjectID=4CD1398D4AF3BFD2578C7FAC9237DAB0
3 changes: 3 additions & 0 deletions Content/Main.umap
Git LFS file not shown
3 changes: 3 additions & 0 deletions Content/Main_BuiltData.uasset
Git LFS file not shown
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# UE5VoxelTutorial

Developed with Unreal Engine 5
14 changes: 14 additions & 0 deletions Source/UE5VoxelTutorial.Target.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;
using System.Collections.Generic;

public class UE5VoxelTutorialTarget : TargetRules
{
public UE5VoxelTutorialTarget( TargetInfo Target) : base(Target)
{
Type = TargetType.Game;
DefaultBuildSettings = BuildSettingsVersion.V2;
ExtraModuleNames.AddRange( new string[] { "UE5VoxelTutorial" } );
}
}
143 changes: 143 additions & 0 deletions Source/UE5VoxelTutorial/Private/Chunk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Fill out your copyright notice in the Description page of Project Settings.


#include "Chunk.h"

#include "Enums.h"
#include "ProceduralMeshComponent.h"
#include "FastNoiseLite.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 = false;

Mesh = CreateDefaultSubobject<UProceduralMeshComponent>("Mesh");
Noise = new FastNoiseLite();
Noise->SetFrequency(0.03f);
Noise->SetNoiseType(FastNoiseLite::NoiseType_Perlin);
Noise->SetFractalType(FastNoiseLite::FractalType_FBm);

// Initialize Blocks
Blocks.SetNum(Size * Size * Size);

// Mesh Settings
Mesh->SetCastShadow(false);
}

// Called when the game starts or when spawned
void AChunk::BeginPlay()
{
Super::BeginPlay();

GenerateBlocks();

GenerateMesh();

ApplyMesh();
}

void AChunk::GenerateBlocks()
{
const auto Location = GetActorLocation();

for (int x = 0; x < Size; x++)
{
for (int y = 0; y < Size; y++)
{
const float Xpos = (x * 100 + Location.X) / 100;
const float ypos = (y * 100 + Location.Y) / 100;

const int Height = FMath::Clamp(FMath::RoundToInt((Noise->GetNoise(Xpos, ypos) + 1) * Size / 2), 0, Size);

for (int z = 0; z < Height; z++)
{
Blocks[GetBlockIndex(x,y,z)] = EBlock::Stone;
}

for (int z = Height; z < Size; z++)
{
Blocks[GetBlockIndex(x,y,z)] = EBlock::Air;
}

}
}
}

void AChunk::GenerateMesh()
{
for (int x = 0; x < Size; x++)
{
for (int y = 0; y < Size; y++)
{
for (int z = 0; z < Size; z++)
{
if (Blocks[GetBlockIndex(x,y,z)] != EBlock::Air)
{
const auto Position = FVector(x,y,z);

for (auto Direction : {EDirection::Forward, EDirection::Right, EDirection::Back, EDirection::Left, EDirection::Up, EDirection::Down})
{
if (Check(GetPositionInDirection(Direction, Position)))
{
CreateFace(Direction, Position * 100);
}
}
}
}
}
}
}

void AChunk::ApplyMesh() const
{
Mesh->CreateMeshSection(0, VertexData, TriangleData, TArray<FVector>(), UVData, TArray<FColor>(), TArray<FProcMeshTangent>(), false);
}

bool AChunk::Check(const FVector Position) const
{
if (Position.X >= Size || Position.Y >= Size || Position.X < 0 || Position.Y < 0 || Position.Z < 0) return true;
if (Position.Z >= Size) return true;
return Blocks[GetBlockIndex(Position.X, Position.Y, Position.Z)] == EBlock::Air;
}

void AChunk::CreateFace(const EDirection Direction, const FVector Position)
{
VertexData.Append(GetFaceVertices(Direction, Position));
UVData.Append({ FVector2D(1,1), FVector2D(1,0), FVector2D(0,0), FVector2D(0,1) });
TriangleData.Append({ VertexCount + 3, VertexCount + 2, VertexCount, VertexCount + 2, VertexCount + 1, VertexCount });
VertexCount += 4;
}

TArray<FVector> AChunk::GetFaceVertices(EDirection Direction, FVector Position) const
{
TArray<FVector> Vertices;

for (int i = 0; i < 4; i++)
{
Vertices.Add(BlockVertexData[BlockTriangleData[i + static_cast<int>(Direction) * 4]] * Scale + Position);
}

return Vertices;
}

FVector AChunk::GetPositionInDirection(const EDirection Direction, const FVector Position) const
{
switch (Direction)
{
case EDirection::Forward: return Position + FVector(1,0,0);
case EDirection::Back: return Position + FVector(-1,0,0);
case EDirection::Left: return Position + FVector(0,-1,0);
case EDirection::Right: return Position + FVector(0,1,0);
case EDirection::Up: return Position + FVector(0,0,1);
case EDirection::Down: return Position + FVector(0,0,-1);
default: throw std::invalid_argument("Invalid direction");
}
}

int AChunk::GetBlockIndex(int X, int Y, int Z) const
{
return Z * Size * Size + Y * Size + X;
}

80 changes: 80 additions & 0 deletions Source/UE5VoxelTutorial/Private/Chunk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Chunk.generated.h"

enum class EBlock;
enum class EDirection;
class FastNoiseLite;
class UProceduralMeshComponent;

UCLASS()
class AChunk : public AActor
{
GENERATED_BODY()

public:
// Sets default values for this actor's properties
AChunk();

UPROPERTY(EditAnywhere, Category="Chunk")
int Size = 32;

UPROPERTY(EditAnywhere, Category="Chunk")
int Scale = 1;

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

private:
TObjectPtr<UProceduralMeshComponent> Mesh;
TObjectPtr<FastNoiseLite> Noise;

TArray<EBlock> Blocks;

TArray<FVector> VertexData;
TArray<int> TriangleData;
TArray<FVector2D> UVData;

int VertexCount = 0;

const FVector BlockVertexData[8] = {
FVector(100,100,100),
FVector(100,0,100),
FVector(100,0,0),
FVector(100,100,0),
FVector(0,0,100),
FVector(0,100,100),
FVector(0,100,0),
FVector(0,0,0)
};

const int BlockTriangleData[24] = {
0,1,2,3, // Forward
5,0,3,6, // Right
4,5,6,7, // Back
1,4,7,2, // Left
5,4,1,0, // Up
3,2,7,6 // Down
};

void GenerateBlocks();

void GenerateMesh();

void ApplyMesh() const;

bool Check(FVector Position) const;

void CreateFace(EDirection Direction, FVector Position);

TArray<FVector> GetFaceVertices(EDirection Direction, FVector Position) const;

FVector GetPositionInDirection(EDirection Direction, FVector Position) const;

int GetBlockIndex(int X, int Y, int Z) const;
};
27 changes: 27 additions & 0 deletions Source/UE5VoxelTutorial/Private/ChunkWorld.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Fill out your copyright notice in the Description page of Project Settings.


#include "ChunkWorld.h"

#include "Chunk.h"

// Sets default values
AChunkWorld::AChunkWorld()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
}

// Called when the game starts or when spawned
void AChunkWorld::BeginPlay()
{
Super::BeginPlay();

for (int x = -DrawDistance; x <= DrawDistance; x++)
{
for (int y = -DrawDistance; y < DrawDistance; ++y)
{
GetWorld()->SpawnActor<AChunk>(FVector(x * ChunkSize * 100, y * ChunkSize * 100, 0), FRotator(0,0,0));
}
}
}
28 changes: 28 additions & 0 deletions Source/UE5VoxelTutorial/Private/ChunkWorld.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ChunkWorld.generated.h"

UCLASS()
class AChunkWorld : public AActor
{
GENERATED_BODY()

public:
UPROPERTY(EditAnywhere, Category="Chunk World")
int DrawDistance = 5;

UPROPERTY(EditAnywhere, Category="Chunk World")
int ChunkSize = 32;

// Sets default values for this actor's properties
AChunkWorld();

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

};
11 changes: 11 additions & 0 deletions Source/UE5VoxelTutorial/Private/Enums.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

enum class EDirection
{
Forward, Right, Back, Left, Up, Down
};

enum class EBlock
{
Null, Air, Stone, Dirt, Grass
};
Loading

0 comments on commit fe4f612

Please sign in to comment.