Dear community,
Is it possible having physics on an AActor with only a UBoxComponent attached?
What i basicly want is an AActor with only a UBoxComponent attached with physics enabled.
The Actor has NO static mesh attached, I use an Instanced Static Mesh instead.
The instanced static mesh gets its transform updated by passing the current Actor transform.
My question(s)
- Is it even possible to have an actor with only a boxcomponent and physics enabled?
- If so, could someone please give or point to a basic example?
I tried many many things, read docs and threads, but the examples given assumes characters/pawns/actors with a static mesh…
Below some code i tried…
I hope someone can help this happy noob
Greetz,
G
.h file
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/Actor.h"
#include "CQBgDebrisCollisionActor.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(QBgDebris_CollisionActor, All, All);
UCLASS()
class TWINSTICK_API ACQBgDebrisCollisionActor : public AActor
{
GENERATED_BODY()
//CONSTRUCTOR/DESTRUCTOR =========================================================================
public:
ACQBgDebrisCollisionActor(const FObjectInitializer& PCIP);
//FUNCTIONS ======================================================================================
public:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
/* Called externally to start physics */
void C_QActivate();
//--- COLLISION ==================================================================================
/* ReceiveHit */
virtual void ReceiveHit(class UPrimitiveComponent * MyComp,
class AActor * Other,
class UPrimitiveComponent * OtherComp,
bool bSelfMoved,
FVector HitLocation,
FVector HitNormal,
FVector NormalImpulse,
const FHitResult & Hit
) override;
/* ReceiveActorBeginOverlap */
virtual void ReceiveActorBeginOverlap(AActor * OtherActor) override;
//--- PHYSICS ====================================================================================
/* */
void C_QINITPhysics();
/* Called externally */
void C_QDisablePhysics();
//VARS ===========================================================================================
public:
//--- Collision
UPROPERTY()
UBoxComponent* c_p_Collider;
//--- Physics / Kinematic
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "QPhysics")
bool c_QDoUseGravity;
};
.cpp file
// Fill out your copyright notice in the Description page of Project Settings.
#include "TwinStick.h"
#include "CQBgDebrisCollisionActor.h"
//--- General log
DEFINE_LOG_CATEGORY(QBgDebris_CollisionActor);
/**
* @brief ACQBgDebrisCollisionActor::ACollisionActor
* @param PCIP
*/
ACQBgDebrisCollisionActor::ACQBgDebrisCollisionActor(const FObjectInitializer& PCIP) : Super(PCIP)
{
//--- ACTOR
PrimaryActorTick.bCanEverTick = false;
SetActorTickEnabled(false);
//--- COLLIDER setup
c_p_Collider = PCIP.CreateDefaultSubobject<UBoxComponent>(this,TEXT("BoxColliderComponent"));
c_p_Collider->bAutoActivate = false;
c_p_Collider->bOwnerNoSee = false;
c_p_Collider->bCastDynamicShadow = false;
c_p_Collider->CastShadow = false;
c_p_Collider->SetMobility(EComponentMobility::Movable);
c_p_Collider->BodyInstance.SetObjectType(ECC_WorldDynamic);
c_p_Collider->BodyInstance.SetResponseToAllChannels(ECR_Ignore);
c_p_Collider->PrimaryComponentTick.bCanEverTick = false;
c_p_Collider->bTraceComplexOnMove = false;
c_p_Collider->bGenerateOverlapEvents = true;
//--- Initial dimensions; EXTERNALLY set when instance of this actor is activated
c_p_Collider->InitBoxExtent(FVector(0.f, 0.f, 0.f));
// -- Set as rootcomponent
RootComponent = c_p_Collider;
//--- Initial COLLISION / PHYSICS disabled; Call C_QActivate() to enable...
C_QDisablePhysics();
//--- TODO DEBUG
c_p_Collider->SetHiddenInGame(false); //Keep actor visible for debugging
}
/**
* @brief ACQBgDebrisCollisionActor::BeginPlay
*/
void ACQBgDebrisCollisionActor::BeginPlay()
{
Super::BeginPlay();
}
/**
* @brief ACQBgDebrisCollisionActor::C_QActivate
*/
void ACQBgDebrisCollisionActor:: C_QActivate()
{
c_p_Collider->SetActive(true);
C_QINITPhysics();
}
/**
* @brief ACQBgDebrisCollisionActor::ReceiveHit
* @param MyComp
* @param Other
* @param OtherComp
* @param bSelfMoved
* @param HitLocation
* @param HitNormal
* @param NormalImpulse
* @param Hit
*/
void ACQBgDebrisCollisionActor::ReceiveHit(
class UPrimitiveComponent * MyComp,
class AActor * Other,
class UPrimitiveComponent * OtherComp,
bool bSelfMoved,
FVector HitLocation,
FVector HitNormal,
FVector NormalImpulse,
const FHitResult & Hit
)
{
Super::ReceiveHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation, HitNormal, NormalImpulse, Hit);
// ...
UE_LOG(QBgDebris_CollisionActor, Log, TEXT("ReceiveHit"));
}
/**
* @brief ACQBgDebrisCollisionActor::ReceiveActorBeginOverlap
* @param OtherActor
*/
void ACQBgDebrisCollisionActor::ReceiveActorBeginOverlap(AActor * OtherActor)
{
Super::ReceiveActorBeginOverlap(OtherActor);
// ...
UE_LOG(QBgDebris_CollisionActor, Log, TEXT("ReceiveActorBeginOverlap"));
}
/**
* @brief ACQBgDebrisCollisionActor::C_QINITPhysics
*/
void ACQBgDebrisCollisionActor::C_QINITPhysics()
{
//--- Setup collison
c_p_Collider->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Block);
c_p_Collider->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Block);
c_p_Collider->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
//-- Fire Hit event when this object collides
c_p_Collider->BodyInstance.SetInstanceNotifyRBCollision(true);
//---
c_p_Collider->BodyInstance.MassInKg = 100.f;
//--- Enable collision
SetActorEnableCollision(true);
c_p_Collider->BodyInstance.SetEnableGravity(c_QDoUseGravity);
c_p_Collider->BodyInstance.SetInstanceSimulatePhysics(true);
//---
c_p_Collider->Activate();
//--- TODO TEST
c_p_Collider->BodyInstance.AddImpulse(FVector(0.f,1000.f,0.f),true);
//--- TODO LOG Always returns 0!
UE_LOG(QBgDebris_CollisionActor, Log, TEXT("C_QINITPhysics Mass: %f "),
c_p_Collider->GetMass());
//--- Always returns FALSE!
if(c_QDoUseGravity)
{
UE_LOG(QBgDebris_CollisionActor, Log, TEXT("C_QINITPhysics GRAVITIY enabled "));
}
else
{
UE_LOG(QBgDebris_CollisionActor, Log, TEXT("C_QINITPhysics GRAVITIY disabled "));
}
if(c_p_Collider->IsSimulatingPhysics())
{
UE_LOG(QBgDebris_CollisionActor, Log, TEXT("C_QINITPhysics PHYSICS enabled "));
}
else
{
UE_LOG(QBgDebris_CollisionActor, Log, TEXT("C_QINITPhysics PHYSICS disabled "));
}
}
/**
* @brief ACQBgDebrisCollisionActor::C_QDisablePhysics
*/
void ACQBgDebrisCollisionActor::C_QDisablePhysics()
{
c_p_Collider->SetActive(false);
c_p_Collider->BodyInstance.SetResponseToAllChannels(ECR_Ignore);
c_p_Collider->SetNotifyRigidBodyCollision(false);
c_p_Collider->BodyInstance.SetInstanceSimulatePhysics(false);
c_p_Collider->BodyInstance.SetCollisionEnabled(ECollisionEnabled::NoCollision);
//--- Disable collision
SetActorEnableCollision(false);
}