Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

Commit

Permalink
Finish v1.0-r1
Browse files Browse the repository at this point in the history
  • Loading branch information
ufna committed Dec 12, 2019
2 parents 7a5f87a + 046605f commit d396933
Show file tree
Hide file tree
Showing 31 changed files with 2,635 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "Content"]
path = Content
url = ../VaFogOfWar-Content.git
2 changes: 2 additions & 0 deletions Config/FilterPlugin.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[FilterPlugin]
/Documentation/
1 change: 1 addition & 0 deletions Content
Submodule Content added at b74885
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,30 @@
[![statusIcon](https://teamcity.ufna.dev/app/rest/builds/buildType:(id:UfnaDev_VaFogOfWar_ClangFormatCheck)/statusIcon.svg)](https://teamcity.ufna.dev/viewType.html?buildTypeId=UfnaDev_VaFogOfWar_ClangFormatCheck&guest=1)
![GitHub](https://img.shields.io/github/license/ufna/VaFogOfWar)
![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/ufna/VaFogOfWar?include_prereleases)

# VaFogOfWar
A clear and simple solution of Fog of War for Unreal Engine 4

A clear and simple solution of Fog of War for Unreal Engine 4.

![SCREENSHOT](SCREENSHOT.jpg)

**VaFogOfWar** implements fast and optimized fog of war solution for topdown games like Dota, StarCraft or League of Legends. It fast enough even to work on mid-end mobile devices, so it works like a charm on desktop.

Check [wiki](http://bit.ly/VaFogOfWar-Docs) for usage examples and development notes.

### Main features

- Three types of layers: current visibility, global visibility (permanent from black), terrain
- Eight height levels supported (river, lowground, highground, etc.)
- Dynamic and static obstacles (trees, rocks, etc)
- Different types of radius strategy: circle, square and others
- Freeform fog blocking volumes as tool for terrain level painting
- Initial terrain levels can be set with heightmap

### Plugin versions

There are two versions of plugin:

1. Free Community version (which is already available) on Github. Just core C++ code to handle the fog, but no demo content and usage examples.

2. Paid Marketplace version: same as community version + demo content and extended usage example with preconfigured post process.
Binary file added Resources/Icon128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added SCREENSHOT.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions Source/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
Language: Cpp
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Always
Standard: Cpp11
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignEscapedNewlines: Right
AlignTrailingComments: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: InlineOnly
BreakBeforeBraces: Allman
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 0
PointerAlignment: Left
SpacesInAngles: false
---
Language: ObjC
...
132 changes: 132 additions & 0 deletions Source/VaFogOfWar/Private/VaFogAgentComponent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright 2019 Vladimir Alyamkin. All Rights Reserved.

#include "VaFogAgentComponent.h"

#include "VaFogController.h"
#include "VaFogDefines.h"

#include "Components/BillboardComponent.h"

UVaFogAgentComponent::UVaFogAgentComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bAutoActivate = true;
bWantsInitializeComponent = true;

bAgentEnabled = true;
TargetChannels.Add(EVaFogLayerChannel::Permanent);
RadiusStrategy = EVaFogRadiusStrategy::Circle;
VisionRadius = 500;
HeightLevel = EVaFogHeightLevel::HL_3;

#if WITH_EDITORONLY_DATA
bVisualizeComponent = true;
#endif
}

void UVaFogAgentComponent::InitializeComponent()
{
Super::InitializeComponent();
}

void UVaFogAgentComponent::UninitializeComponent()
{
Super::UninitializeComponent();
}

void UVaFogAgentComponent::BeginPlay()
{
if (bAgentEnabled)
{
UVaFogController::Get(this)->OnFogAgentAdded(this);
}

Super::BeginPlay();
}

void UVaFogAgentComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if (bAgentEnabled && UVaFogController::Get(this, EGetWorldErrorMode::LogAndReturnNull))
{
UVaFogController::Get(this)->OnFogAgentRemoved(this);
}

Super::EndPlay(EndPlayReason);
}

#if WITH_EDITORONLY_DATA
void UVaFogAgentComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
UpdateSpriteTexture();

Super::PostEditChangeProperty(PropertyChangedEvent);
}

void UVaFogAgentComponent::OnRegister()
{
Super::OnRegister();

UpdateSpriteTexture();
}
#endif

void UVaFogAgentComponent::EnableAgent(bool bEnable)
{
bAgentEnabled = bEnable;

UpdateAgentRegistration();
}

void UVaFogAgentComponent::DisableAgent()
{
bAgentEnabled = false;

UpdateAgentRegistration();
}

bool UVaFogAgentComponent::IsAgentEnabled() const
{
return bAgentEnabled;
}

void UVaFogAgentComponent::SetVisionRadius(int32 NewVisionRadius)
{
VisionRadius = FMath::Max(NewVisionRadius, 0);
}

void UVaFogAgentComponent::SetHeightLevel(EVaFogHeightLevel NewHeightLevel)
{
HeightLevel = NewHeightLevel;
}

void UVaFogAgentComponent::UpdateAgentRegistration()
{
if (bAgentEnabled)
{
UVaFogController::Get(this)->OnFogAgentAdded(this);
}
else
{
UVaFogController::Get(this)->OnFogAgentRemoved(this);
}
}

#if WITH_EDITORONLY_DATA
void UVaFogAgentComponent::UpdateSpriteTexture()
{
if (SpriteComponent)
{
SpriteComponent->SpriteInfo.Category = TEXT("Misc");
SpriteComponent->SpriteInfo.DisplayName = NSLOCTEXT("SpriteCategory", "Misc", "Misc");

if (TargetChannels.Contains(EVaFogLayerChannel::Terrain))
{
SpriteComponent->SetSprite(LoadObject<UTexture2D>(nullptr, TEXT("/Engine/EditorResources/S_Terrain.S_Terrain")));
}
else
{
SpriteComponent->SetSprite(LoadObject<UTexture2D>(nullptr, TEXT("/Engine/EditorResources/S_Emitter.S_Emitter")));
}
}
}
#endif
113 changes: 113 additions & 0 deletions Source/VaFogOfWar/Private/VaFogBlockingVolume.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2019 Vladimir Alyamkin. All Rights Reserved.

#include "VaFogBlockingVolume.h"

#include "VaFogDefines.h"
#include "VaFogLayer.h"

#include "Components/BillboardComponent.h"
#include "Components/BrushComponent.h"
#include "Engine/CollisionProfile.h"
#include "UObject/ConstructorHelpers.h"

AVaFogBlockingVolume::AVaFogBlockingVolume(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
#if WITH_EDITORONLY_DATA
SpriteComponent = CreateEditorOnlyDefaultSubobject<UBillboardComponent>(TEXT("Sprite"));

if (!IsRunningCommandlet() && (SpriteComponent != nullptr))
{
// Structure to hold one-time initialization
struct FConstructorStatics
{
ConstructorHelpers::FObjectFinderOptional<UTexture2D> TextRenderTexture;
FConstructorStatics()
: TextRenderTexture(TEXT("/Engine/EditorResources/S_VectorFieldVol"))
{
}
};
static FConstructorStatics ConstructorStatics;

SpriteComponent->Sprite = ConstructorStatics.TextRenderTexture.Get();
SpriteComponent->SetRelativeScale3D(FVector(1.f, 1.f, 1.f));
SpriteComponent->SetupAttachment(GetBrushComponent());
SpriteComponent->bIsScreenSizeScaled = true;
SpriteComponent->SetUsingAbsoluteScale(true);
SpriteComponent->bReceivesDecals = false;
}
#endif

//GetBrushComponent()->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
GetBrushComponent()->Mobility = EComponentMobility::Static;

BrushColor = FColor(0, 255, 0, 255);
bColored = true;

HeightLevel = EVaFogHeightLevel::HL_3;
Priority = 0;
}

void AVaFogBlockingVolume::PostLoad()
{
Super::PostLoad();

UpdateTargetLayer();
}

void AVaFogBlockingVolume::PostActorCreated()
{
Super::PostActorCreated();

UpdateTargetLayer();
}

void AVaFogBlockingVolume::OnConstruction(const FTransform& Transform)
{
UpdateTargetLayer();

#if WITH_EDITORONLY_DATA
// Force update layer state for realtime preview
if (Layer)
{
Layer->UpdateLayer(true);
}
#endif
}

void AVaFogBlockingVolume::Destroyed()
{
if (Layer)
{
Layer->RemoveFogBlockingVolume(this);
}

Super::Destroyed();
}

#if WITH_EDITOR
void AVaFogBlockingVolume::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
UpdateTargetLayer();

// @TODO Force volume brush to be square or use custom BrushBuilder

Super::PostEditChangeProperty(PropertyChangedEvent);

// Force update layer state for realtime preview
if (Layer)
{
Layer->UpdateLayer(true);
}
}
#endif

void AVaFogBlockingVolume::UpdateTargetLayer()
{
UE_LOG(LogVaFog, Log, TEXT("[%s] Volume [%s] Check layer we should update and apply self into"), *VA_FUNC_LINE, *GetName());

if (Layer)
{
Layer->AddFogBlockingVolume(this);
}
}
Loading

0 comments on commit d396933

Please sign in to comment.