Hello folks!
I feel like I’ve got a pretty simple problem, in a relatively complicated situation. Please don’t run away because of all the code down there! It’s just to be sure whoever can help me has all the info he needs. Here goes.
I am using three different actors here, one for the player, one for the enemy, and one for the weapon used by the enemy.
The weapon is placed in the hand of the enemy at the start of the game, and when the player is within range, he swings. I placed a notify at the moment of the animation when I want the weapon to be able to damage the player. As far as my tests go, the notify works.
I want to use the notify to change a bool variable in the weapon’s class. However, I am having trouble “getting” to the weapon from the “enemy” animation blueprint. Here are the relevant bits of code.
from enemy.h
UCLASS()
class GOLDENEGGREDUX_API AEnemy : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AEnemy(const FObjectInitializer& ObjectInitializer);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MonsterProperties)
UClass* BPMonsterWeapon;
//The melee weapon instance
AActor* MonsterWeapon;
};
from enemy.cpp
AEnemy::AEnemy(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
}
void AEnemy::PostInitializeComponents()
{
Super::PostInitializeComponents();
//instantiate the weapon if the bp is selected
if (BPMonsterWeapon)
{
MonsterWeapon = GetWorld()->SpawnActor<AAMeleeWeapon>(BPMonsterWeapon, FVector(), FRotator());
if (MonsterWeapon)
{
const USkeletalMeshSocket *socket = Mesh->GetSocketByName("RightHandWeapon");
socket->AttachActor(MonsterWeapon, Mesh);
}
}
}
from MeleeWeapon.h
UCLASS()
class GOLDENEGGREDUX_API AMeleeWeapon : public AActor
{
GENERATED_BODY()
public:
AMeleeWeapon(const FObjectInitializer& ObjectInitializer);
//We need a list of the things hit by the weapon during a swing, so we don't hit anything twice
TArray<AActor*> ThingsHit;
//Prevents damage from happening while we're not swinging
bool isSwinging;
AEnemy *WeaponHolder;
//Box that's the collision box for hitting stuff
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = MeleeWeapon)
UBoxComponent* ProxBox;
UFUNCTION(BlueprintNativeEvent, Category = "Collision")
void Prox(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
void Prox_Implementation(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
UFUNCTION(BlueprintCallable, Category = Collision)
void Swing();
};
from MeleeWeapon.cpp
AMeleeWeapon::AMeleeWeapon(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
isSwinging = false;
WeaponHolder = NULL;
ProxBox = ObjectInitializer.CreateDefaultSubobject<UBoxComponent>(this, TEXT("ProxBox"));
ProxBox->OnComponentBeginOverlap.AddDynamic(this, &AMeleeWeapon::Prox);
ProxBox->AttachTo(RootComponent);
}
//Implementation of the hit
void AMeleeWeapon::Prox_Implementation(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
//Don't hit non root components on stuff
if (OtherComp != OtherActor->GetRootComponent())
{
return;
}
AAvatar *player = Cast<AAvatar>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
//Don't hit things when not swinging, hit only the player, and don't hit the same thing twice
if (isSwinging && OtherActor == player && !ThingsHit.Contains(OtherActor))
{
GEngine->AddOnScreenDebugMessage(0, 1.f, FColor::Green, "You got hit");
ThingsHit.Add(OtherActor);
}
}
//Function for swinging
void AMeleeWeapon::Swing()
{
ThingsHit.Empty();
isSwinging = true;
}
I tried to remove everything irrelevant to my problem, for clarity’s sake. BP_MonsterWeapon is a blueprint derived from the MeleeWeapon class. It can be chosen from the blueprint derived from the enemy.cpp class. Now, here is the blueprint for the enemy’s animation.
You can see down there my SwordSwung notify. I tested it by printing debug text, and it worked since everytime the enemy swung, text was print to the screen. I also know the collision between the sword and the player works well, since if I set the bool isSwinging to be always true, the debug text “You got hit” prints to the screen.
All I want now, is to be able to use the “Swing()” function from the relevant weapon class at every SwordSwung notify. I haven’t had to use a function so many “levels” from the one I’m using until now, so I’m not sure how I should go about this.
I don’t really want a walkthrough, I’d quite appreciate pointers as to what I should do.
Thank you! If you need to know anything else, fire away.