For your particular example, what are you trying to do?
have the pickup add its self to the player who picked it up and then destroy it. I would like to make it respawn at a later time but I haven’t gotten that far.
Have the pickup call OnPickedUpEvent() for every machine and then destroy the pickup?
yes this is what I thought I was trying to do but I don’t think the client is reaching OnPickedUpEvent()
How are you handling the pickup part?
Right now I have an interface that traces to a boxcomponent set as root which when hit will display a canvas USE message. and also will allow you to pick it up with a key
When someone collides with the pickup? no. I used existing pickup code that was in shootergame and changed it from a particlefx to a mesh. Although now I can see that the particlefx is easier to deal with since you can just activate and deactivate it. if this is the better route I will revert back to it.
I will post the code here you probably will be able to analyze it better and see my errors
.h
UCLASS(abstract)
class ACH_Pickup : public AActor, public ICH_UseInterface
{
GENERATED_UCLASS_BODY()
/** check if pawn can use this pickup */
virtual bool CanBePickedUp(class AShooterCharacter* TestPawn) const;
/** initial setup */
virtual void BeginPlay() OVERRIDE;
protected:
/** collisions */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Pickup)
TSubobjectPtr<class UBoxComponent> CollisionComp;
/** Pickupmesh component */
UPROPERTY(VisibleDefaultsOnly, Category = Pickup)
TSubobjectPtr<UStaticMeshComponent> CHPickupMesh;
/** FX of active pickup */
UPROPERTY(EditDefaultsOnly, Category = Effects)
UParticleSystem* ActiveFX;
/** FX of pickup on respawn timer */
UPROPERTY(EditDefaultsOnly, Category = Effects)
UParticleSystem* RespawningFX;
/** sound played when player picks it up */
UPROPERTY(EditDefaultsOnly, Category = Effects)
USoundCue* PickupSound;
/** sound played on respawn */
UPROPERTY(EditDefaultsOnly, Category = Effects)
USoundCue* RespawnSound;
/** how long it takes to respawn? */
UPROPERTY(EditDefaultsOnly, Category = Pickup)
float RespawnTime;
/** is it ready for interactions? */
UPROPERTY(Transient, ReplicatedUsing = OnRep_IsActive)
uint32 bIsActive : 1;
/* The character who has picked up this pickup */
UPROPERTY(Transient, Replicated)
AShooterCharacter* PickedUpBy;
UFUNCTION()
void OnRep_IsActive();
/** give pickup */
virtual void GivePickupTo(class AShooterCharacter* Pawn);
/** handle touches */
void PickupOnTouch(class AShooterCharacter* Pawn);
/** show and enable pickup */
virtual void RespawnPickup();
/** show effects when pickup disappears */
virtual void OnPickedUp();
/** show effects when pickup appears */
virtual void OnRespawned();
/** blueprint event: pickup disappears */
UFUNCTION(BlueprintImplementableEvent)
virtual void OnPickedUpEvent();
/** blueprint event: pickup appears */
UFUNCTION(BlueprintImplementableEvent)
virtual void OnRespawnEvent();
// USE - DJMK
virtual void DisplayPrompt(UCanvas* Canvas, AController * user) OVERRIDE;
// USE - DJMK
virtual void OnUsed(class AController* user);
/** shutdown mesh when picked up - DJMK */
UFUNCTION(reliable, netmulticast)
virtual void CullAndDestroy();
UPROPERTY(EditDefaultsOnly, Category = Debug)
bool DrawDebug;
};
.cpp
#include "CH_Pickup.h"
ACH_Pickup::ACH_Pickup(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
CollisionComp = PCIP.CreateDefaultSubobject<UBoxComponent>(this, TEXT("PickupComp"));
CollisionComp->InitBoxExtent(FVector(20, 20, 20));
CollisionComp->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
CollisionComp->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore);
CollisionComp->SetCollisionResponseToChannel(COLLISION_PROJECTILE, ECR_Block);
RootComponent = CollisionComp;
CHPickupMesh = PCIP.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("PickupMesh"));
CHPickupMesh->bAutoActivate = false;
CHPickupMesh->AttachParent = RootComponent;
RespawnTime = 10.0f;
bIsActive = false;
PickedUpBy = NULL;
SetRemoteRoleForBackwardsCompat(ROLE_SimulatedProxy);
bReplicates = true;
bReplicateInstigator = true; //for projectiles, see actor description
bReplicateMovement = true;
DrawDebug = false;
}
void ACH_Pickup::BeginPlay()
{
Super::BeginPlay();
RespawnPickup();
// register on pickup list (server only), don't care about unregistering (in FinishDestroy) - no streaming
AShooterGameMode* GameMode = GetWorld()->GetAuthGameMode<AShooterGameMode>();
if (GameMode)
{
GameMode->CHLevelPickups.Add(this);
}
}
void ACH_Pickup::OnUsed(class AController* user)
{
AShooterCharacter* picker = Cast<AShooterCharacter>(user->GetPawn());
PickupOnTouch(Cast<AShooterCharacter>(picker));
}
bool ACH_Pickup::CanBePickedUp(class AShooterCharacter* TestPawn) const
{
return TestPawn && TestPawn->IsAlive();
}
void ACH_Pickup::GivePickupTo(class AShooterCharacter* Pawn)
{
}
void ACH_Pickup::PickupOnTouch(class AShooterCharacter* Pawn)
{
if (bIsActive && Pawn && Pawn->IsAlive() && !IsPendingKill())
{
if (CanBePickedUp(Pawn))
{
GivePickupTo(Pawn);
PickedUpBy = Pawn;
if (!IsPendingKill())
{
bIsActive = false;
OnPickedUp();
if (RespawnTime > 0.0f)
{
GetWorldTimerManager().SetTimer(this, &ACH_Pickup::RespawnPickup, RespawnTime, false);
}
}
}
}
}
void ACH_Pickup::RespawnPickup()
{
bIsActive = true;
PickedUpBy = NULL;
OnRespawned();
}
void ACH_Pickup::OnPickedUp()
{
if (RespawningFX)
{
//PickupPSC->SetTemplate(RespawningFX);
//PickupPSC->ActivateSystem();
}
else
{
//PickupPSC->DeactivateSystem();
}
if (PickupSound && PickedUpBy)
{
UGameplayStatics::PlaySoundAttached(PickupSound, PickedUpBy->GetRootComponent());
}
OnPickedUpEvent();
CullAndDestroy();
}
void ACH_Pickup::OnRespawned()
{
const bool bJustSpawned = CreationTime <= (GetWorld()->GetTimeSeconds() + 5.0f);
if (!bJustSpawned)
{
}
OnRespawnEvent();
}
void ACH_Pickup::OnRep_IsActive()
{
if (bIsActive)
{
OnRespawned();
}
else
{
OnPickedUp();
}
}
void ACH_Pickup::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ACH_Pickup, bIsActive);
DOREPLIFETIME(ACH_Pickup, PickedUpBy);
}
/** shutdown pickup mesh */
void ACH_Pickup::CullAndDestroy_Implementation()
{
Destroy();
SetLifeSpan(0.1);
SetActorHiddenInGame(true);
CollisionComp->SetCollisionEnabled(ECollisionEnabled::NoCollision);
CollisionComp->SetCollisionResponseToAllChannels(ECR_Ignore);
}
/** Display Use Helper - DJMK */
void ACH_Pickup::DisplayPrompt(UCanvas* Canvas, AController* user)
{
float x, y;
Canvas->GetCenter(x, y);
FVector ScreenPos = Canvas->Project(GetActorLocation());
FString UseText = FString("<USE>");
float SizeX, SizeY;
Canvas->StrLen(GEngine->GetLargeFont(), UseText, SizeX, SizeY);
Canvas->DrawText(GEngine->GetLargeFont(), UseText, ScreenPos.X - SizeX * 2, ScreenPos.Y, 4, 4);
}