|
|
|
|
@@ -11,6 +11,7 @@
|
|
|
|
|
#include "../Public/EleriPlayerController.h"
|
|
|
|
|
#include "../Public/MyCharacter.h"
|
|
|
|
|
#include "Engine/OverlapResult.h"
|
|
|
|
|
#include "LandscapeProxy.h"
|
|
|
|
|
|
|
|
|
|
// Sets default values for this component's properties
|
|
|
|
|
UMoveActorsComponent::UMoveActorsComponent()
|
|
|
|
|
@@ -18,8 +19,6 @@ UMoveActorsComponent::UMoveActorsComponent()
|
|
|
|
|
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
|
|
|
|
|
// off to improve performance if you don't need them.
|
|
|
|
|
PrimaryComponentTick.bCanEverTick = true;
|
|
|
|
|
|
|
|
|
|
// ...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -31,13 +30,19 @@ void UMoveActorsComponent::BeginPlay()
|
|
|
|
|
PlayerController = Cast<AEleriPlayerController>(UGameplayStatics::GetPlayerController(GetWorld(), 0));
|
|
|
|
|
PlayerCharacter = Cast<AMyCharacter>(GetOwner());
|
|
|
|
|
|
|
|
|
|
if (!PlayerCharacter)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TArray<AActor*> OutActors;
|
|
|
|
|
PlayerCharacter->GetOverlappingActors(OutActors);
|
|
|
|
|
for (auto Actor : OutActors)
|
|
|
|
|
for (const AActor* Actor : OutActors)
|
|
|
|
|
{
|
|
|
|
|
if(PlantableAreaActorClass == Actor->GetClass())
|
|
|
|
|
if (Actor && PlantableAreaActorClass == Actor->GetClass())
|
|
|
|
|
{
|
|
|
|
|
bRemovalModePossible = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -48,114 +53,121 @@ void UMoveActorsComponent::TickComponent(float DeltaTime, ELevelTick TickType, F
|
|
|
|
|
{
|
|
|
|
|
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
|
|
|
|
|
|
|
|
|
if (!PlayerCharacter || !MovingActor) return;
|
|
|
|
|
if (!PlayerCharacter || !IsValid(MovingActor) || MovingActor->bPlaced) return;
|
|
|
|
|
|
|
|
|
|
if (!MovingActor->bPlaced)
|
|
|
|
|
FVector ForwardVec = PlayerCharacter->GetActorForwardVector();
|
|
|
|
|
if (PlayerController && PlayerController->PlayerCameraManager)
|
|
|
|
|
{
|
|
|
|
|
FVector ForwardVec;
|
|
|
|
|
if (APlayerCameraManager* CameraManager = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0))
|
|
|
|
|
ForwardVec = PlayerController->PlayerCameraManager->GetCameraRotation().Vector();
|
|
|
|
|
ForwardVec.Z = 0.f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Prefer the per-actor tuning values, falling back to the component defaults.
|
|
|
|
|
const float Distance = MovingActor->DistanceFromActor > 0.f ? MovingActor->DistanceFromActor : PlacementDistance;
|
|
|
|
|
const float GridSnap = MovingActor->GridScale > 0.f ? MovingActor->GridScale : GridSnapSize;
|
|
|
|
|
|
|
|
|
|
FVector PosVector = PlayerCharacter->GetActorLocation() + (ForwardVec * Distance) + FVector(0.f, 0.f, PlacementHeightOffset);
|
|
|
|
|
|
|
|
|
|
if (bGridMovementActive)
|
|
|
|
|
{
|
|
|
|
|
PosVector = UKismetMathLibrary::Vector_SnappedToGrid(PosVector, GridSnap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const FVector TargetScale = (MovingActor->ScaleOverride != FVector::ZeroVector) ? MovingActor->ScaleOverride : MovingActor->GetActorScale();
|
|
|
|
|
MovingActor->SetActorTransform(FTransform(MovingActor->GetActorRotation(), PosVector, TargetScale));
|
|
|
|
|
|
|
|
|
|
// Snap the object down onto the ground beneath it.
|
|
|
|
|
FCollisionObjectQueryParams QueryParams;
|
|
|
|
|
QueryParams.AddObjectTypesToQuery(ECC_WorldStatic);
|
|
|
|
|
|
|
|
|
|
const FVector TraceEnd = MovingActor->GetActorLocation() + FVector(0.f, 0.f, -GroundTraceLength);
|
|
|
|
|
TArray<FHitResult> OutHits;
|
|
|
|
|
GetWorld()->LineTraceMultiByObjectType(OutHits, MovingActor->GetActorLocation(), TraceEnd, QueryParams);
|
|
|
|
|
|
|
|
|
|
MovingActor->bPlaceable = true;
|
|
|
|
|
MovingActor->IntersectingActors.Empty();
|
|
|
|
|
for (const FHitResult& HitResult : OutHits)
|
|
|
|
|
{
|
|
|
|
|
AActor* HitActor = HitResult.GetActor();
|
|
|
|
|
if (!HitActor || HitActor == MovingActor) continue;
|
|
|
|
|
|
|
|
|
|
MovingActor->IntersectingActors.Add(HitActor);
|
|
|
|
|
|
|
|
|
|
if (HitActor->IsA(ALandscapeProxy::StaticClass()))
|
|
|
|
|
{
|
|
|
|
|
ForwardVec = CameraManager->GetCameraRotation().Vector();
|
|
|
|
|
ForwardVec.Z = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ForwardVec = PlayerCharacter->GetActorForwardVector();
|
|
|
|
|
}
|
|
|
|
|
//FVector PosVector = UKismetMathLibrary::Vector_SnappedToGrid(PlayerCharacter->GetActorLocation() + ((ForwardVec * MovingActor->DistanceFromActor) + FVector(0.f, 0.f, 100.f)), MovingActor->GridScale);
|
|
|
|
|
|
|
|
|
|
FVector PosVector = PlayerCharacter->GetActorLocation() + ((ForwardVec * 800.f) + FVector(0.f, 0.f, 100.f));
|
|
|
|
|
|
|
|
|
|
if (bGridMovementActive)
|
|
|
|
|
{
|
|
|
|
|
PosVector = UKismetMathLibrary::Vector_SnappedToGrid(PosVector, 250.f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FTransform NewTransform = FTransform(MovingActor->GetActorRotation(), PosVector, (MovingActor->ScaleOverride != FVector::ZeroVector) ? MovingActor->ScaleOverride : MovingActor->GetActorScale());
|
|
|
|
|
MovingActor->SetActorTransform(NewTransform);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TArray<FHitResult> OutHits;
|
|
|
|
|
FCollisionObjectQueryParams QueryParams;
|
|
|
|
|
QueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic);
|
|
|
|
|
FVector TraceEnd = (MovingActor->GetActorLocation() + FVector(0.f, 0.f, -1000.f));
|
|
|
|
|
GetWorld()->LineTraceMultiByObjectType(OutHits, MovingActor->GetActorLocation(), TraceEnd, QueryParams);
|
|
|
|
|
|
|
|
|
|
MovingActor->bPlaceable = true;
|
|
|
|
|
MovingActor->IntersectingActors.Empty();
|
|
|
|
|
for (const FHitResult& HitResult : OutHits)
|
|
|
|
|
{
|
|
|
|
|
if (HitResult.GetActor() == MovingActor) continue;
|
|
|
|
|
|
|
|
|
|
MovingActor->IntersectingActors.Add(HitResult.GetActor());
|
|
|
|
|
|
|
|
|
|
if (HitResult.GetActor()->GetClass()->GetName() == FString("Landscape"))
|
|
|
|
|
{
|
|
|
|
|
MovingActor->SetActorLocation(HitResult.ImpactPoint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Check if moving object is overlapping
|
|
|
|
|
TArray<AActor*> OverlappingActors;
|
|
|
|
|
FVector Center, BoxExtent;
|
|
|
|
|
MovingActor->GetActorBounds(false, Center, BoxExtent);
|
|
|
|
|
BoxExtent *= 0.9f;
|
|
|
|
|
if (!MovingActor->BoxExtentOverride.IsNearlyZero())
|
|
|
|
|
{
|
|
|
|
|
BoxExtent = MovingActor->BoxExtentOverride;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TArray<FOverlapResult> OverlapResults;
|
|
|
|
|
FCollisionQueryParams QueryParams1;
|
|
|
|
|
QueryParams1.bTraceComplex = true;
|
|
|
|
|
QueryParams1.AddIgnoredActor(MovingActor);
|
|
|
|
|
QueryParams1.AddIgnoredActor(PlayerCharacter);
|
|
|
|
|
FCollisionObjectQueryParams ObjectQueryParams;
|
|
|
|
|
ObjectQueryParams.AddObjectTypesToQuery(ECC_WorldStatic);
|
|
|
|
|
ObjectQueryParams.AddObjectTypesToQuery(ECC_WorldDynamic);
|
|
|
|
|
ObjectQueryParams.AddObjectTypesToQuery(ECC_GameTraceChannel1);
|
|
|
|
|
ObjectQueryParams.AddObjectTypesToQuery(ECC_GameTraceChannel2);
|
|
|
|
|
|
|
|
|
|
bool bHit = GetWorld()->OverlapMultiByObjectType(
|
|
|
|
|
OverlapResults,
|
|
|
|
|
MovingActor->GetActorLocation(),
|
|
|
|
|
FQuat::Identity,
|
|
|
|
|
ObjectQueryParams,
|
|
|
|
|
FCollisionShape::MakeBox(BoxExtent), // Or MakeSphere, MakeCapsule
|
|
|
|
|
QueryParams1
|
|
|
|
|
);
|
|
|
|
|
for (const FOverlapResult& OverlapResult : OverlapResults)
|
|
|
|
|
{
|
|
|
|
|
if (OverlapResult.GetActor())
|
|
|
|
|
OverlappingActors.Add(OverlapResult.GetActor());
|
|
|
|
|
}
|
|
|
|
|
//DrawDebugBox(GetWorld(), MovingActor->GetActorLocation(), BoxExtent, FColor::Red);
|
|
|
|
|
bool PlantableAreaFound = false;
|
|
|
|
|
for (auto OverlappingActor : OverlappingActors)
|
|
|
|
|
{
|
|
|
|
|
if (OverlappingActor->GetClass() == PlantableAreaActorClass)
|
|
|
|
|
{
|
|
|
|
|
PlantableAreaFound = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OverlappingActor->GetClass()->GetName() == FString("Landscape") ||
|
|
|
|
|
!OverlappingActor->GetClass()->IsChildOf(AStaticMeshActor::StaticClass())) continue;
|
|
|
|
|
|
|
|
|
|
if (!ActorsToIgnore.FindByPredicate([&OverlappingActor](const TSubclassOf<AActor>& ActorClass) { return OverlappingActor->GetClass() == ActorClass; }))
|
|
|
|
|
{
|
|
|
|
|
MovingActor->bPlaceable = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!PlantableAreaFound)
|
|
|
|
|
MovingActor->bPlaceable = false;
|
|
|
|
|
|
|
|
|
|
if (MovingActor)
|
|
|
|
|
{
|
|
|
|
|
MovingActor->GetStaticMeshComponent()->SetOverlayMaterial((!MovingActor->bPlaceable) ? MovingActor->CantPlaceMaterial : MovingActor->CanPlaceMaterial);
|
|
|
|
|
MovingActor->K2_TogglePlaceableEffects(MovingActor->bPlaceable);
|
|
|
|
|
MovingActor->SetActorLocation(HitResult.ImpactPoint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check whether the object overlaps anything that should block placement.
|
|
|
|
|
FVector Center, BoxExtent;
|
|
|
|
|
MovingActor->GetActorBounds(false, Center, BoxExtent);
|
|
|
|
|
BoxExtent *= OverlapBoxExtentMultiplier;
|
|
|
|
|
if (!MovingActor->BoxExtentOverride.IsNearlyZero())
|
|
|
|
|
{
|
|
|
|
|
BoxExtent = MovingActor->BoxExtentOverride;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FCollisionQueryParams OverlapQueryParams;
|
|
|
|
|
OverlapQueryParams.bTraceComplex = true;
|
|
|
|
|
OverlapQueryParams.AddIgnoredActor(MovingActor);
|
|
|
|
|
OverlapQueryParams.AddIgnoredActor(PlayerCharacter);
|
|
|
|
|
|
|
|
|
|
FCollisionObjectQueryParams ObjectQueryParams;
|
|
|
|
|
ObjectQueryParams.AddObjectTypesToQuery(ECC_WorldStatic);
|
|
|
|
|
ObjectQueryParams.AddObjectTypesToQuery(ECC_WorldDynamic);
|
|
|
|
|
ObjectQueryParams.AddObjectTypesToQuery(ECC_GameTraceChannel1);
|
|
|
|
|
ObjectQueryParams.AddObjectTypesToQuery(ECC_GameTraceChannel2);
|
|
|
|
|
|
|
|
|
|
TArray<FOverlapResult> OverlapResults;
|
|
|
|
|
GetWorld()->OverlapMultiByObjectType(
|
|
|
|
|
OverlapResults,
|
|
|
|
|
MovingActor->GetActorLocation(),
|
|
|
|
|
MovingActor->GetActorQuat(),
|
|
|
|
|
ObjectQueryParams,
|
|
|
|
|
FCollisionShape::MakeBox(BoxExtent),
|
|
|
|
|
OverlapQueryParams
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
bool PlantableAreaFound = false;
|
|
|
|
|
for (const FOverlapResult& OverlapResult : OverlapResults)
|
|
|
|
|
{
|
|
|
|
|
AActor* OverlappingActor = OverlapResult.GetActor();
|
|
|
|
|
if (!OverlappingActor) continue;
|
|
|
|
|
|
|
|
|
|
if (PlantableAreaActorClass == OverlappingActor->GetClass())
|
|
|
|
|
{
|
|
|
|
|
PlantableAreaFound = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Landscape and non-static-mesh actors don't block placement.
|
|
|
|
|
if (OverlappingActor->IsA(ALandscapeProxy::StaticClass()) || !OverlappingActor->GetClass()->IsChildOf(AStaticMeshActor::StaticClass()))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool bIsIgnored = ActorsToIgnore.ContainsByPredicate([&OverlappingActor](const TSubclassOf<AActor>& ActorClass)
|
|
|
|
|
{
|
|
|
|
|
return OverlappingActor->GetClass() == ActorClass;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!bIsIgnored)
|
|
|
|
|
{
|
|
|
|
|
MovingActor->bPlaceable = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!PlantableAreaFound)
|
|
|
|
|
{
|
|
|
|
|
MovingActor->bPlaceable = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (UStaticMeshComponent* MeshComponent = MovingActor->GetStaticMeshComponent())
|
|
|
|
|
{
|
|
|
|
|
MeshComponent->SetOverlayMaterial((!MovingActor->bPlaceable) ? MovingActor->CantPlaceMaterial : MovingActor->CanPlaceMaterial);
|
|
|
|
|
}
|
|
|
|
|
MovingActor->K2_TogglePlaceableEffects(MovingActor->bPlaceable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UMoveActorsComponent::ToggleGridMovement()
|
|
|
|
|
@@ -172,20 +184,21 @@ bool UMoveActorsComponent::PlaceableActionUsed(ERemovalAction ActionUsed)
|
|
|
|
|
switch (ActionUsed)
|
|
|
|
|
{
|
|
|
|
|
case ERemovalAction::NONE:
|
|
|
|
|
case ERemovalAction::MAX:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ERemovalAction::START_MOVE:
|
|
|
|
|
if (AEleriPlayerController* PC = Cast<AEleriPlayerController>(UGameplayStatics::GetPlayerController(GetWorld(), 0)))
|
|
|
|
|
{
|
|
|
|
|
PickUpObjectForPlacing(HighligtedMovingActor);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
return PickUpObjectForPlacing(HighligtedMovingActor);
|
|
|
|
|
|
|
|
|
|
case ERemovalAction::PLACE:
|
|
|
|
|
if (PlayerController && MovingActor && MovingActor->IsPlaceable())
|
|
|
|
|
if (PlayerController && MovingActor->IsPlaceable())
|
|
|
|
|
{
|
|
|
|
|
FPrimaryAssetId ItemId = MovingActor->ItemStack.ItemId;
|
|
|
|
|
if (!ItemId.IsValid())
|
|
|
|
|
{
|
|
|
|
|
ItemId = MovingActor->DataAssetId;
|
|
|
|
|
}
|
|
|
|
|
if (ItemId.IsValid())
|
|
|
|
|
{
|
|
|
|
|
if (UInventoryComponent* Inventory = UMainBlueprintFunctionLibrary::GetPlayerInventory(GetWorld()))
|
|
|
|
|
@@ -197,52 +210,50 @@ bool UMoveActorsComponent::PlaceableActionUsed(ERemovalAction ActionUsed)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
//Will place it in inventory
|
|
|
|
|
|
|
|
|
|
case ERemovalAction::REMOVE:
|
|
|
|
|
case ERemovalAction::EXIT:
|
|
|
|
|
if (UGameInstance* GI = UGameplayStatics::GetGameInstance(GetWorld()))
|
|
|
|
|
{
|
|
|
|
|
// A world object is returned to the player's inventory before it is removed.
|
|
|
|
|
if (MovingActor->DataAssetId.IsValid() && !MovingActor->bFromInventory)
|
|
|
|
|
{
|
|
|
|
|
if (UObjectPersistenceSubsystem* ObjectPersistenceSubsystem = GI->GetSubsystem<UObjectPersistenceSubsystem>())
|
|
|
|
|
if (UInventoryComponent* Inventory = UMainBlueprintFunctionLibrary::GetPlayerInventory(GetWorld()))
|
|
|
|
|
{
|
|
|
|
|
Inventory->AddItemToInventory(MovingActor->DataAssetId, 1, false, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(GetWorld()))
|
|
|
|
|
{
|
|
|
|
|
if (UObjectPersistenceSubsystem* ObjectPersistenceSubsystem = GameInstance->GetSubsystem<UObjectPersistenceSubsystem>())
|
|
|
|
|
{
|
|
|
|
|
if (MovingActor)
|
|
|
|
|
{
|
|
|
|
|
if (MovingActor->DataAssetId.IsValid() && !MovingActor->bFromInventory)
|
|
|
|
|
{
|
|
|
|
|
if (UInventoryComponent* Inventory = UMainBlueprintFunctionLibrary::GetPlayerInventory(GetWorld()))
|
|
|
|
|
{
|
|
|
|
|
Inventory->AddItemToInventory(MovingActor->DataAssetId, 1, false, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ObjectPersistenceSubsystem->RemoveActorFromLevel(MovingActor);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
/*if (MovingActor->InventoryRef)
|
|
|
|
|
|
|
|
|
|
// Fallback if the persistence subsystem is unavailable.
|
|
|
|
|
MovingActor->Destroy();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ERemovalAction::EXIT:
|
|
|
|
|
{
|
|
|
|
|
// Cancel the current placement/move without committing it.
|
|
|
|
|
if (MovingActor->bFromInventory)
|
|
|
|
|
{
|
|
|
|
|
PlaceableActionUsed(ERemovalAction::REMOVE);
|
|
|
|
|
// A preview spawned from the inventory: return the item and destroy the preview.
|
|
|
|
|
MovingActor->ReturnToInventory();
|
|
|
|
|
MovingActor->Destroy();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// An existing world object: put it back where it was picked up from.
|
|
|
|
|
MovingActor->SetActorTransform(MovingActor->CurrentMemorizedTransform);
|
|
|
|
|
for (int32 i = 0; i < MovingActor->MeshMaterials.Num(); i++)
|
|
|
|
|
{
|
|
|
|
|
MovingActor->GetStaticMeshComponent()->SetMaterial(i, MovingActor->MeshMaterials[i]);
|
|
|
|
|
}
|
|
|
|
|
MovingActor->GetStaticMeshComponent()->SetOverlayMaterial(nullptr);
|
|
|
|
|
if (PlayerController)
|
|
|
|
|
{
|
|
|
|
|
PlaceObjectForPlacing();
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}*/
|
|
|
|
|
break;
|
|
|
|
|
case ERemovalAction::MAX:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -253,7 +264,7 @@ void UMoveActorsComponent::ToggleRemovalModeOption(bool bNewRemoveModePossible)
|
|
|
|
|
|
|
|
|
|
bool UMoveActorsComponent::PickUpObjectForPlacing(ARemovableStaticMeshActor* Placable)
|
|
|
|
|
{
|
|
|
|
|
if (MovingActor || !Placable || !PlayerController) return false;
|
|
|
|
|
if (MovingActor || !IsValid(Placable) || !PlayerController) return false;
|
|
|
|
|
|
|
|
|
|
// Get the Enhanced Input Local Player Subsystem from the Local Player related to our Player Controller.
|
|
|
|
|
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
|
|
|
|
|
@@ -268,16 +279,14 @@ bool UMoveActorsComponent::PickUpObjectForPlacing(ARemovableStaticMeshActor* Pla
|
|
|
|
|
|
|
|
|
|
bool UMoveActorsComponent::PlaceObjectForPlacing()
|
|
|
|
|
{
|
|
|
|
|
if (!MovingActor) return false;
|
|
|
|
|
if (!IsValid(MovingActor)) return false;
|
|
|
|
|
|
|
|
|
|
if (MovingActor)
|
|
|
|
|
if (UStaticMeshComponent* MeshComponent = MovingActor->GetStaticMeshComponent())
|
|
|
|
|
{
|
|
|
|
|
if (MovingActor->GetStaticMeshComponent())
|
|
|
|
|
{
|
|
|
|
|
MovingActor->GetStaticMeshComponent()->SetOverlayMaterial(nullptr);
|
|
|
|
|
}
|
|
|
|
|
MovingActor->Place();
|
|
|
|
|
MeshComponent->SetOverlayMaterial(nullptr);
|
|
|
|
|
}
|
|
|
|
|
MovingActor->Place();
|
|
|
|
|
|
|
|
|
|
RemovalModePlacingStack--;
|
|
|
|
|
return RemoveObjectForPlacing();
|
|
|
|
|
}
|
|
|
|
|
@@ -290,9 +299,11 @@ bool UMoveActorsComponent::RemoveObjectForPlacing()
|
|
|
|
|
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
|
|
|
|
|
{
|
|
|
|
|
if (RemovalModePlacingStack <= 0)
|
|
|
|
|
{
|
|
|
|
|
Subsystem->RemoveMappingContext(PlayerController->RemoveModeContext);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MovingActor = nullptr;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@@ -300,9 +311,11 @@ bool UMoveActorsComponent::RemoveObjectForPlacing()
|
|
|
|
|
|
|
|
|
|
void UMoveActorsComponent::StartObjectRemoval(bool bStart, int32 Stack)
|
|
|
|
|
{
|
|
|
|
|
if (!PlayerCharacter) return;
|
|
|
|
|
|
|
|
|
|
if (!bStart)
|
|
|
|
|
{
|
|
|
|
|
PlayerCharacter->bAlreadyInteracting = bStart;
|
|
|
|
|
PlayerCharacter->bAlreadyInteracting = false;
|
|
|
|
|
}
|
|
|
|
|
PlayerCharacter->CurrentlyDoing = bStart ? ECurrentlyDoing::OBJECT_PLACING : ECurrentlyDoing::NOTHING;
|
|
|
|
|
|
|
|
|
|
@@ -312,29 +325,33 @@ void UMoveActorsComponent::StartObjectRemoval(bool bStart, int32 Stack)
|
|
|
|
|
if (!bStart)
|
|
|
|
|
{
|
|
|
|
|
PlayerCharacter->ZoomBack(0.5f);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (bStart)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PlayerCharacter->ZoomCamera(-500.f, 0.5f);
|
|
|
|
|
PlayerCharacter->ZoomCamera(500.f, 0.5f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bRemovalMode = bStart;
|
|
|
|
|
OnRemovalModeToggled.Broadcast(bRemovalMode);
|
|
|
|
|
|
|
|
|
|
PlayerCharacter->SetNewCameraPitches(
|
|
|
|
|
bStart? PlayerCharacter->CameraPitchMin - 50 : PlayerCharacter->CameraPitchMin,
|
|
|
|
|
bStart? PlayerCharacter->CameraPitchMax + 5 : PlayerCharacter->CameraPitchMax);
|
|
|
|
|
bStart ? PlayerCharacter->CameraPitchMin - 50 : PlayerCharacter->CameraPitchMin,
|
|
|
|
|
bStart ? PlayerCharacter->CameraPitchMax + 5 : PlayerCharacter->CameraPitchMax);
|
|
|
|
|
|
|
|
|
|
if (PlayerController->GetMainGameWidget())
|
|
|
|
|
if (PlayerController && PlayerController->GetMainGameWidget())
|
|
|
|
|
{
|
|
|
|
|
PlayerController->GetMainGameWidget()->SwitchKeybindsDisplay(bRemovalMode ? 4 : 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the Enhanced Input Local Player Subsystem from the Local Player related to our Player Controller.
|
|
|
|
|
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
|
|
|
|
|
if (PlayerController)
|
|
|
|
|
{
|
|
|
|
|
if (!bStart)
|
|
|
|
|
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
|
|
|
|
|
{
|
|
|
|
|
Subsystem->RemoveMappingContext(PlayerController->RemoveModeContext);
|
|
|
|
|
if (!bStart)
|
|
|
|
|
{
|
|
|
|
|
Subsystem->RemoveMappingContext(PlayerController->RemoveModeContext);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -343,38 +360,21 @@ void UMoveActorsComponent::StartObjectRemoval(bool bStart, int32 Stack)
|
|
|
|
|
|
|
|
|
|
bool UMoveActorsComponent::HighlightRemovableObject(ARemovableStaticMeshActor* Placable)
|
|
|
|
|
{
|
|
|
|
|
if (!bRemovalModePossible || !bRemovalMode) return false;
|
|
|
|
|
if (!bRemovalModePossible || !bRemovalMode || !IsValid(Placable)) return false;
|
|
|
|
|
|
|
|
|
|
if (!HighligtedMovingActor)
|
|
|
|
|
if (HighligtedMovingActor == Placable)
|
|
|
|
|
{
|
|
|
|
|
HighligtedMovingActor = Placable;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (HighligtedMovingActor != Placable)
|
|
|
|
|
{
|
|
|
|
|
if (HighligtedMovingActor)
|
|
|
|
|
{
|
|
|
|
|
HighligtedMovingActor = Placable;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
HighligtedMovingActor = Placable;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UMoveActorsComponent::UnhighlightRemovableObject(ARemovableStaticMeshActor* Placable)
|
|
|
|
|
{
|
|
|
|
|
if (Placable)
|
|
|
|
|
if (Placable && HighligtedMovingActor == Placable)
|
|
|
|
|
{
|
|
|
|
|
if (HighligtedMovingActor == Placable)
|
|
|
|
|
{
|
|
|
|
|
HighligtedMovingActor = nullptr;
|
|
|
|
|
}
|
|
|
|
|
HighligtedMovingActor = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|