Inheritance

I think, i am not tooo far away right now, but what am i doing wrong now ???
It’s not working this way …

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "MilitaryEntity.generated.h"

// Dynamic multicast delegate to broadcast entity death
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FMilitaryEntityDelegateDeath);

/// Forward Decleration definitions to keep headers clear
class UArrowComponent;
class UAimingComponent;
class UAudioEffectComponent;
class UTurret;

// Abstract implementation of an military entity inside the game
UCLASS(abstract)
class TURRETPOWER_API AMilitaryEntity : public APawn
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMilitaryEntity();

	// OnDeath Delegator to broadcast entities death
	FMilitaryEntityDelegateDeath OnDeath;

	virtual void OnConstruction(const FTransform& Transform) override;

#pragma region BlueprintImplementableEvents
	// Blueprint implementable event to show individual Barrel Fire
	UFUNCTION(BlueprintImplementableEvent, Category = "Setup")
	void OnBarrelFire();

	// Blueprint implementable event to show individual Destruction
	UFUNCTION(BlueprintImplementableEvent, Category = "Setup")
	void OnDestruction();

	// Blueprint implementable event to make something on turret rotation
	UFUNCTION(BlueprintImplementableEvent, Category = "Setup")
	void OnTurretRotate(bool IsPrimaryTurret);
	
	// Blueprint implementable event to make something on barrel lift
	UFUNCTION(BlueprintImplementableEvent, Category = "Setup")
	void OnBarrelMove(bool IsPrimaryTurret);
#pragma endregion to handle special behaviour on  action
	

	// Return value, if actor is locked on
	UFUNCTION(BlueprintCallable, Category = "Setup")
	AActor* GetLockedOnTarget() const;

	// Sets an Actor as Locked on target
	void SetLockedOnTarget(AActor* Target);
	
	// Blueprint Callable implementation for inherited primary turret
	UFUNCTION(BlueprintCallable, Category = "Setup")
	UTurret* GetPrimaryTurret() const;

	// Blueprint Callable implementation for inherited primary turret
	UFUNCTION(BlueprintCallable, Category = "Setup")
	UTurret* GetSecondaryTurret() const;

	// Blueprint Callable implementation for inherited body
	UFUNCTION(BlueprintCallable, Category = "Setup")
	UStaticMeshComponent* GetBody() const;

	// Blueprint Callable implementation for inherited Aiming Component
	UFUNCTION(BlueprintCallable, Category = "Setup")
	UAimingComponent* GetAimingComponent() const;

	// Blueprint Callable implementation for inherited AudioComponent
	UFUNCTION(BlueprintCallable, Category = "Setup")
	UAudioEffectComponent* GetAudioComponent() const;

	/// Visibility functionality
	// Visibility passthroug callable
	UFUNCTION(BlueprintCallable, Category = "Game")
	void SetVisibility(bool Visibility);

	// is Pawn is Visible to player
	UFUNCTION(BlueprintImplementableEvent, Category = "Setup")
	void VisibleToPlayer(bool isVisible);

protected:
	// TODO put into Player Controller !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	// Flag indicating, First Person Camera is used
	UPROPERTY(BlueprintReadWrite, Category = "Camera")
	bool isUsingFirstPerson = false;

	// Pointer to the Locked on target
	AActor* LockedOnTarget;

#pragma region Debug
	// Shows Debug Direction Arrows
	UPROPERTY(EditAnywhere, Category = "Debug")
	bool ShowArrows = true;

	// Arrow showing into the primary barrels direction
	UPROPERTY(VisibleAnywhere, Category = "Components")
	UArrowComponent* PrimaryDirection = nullptr;

	// Arrow showing into the secondary barrels direction
	UPROPERTY(VisibleAnywhere, Category = "Components")
	UArrowComponent* SecondaryDirection = nullptr;

	// Outliner Folder name for editor play sorting
	UPROPERTY(EditDefaultsOnly, Category = "Components")
	FName EditorOutlinerFolderName = "Entities";
#pragma endregion information seen on the entity

private:
	virtual void BeginPlay() override;


