Add basic code

This commit is contained in:
2025-02-22 01:06:04 -05:00
parent 9ffe9abddb
commit d3f9f594af
6 changed files with 386 additions and 0 deletions
@@ -0,0 +1,114 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Hammer.h"
#include "StickySlimeComponent.h"
// Sets default values
AHammer::AHammer()
{
// 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;
MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("HammerMesh"));
RootComponent = MeshComponent;
MeshComponent->SetSimulatePhysics(true);
MeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
MeshComponent->SetCollisionObjectType(ECC_PhysicsBody);
MeshComponent->OnComponentHit.AddDynamic(this, &AHammer::OnHit);
MeshComponent->SetNotifyRigidBodyCollision(true);
MeshComponent->SetGenerateOverlapEvents(true);
GroundIdleTime = 1.0f;
AirIdleTime = 0.5f;
LiftSpeed = 100.0f;
bIsSlimed = false;
bIsMovingUp = false;
IdleTimer = 0.0f;
}
// Called when the game starts or when spawned
void AHammer::BeginPlay()
{
Super::BeginPlay();
InitialLocation = GetActorLocation();
}
// Called every frame
void AHammer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (bIsSlimed)
{
return;
}
if (bIsMovingUp && IdleTimer <= 0.0f)
{
FVector NewLocation = GetActorLocation();
NewLocation.Z += LiftSpeed * DeltaTime;
if (NewLocation.Z >= InitialLocation.Z)
{
NewLocation.Z = InitialLocation.Z;
bIsMovingUp = false;
IdleTimer = AirIdleTime;
}
SetActorLocation(NewLocation);
}
else if (IdleTimer > 0.0f)
{
IdleTimer -= DeltaTime;
if (IdleTimer <= 0.0f)
{
IdleTimer = 0.0f;
if (!bIsMovingUp)
{
MeshComponent->SetSimulatePhysics(true);
}
}
}
}
void AHammer::OnSlimed_Implementation(AActor* Slime)
{
ISlimableInterface::OnSlimed_Implementation(Slime);
bIsSlimed = true;
MeshComponent->SetSimulatePhysics(false);
}
void AHammer::OnUnslimed_Implementation()
{
ISlimableInterface::OnUnslimed_Implementation();
bIsSlimed = false;
IdleTimer = GroundIdleTime;
}
void AHammer::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent,
FVector NormalImpulse, const FHitResult& Hit)
{
UE_LOG(LogTemp, Warning, TEXT("Hit"));
if (bIsSlimed)
{
return;
}
if (!OtherActor || OtherActor == this)
{
return;
}
MeshComponent->SetSimulatePhysics(false);
IdleTimer = GroundIdleTime;
bIsMovingUp = true;
}
@@ -0,0 +1,61 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SlimableInterface.h"
#include "Hammer.generated.h"
UCLASS()
class WIZARDINGCENTRAL_API AHammer : public AActor, public ISlimableInterface
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AHammer();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called when slimed
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "StickySlime")
void OnSlimed(AActor* Slime);
virtual void OnSlimed_Implementation(AActor* Slime) override;
// Called when un-slimed
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "StickySlime")
void OnUnslimed();
virtual void OnUnslimed_Implementation() override;
protected:
UFUNCTION()
virtual void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent,
FVector NormalImpulse, const FHitResult& Hit);
private:
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Hammer", meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent* MeshComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hammer", meta = (AllowPrivateAccess = "true"))
float GroundIdleTime;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hammer", meta = (AllowPrivateAccess = "true"))
float AirIdleTime;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Hammer", meta = (AllowPrivateAccess = "true"))
float LiftSpeed;
FVector InitialLocation;
bool bIsSlimed;
bool bIsMovingUp;
float IdleTimer;
};
@@ -0,0 +1,25 @@
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "SlimableInterface.generated.h"
UINTERFACE(MinimalAPI, Blueprintable)
class USlimableInterface : public UInterface
{
GENERATED_BODY()
};
class WIZARDINGCENTRAL_API ISlimableInterface
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Sticky Slime")
void OnSlimed(AActor* Slime);
virtual void OnSlimed_Implementation(AActor* Slime) {};
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Sticky Slime")
void OnUnslimed();
virtual void OnUnslimed_Implementation() {};
};
@@ -0,0 +1,16 @@
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "SlimeAnchorInterface.generated.h"
UINTERFACE(MinimalAPI, Blueprintable)
class USlimeAnchorInterface : public UInterface
{
GENERATED_BODY()
};
class WIZARDINGCENTRAL_API ISlimeAnchorInterface
{
GENERATED_BODY()
};
@@ -0,0 +1,125 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "StickySlimeComponent.h"
#include "SlimableInterface.h"
#include "SlimeAnchorInterface.h"
// Sets default values for this component's properties
UStickySlimeComponent::UStickySlimeComponent()
{
// 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 = false;
// ...
// Initialize
AttachedActor1 = nullptr;
AttachedActor1 = nullptr;
bIsActivated = false;
}
// Called when the game starts
void UStickySlimeComponent::BeginPlay()
{
Super::BeginPlay();
// ...
}
void UStickySlimeComponent::AttachToActor(AActor* Target)
{
if (!Target || this->AttachedActor1 == Target || this->AttachedActor2 == Target)
{
return;
}
if (bIsActivated)
{
return;
}
if (this->AttachedActor1)
{
UE_LOG(LogTemp, Warning, TEXT("Attaching to actor"));
this->ActivateIfAnchored(Target);
}
UE_LOG(LogTemp, Warning, TEXT("Attaching to actor"));
this->AttachedActor1 = Target;
this->GetOwner()->AttachToComponent(Target->GetRootComponent(),
FAttachmentTransformRules::KeepWorldTransform);
}
void UStickySlimeComponent::ActivateIfAnchored(AActor* Target)
{
if (!Target || this->AttachedActor1 == Target || this->AttachedActor2 == Target)
{
return;
}
if (bIsActivated)
{
return;
}
this->AttachedActor2 = Target;
const bool bA1IsAnchor = this->AttachedActor1->GetClass()->
ImplementsInterface(USlimeAnchorInterface::StaticClass());
const bool bA2IsAnchor = this->AttachedActor2->GetClass()->
ImplementsInterface(USlimeAnchorInterface::StaticClass());
if (!bA1IsAnchor && !bA2IsAnchor)
{
this->AttachedActor2 = nullptr;
return;
}
bIsActivated = true;
if (bA1IsAnchor && this->AttachedActor2->GetClass()->ImplementsInterface(USlimableInterface::StaticClass()))
{
ISlimableInterface::Execute_OnSlimed(this->AttachedActor2, this->GetOwner());
}
else if (bA2IsAnchor && this->AttachedActor1->GetClass()->ImplementsInterface(USlimableInterface::StaticClass()))
{
ISlimableInterface::Execute_OnSlimed(this->AttachedActor1, this->GetOwner());
}
else
{
this->BreakSlime();
}
}
void UStickySlimeComponent::BreakSlime()
{
if (!bIsActivated)
{
return;
}
if (this->AttachedActor1->GetClass()->ImplementsInterface(USlimableInterface::StaticClass()))
{
ISlimableInterface::Execute_OnUnslimed(this->AttachedActor1);
}
if (this->AttachedActor2->GetClass()->ImplementsInterface(USlimableInterface::StaticClass()))
{
ISlimableInterface::Execute_OnUnslimed(this->AttachedActor2);
}
this->AttachedActor1 = nullptr;
this->AttachedActor2 = nullptr;
this->bIsActivated = false;
}
// // Called every frame
// void UStickySlimeComponent::TickComponent(float DeltaTime, ELevelTick TickType,
// FActorComponentTickFunction* ThisTickFunction)
// {
// Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
//
// // ...
// }
@@ -0,0 +1,45 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "PhysicsEngine/PhysicsConstraintComponent.h"
#include "StickySlimeComponent.generated.h"
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class WIZARDINGCENTRAL_API UStickySlimeComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UStickySlimeComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// // Called every frame
// virtual void TickComponent(float DeltaTime, ELevelTick TickType,
// FActorComponentTickFunction* ThisTickFunction) override;
UFUNCTION(BlueprintCallable, Category="Skicky Slime")
void AttachToActor(AActor* Target);
UFUNCTION(BlueprintCallable, Category="Sticky Slime")
void ActivateIfAnchored(AActor* Target);
UFUNCTION(BlueprintCallable, BlueprintCallable, Category = "Sticky Slime")
void BreakSlime();
private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Sticky Slime", meta=(AllowPrivateAccess="true"))
AActor* AttachedActor1;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Sticky Slime", meta=(AllowPrivateAccess="true"))
AActor* AttachedActor2;
bool bIsActivated;
};