I’ve just started to develop with Unreal Engine and I’ve been for five days trying to understand how collision works.
I’m developing a Pong game, and I’m trying to make that the Ball bounces with the Paddle.
The Ball class has a UProjectileMovementComponent
to move it and the Paddle will be controlled by the player with a UPawnMovementComponent
custom class. So, both will move.
These are my two classes:
Ball:
ABall::ABall()
{
// 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;
VisualComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualComp"));
CollisionComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("CollComp"));
static ConstructorHelpers::FObjectFinder<UStaticMesh> VisualAsset(TEXT("/Game/Geometry/Meshes/Ball_mesh.Ball_mesh"));
if (VisualAsset.Succeeded())
{
VisualComponent->SetStaticMesh(VisualAsset.Object);
VisualComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
VisualComponent->SetWorldScale3D(FVector(1.0f));
FBoxSphereBounds Bounds = VisualAsset.Object->ExtendedBounds;
CollisionComponent->SetRelativeLocation(Bounds.Origin);
CollisionComponent->SetBoxExtent(Bounds.BoxExtent);
}
RootComponent = CollisionComponent;
VisualComponent->SetupAttachment(CollisionComponent);
VisualComponent->SetCollisionProfileName(TEXT("NoCollision"));
CollisionComponent->SetCollisionProfileName(TEXT("Projectile"));
CollisionComponent->OnComponentHit.AddDynamic(this, &ABall::OnHit);
// Use this component to drive this ball's movement.
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComponent"));
ProjectileMovementComponent->SetUpdatedComponent(CollisionComponent);
ProjectileMovementComponent->InitialSpeed = 0.0f;
ProjectileMovementComponent->MaxSpeed = 90.0f;
ProjectileMovementComponent->bRotationFollowsVelocity = false;
ProjectileMovementComponent->bShouldBounce = true;
ProjectileMovementComponent->Bounciness = 0.3f;
ProjectileMovementComponent->ProjectileGravityScale = 0.0f;
}
Paddle:
APaddle::APaddle()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Set this pawn to be controlled by the lowest-numbered player
AutoPossessPlayer = EAutoReceiveInput::Player0;
CollisionComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("CollComp"));
VisualComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualComp"));
RootComponent = CollisionComponent;
// Set up CollisionComponent as parent of VisualComponent;
VisualComponent->SetupAttachment(CollisionComponent);
VisualComponent->BodyInstance.SetCollisionProfileName("NoCollision");
CollisionComponent->BodyInstance.SetCollisionProfileName("Pawn");
// Initialize paddle velocity.
CurrentVelocity.Z = 0.0f;
// Create an instance of our movement component, and tell it to update our root component.
OurMovementComponent = CreateDefaultSubobject<UPaddlePawnMovementComponent>(TEXT("CustomMovementComponent"));
OurMovementComponent->UpdatedComponent = RootComponent;
}
Both have a UBoxComponent as a collision component and a Static Mesh as a Visual Component. The Static Mesh uses NoCollision Preset and Collision Component uses Pawn in the Paddle and Projectile (custom preset) in the Ball.
Projectile Preset is:
And Projectile Object Type is:
I have tried a lot of combinations and the only one that works is when both classes, have, at least, Query only selected.
I think that Query only is used to trigger Overlap events but if I don’t select it, OnComponentHit
won’t trigger.
Is there anything wrong with my code or am I wrong about Query Only and what it does?