#pragma region Components and Meshes	
	// Body of this entity
	UPROPERTY(VisibleAnywhere, Category = "Components")
	UStaticMeshComponent* Body = nullptr;
	
	// Primary turret of this entity
	UPROPERTY(VisibleAnywhere, Category = "Components")
	UTurret* PrimaryTurret = nullptr;
	
	// Secondary Turret of this entity
	UPROPERTY(VisibleAnywhere, Category = "Components")
	UTurret* SecondaryTurret = nullptr;

	// Aiming Component for this entity
	UPROPERTY(VisibleAnywhere, Category = "Components")
	UAimingComponent* AimingComponent = nullptr;

	// Audio Component for this entity
	UPROPERTY(VisibleAnywhere, Category = "Components")
	UAudioEffectComponent* AudioComponent = nullptr;
#pragma endregion of this actors military entity without barrels or extras
	
#pragma region Life
protected:
	// Called by the engine, when actor damage is dealt
	virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCause) override;
	
	// Health Percentage for the current actor
	UFUNCTION(BlueprintPure, Category = "Health")
	float GetHealthPercent() const;

	// current lifes left
	UFUNCTION(BlueprintCallable, Category = "Lifes")
	int GetLifesLeft() const;

	// Starting Health Points to act. EditAnywhere to set individual Health Points
	UPROPERTY(EditAnywhere, Category = "Setup")
	int32 StartingHealth = 100;

	// Current Health for this actor
	UPROPERTY(VisibleAnywhere, Category = "Health")
	int32 CurrentHealth = 0;

	// Starting Life Count
	UPROPERTY(EditDefaultsOnly, Category = "Setup")
	int32 StartingLifes = 0;

	// Current Lifes left
	UPROPERTY(VisibleAnywhere, Category = "Lifes")
	int32 CurrentLifes = 0;
#pragma endregion Settings for Life and Health

};
#include "MilitaryEntity.h"

#include "Components/StaticMeshComponent.h"
#include "Components/ArrowComponent.h"

#include "AimingComponent.h"
#include "AudioEffectComponent.h"
#include "Turret.h"
#include "BarrelInterface.h"
#include "AbstractBarrel.h"

float AMilitaryEntity::TakeDamage(float DamageAmount, FDamageEvent const & DamageEvent, AController * EventInstigator, AActor * DamageCause)
{
	// Round the damage amount
	int32 DamagePoints = FPlatformMath::RoundToInt(DamageAmount);
	// Clamp the Damage to apply between 0 and the current health ans max
	auto DamageToApply = FMath::Clamp<int32>(DamagePoints, 0, CurrentHealth);
	
	//UE_LOG(LogTemp, Warning, TEXT("DamageAmount:%f ,DamageToApply:%i"), DamageAmount, DamageToApply)
	// Apply damage
	CurrentHealth -= DamageToApply;

	// if current health is below or equal 0
	if (CurrentHealth <= 0)
	{
		// Count down lifes
		CurrentLifes--;

		// if no more lifes left
		if (CurrentLifes <= 0)
		{
			// Call entities destruction behaviour
			OnDestruction();			
			// Broadcast destruction of this entity
			OnDeath.Broadcast();
		}
		else
		{
			CurrentHealth = StartingHealth;
			// TODO respawn in a small distance of time and place
		}
	}
	return DamageToApply;
}

