Search code examples
c++collision-detectionunreal-engine4actor

how to make a collision of an actor on a character in C++ UE4?


I’m looking to make items that contain powers on unreal engine in c++ like :

When the player steps on it, he wins the Mushroom effect:

  • It has a scale of 1.25x.

So I create my Actor Item which contains the beginoverlap and the power function : Item.h

#pragma once

#include "CoreMinimal.h"
#include "Components/CapsuleComponent.h"
#include "Components/SphereComponent.h"
#include "GameFramework/Actor.h"
#include "Components/StaticMeshComponent.h"
#include "GameFramework/PlayerController.h"
#include "Character/Projet2Character.h"
#include "Item.generated.h"

UCLASS()
class PROJET2_API AItem : public AActor
{
    GENERATED_BODY()
    
public: 
    // Sets default values for this actor's properties
    AItem();
protected:

    UPROPERTY(EditAnywhere)
    USphereComponent* Collider;

    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:

    UFUNCTION()
    void OnBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

    UFUNCTION()
    void OnEndOverlap(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
    
    UFUNCTION()
    void Power();

   AProjet2Character* player;

    // Called every frame
    virtual void Tick(float DeltaTime) override;

};

Item.cpp

#include "Actor/Item.h"


// Sets default values
AItem::AItem()
{
   // 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;
   
   Mesh = CreateDefaultSubobject<UStaticMeshComponent>(FName("Mesh"));
   Mesh->SetupAttachment(RootComponent);
   RootComponent = Mesh;
   
   Collider = CreateDefaultSubobject<USphereComponent>(FName("Collider"));
   Collider->SetupAttachment(Mesh);

}

// Called when the game starts or when spawned
void AItem::BeginPlay()
{
   Super::BeginPlay();
   Collider->OnComponentBeginOverlap.AddDynamic(this, &AItem::OnBeginOverlap);
   Collider->OnComponentEndOverlap.AddDynamic(this, &AItem::OnEndOverlap);
   
}

void AItem::OnBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
   int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
   if(OtherActor->IsA(AProjet2Character::StaticClass()))
   {
     Power();
   }
}

void AItem::OnEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
   int32 OtherBodyIndex)
{
   if(OtherActor->IsA(AProjet2Character::StaticClass()))
   {
       Power();
   }
}

void AItem::Power()
{
player->GetMesh()->SetRelativeScale3D(FVector(1.5f,1.5f,1.5f));
}

// Called every frame
void AItem::Tick(float DeltaTime)
{
   Super::Tick(DeltaTime);
} 

When I launch the game at the moment I come into contact with the actor, unreal closes and the effect still does not apply to the character. I want to know how to do it? :)

Thank you for your understanding


Solution

  • I didnt quite understand. Do you want the player to step on the object and increase in size and then, when he leaves the object, return it to its original size (1) or keep the size (2)?

    //.h
    
        UFUNCTION()
        void Power();
    
        UFUNCTION()
        void ResetPower();
    
        bool bIsPower = false;
    //.cpp
    
    void AItem::ResetPower()
    {
        player->GetMesh()->SetRelativeScale3D(FVector(1.f,1.f,1.f));
    }
    

    1:

    //.cpp
    
    void AItem::OnBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
       int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
    {
       if(OtherActor->IsA(AProjet2Character::StaticClass()) && !bIsPower)
       {
          player = Cast<AProjet2Character>(OtherActor);
            bIsPower = true;
            Power();
       }
    }
    
    void AItem::OnEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
       int32 OtherBodyIndex)
    {
       if(OtherActor->IsA(AProjet2Character::StaticClass()) && bIsPower)
       {
           player = Cast<AProjet2Character>(OtherActor);
           bIsPower = false;
           ResetPower();
       }
    }
    

    2:

    void AItem::OnBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
       int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
    {
       if(OtherActor->IsA(AProjet2Character::StaticClass()) && !bIsPower)
       {
          player = Cast<AProjet2Character>(OtherActor);
            bIsPower = true;
            Power();
       }
    }
    
    void AItem::OnEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
       int32 OtherBodyIndex)
    {
       //Clear
    }