// Initializes the entities instances
void AMilitaryEntity::OnConstruction(const FTransform& Transform)
{
	Super::OnConstruction(Transform);

	/// Attach all objects to its given location

	if (Body->GetSocketByName("TurretSocket"))
		PrimaryTurret->AttachToComponent(Body, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("TurretSocket"));
	else
		PrimaryTurret->AttachToComponent(Body, FAttachmentTransformRules::KeepRelativeTransform);

	if (PrimaryTurret->GetSocketByName("SecondarySocket"))
		SecondaryTurret->AttachToComponent(PrimaryTurret, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("SecondarySocket"));
	else
		SecondaryTurret->AttachToComponent(PrimaryTurret, FAttachmentTransformRules::KeepRelativeTransform);

	if (PrimaryTurret)
	{
		if (PrimaryTurret->GetSocketByName("BarrelSocket"))
			PrimaryDirection->AttachToComponent(PrimaryTurret, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("BarrelSocket"));
		else
			PrimaryDirection->AttachToComponent(PrimaryTurret, FAttachmentTransformRules::KeepRelativeTransform);
		/// Toggle the Arrows Debug visibility with ShowArrows value
		if (ShowArrows)
			PrimaryDirection->SetVisibility(true);
		else
			PrimaryDirection->SetVisibility(false);
	}

	if (SecondaryTurret)
	{
		if (SecondaryTurret && SecondaryTurret->GetSocketByName("BarrelSocket"))
			SecondaryDirection->AttachToComponent(SecondaryTurret, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("BarrelSocket"));
		else
			SecondaryDirection->AttachToComponent(SecondaryTurret, FAttachmentTransformRules::KeepRelativeTransform);
		SecondaryDirection->SetWorldScale3D(FVector(.5f));
		/// Toggle the Arrows Debug visibility with ShowArrows value
		if (ShowArrows)
			SecondaryDirection->SetVisibility(true);
		else
			SecondaryDirection->SetVisibility(false);
	}			
}

// BeginPlay innitializes Health, Life, Ammo and Fuel
// TODO Ammo and Fuel implementation
void AMilitaryEntity::BeginPlay()
{
	Super::BeginPlay();

	CurrentHealth = StartingHealth;
	CurrentLifes = StartingLifes;


	#if WITH_EDITOR
	SetFolderPath(EditorOutlinerFolderName);
	#endif
}

/// Getter Methods

AActor* AMilitaryEntity::GetLockedOnTarget() const {	return LockedOnTarget;	}
UTurret* AMilitaryEntity::GetPrimaryTurret() const {	return PrimaryTurret;	}
UTurret* AMilitaryEntity::GetSecondaryTurret() const {  return SecondaryTurret; }
UAimingComponent* AMilitaryEntity::GetAimingComponent() const {	return AimingComponent;	}
UStaticMeshComponent * AMilitaryEntity::GetBody() const{return Body; }
UAudioEffectComponent * AMilitaryEntity::GetAudioComponent() const { return AudioComponent; }

int AMilitaryEntity::GetLifesLeft() const	{	return CurrentLifes;	}
float AMilitaryEntity::GetHealthPercent() const { return float(CurrentHealth) / float(StartingHealth); }

/// Setter Methods

void AMilitaryEntity::SetVisibility(bool Visibility) {	VisibleToPlayer(Visibility); }
void AMilitaryEntity::SetLockedOnTarget(AActor* Target)	{	LockedOnTarget = Target; }

/// Constructor

AMilitaryEntity::AMilitaryEntity()
{
	PrimaryActorTick.bCanEverTick = true;
	
	Body = CreateDefaultSubobject<UStaticMeshComponent>(FName("Body"));
	
	PrimaryTurret = CreateDefaultSubobject<UTurret>(FName("PrimaryTurret"));
	SecondaryTurret = CreateDefaultSubobject<UTurret>(FName("SecondaryTurret"));
	
	PrimaryDirection = CreateDefaultSubobject<UArrowComponent>(FName("Primary Direction"));
	SecondaryDirection = CreateDefaultSubobject<UArrowComponent>(FName("Secondary Direction"));
	
	AudioComponent = CreateDefaultSubobject<UAudioEffectComponent>(FName("Audio Component"));
	AimingComponent = CreateDefaultSubobject<UAimingComponent>(FName("Aiming Component"));
}
#pragma once

#include "CoreMinimal.h"
#include "MilitaryEntity.h"
#include "TurretEntity.generated.h"

class UBarrel;
class UStaticMeshComponent;


UCLASS()
class TURRETPOWER_API ATurretEntity : public AMilitaryEntity
{
	GENERATED_BODY()
	
public:

	ATurretEntity();
	
	virtual void OnConstruction(const FTransform& Transform) override;


	UFUNCTION(BlueprintCallable, Category = "Setup")
	UBarrel* GetPrimaryBarrel();

	UFUNCTION(BlueprintCallable, Category = "Setup")
	UBarrel* GetSecondaryBarrel();

protected:
	// Socket scale is to scale the socket and rescale down the body afterwards
	UPROPERTY(EditDefaultsOnly, Category = "Setup")
	FVector SocketScale = FVector(1.f,1.f,1.f);

	// Socket is Showing
	UPROPERTY(VisibleAnywhere, Category = "Components")
	UStaticMeshComponent* Socket = nullptr;

	UPROPERTY(VisibleAnywhere, Category = "Components")
	UBarrel* PrimaryBarrel = nullptr;

	UPROPERTY(VisibleAnywhere, Category = "Components")
	UBarrel* SecondaryBarrel = nullptr;
};
#include "TurretEntity.h"

#include "Components/ArrowComponent.h"
#include "Components/StaticMeshComponent.h"

#include "AimingComponent.h"
#include "Barrel.h"
#include "Turret.h"


ATurretEntity::ATurretEntity() : AMilitaryEntity()
{
	Socket = CreateDefaultSubobject<UStaticMeshComponent>(FName("BodySocket"));
	
	PrimaryBarrel = CreateDefaultSubobject<UBarrel>(FName("PrimaryBarrel"));
	SecondaryBarrel = CreateDefaultSubobject<UBarrel>(FName("SecondaryBarrel"));

	RootComponent = Socket;
}

void ATurretEntity::OnConstruction(const FTransform& Transform)
{
	Super::OnConstruction(Transform);
		
	FVector Scale = FVector(1.0f);
	if (Socket)
	{
		Socket->SetWorldScale3D(Scale * SocketScale);
	}

	
	if (GetBody())
	{
		if (Socket->GetSocketByName("BodySocket"))
			GetBody()->AttachToComponent(Socket, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("BodySocket"));
		else
			GetBody()->AttachToComponent(Socket, FAttachmentTransformRules::KeepRelativeTransform);			
		
	//	GetBody()->SetWorldScale3D(Scale/SocketScale);
	}

	if (GetPrimaryTurret())
	{
		if (GetPrimaryTurret()->GetSocketByName("BarrelSocket"))
			PrimaryBarrel->AttachToComponent(GetPrimaryTurret(), FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("BarrelSocket"));
		else
			PrimaryBarrel->AttachToComponent(GetPrimaryTurret(), FAttachmentTransformRules::KeepRelativeTransform);
	}

	if (GetSecondaryTurret())
	{
		if (GetSecondaryTurret()->GetSocketByName("SecondaryBarrelSocket"))
			SecondaryBarrel->AttachToComponent(GetSecondaryTurret(), FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("SecondaryBarrelSocket"));
		else
			SecondaryBarrel->AttachToComponent(GetSecondaryTurret(), FAttachmentTransformRules::KeepRelativeTransform);
	}

	if (PrimaryBarrel->GetSocketByName("MuzzleSocket"))
		PrimaryDirection->AttachToComponent(PrimaryBarrel, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("MuzzleSocket"));
	else
		PrimaryDirection->AttachToComponent(PrimaryBarrel, FAttachmentTransformRules::KeepRelativeTransform);

	if (SecondaryBarrel->GetSocketByName("MuzzleSocket"))
		SecondaryDirection->AttachToComponent(SecondaryBarrel, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("MuzzleSocket"));
	else
		SecondaryDirection->AttachToComponent(SecondaryBarrel, FAttachmentTransformRules::KeepRelativeTransform);

	GetAimingComponent()->Initialize(GetPrimaryTurret(), PrimaryBarrel, GetSecondaryTurret(), SecondaryBarrel, GetAudioComponent());
}

UBarrel * ATurretEntity::GetPrimaryBarrel()
{
	return PrimaryBarrel;
}

UBarrel * ATurretEntity::GetSecondaryBarrel()
{
	return SecondaryBarrel;
}

It does not apply the attachment correctly
att

Privacy & Terms