Hello guys,
I am working on a personal project about futuristic racing (think wipeout). I am a programmer and this is meant to showcase my programming skills, I am trying to figure out the proper way of adding force to a pawn. However, I could only get as far as moving just the root component, while the static mesh is left behind. Also, the root component still clips through world geometry although I set collisionEnabled to physics only. So my two questions are:
1- Why is the static mesh component not moving with the root (sphere component)?
2- Why is the root (sphere component) not colliding with floor and world geometry if I set collision enabled to physics only?
Please don’t send me to a tutorial, I want to understand what I am doing wrong here. Thanks in advance!
#include "CustomCar.h"
#include "Camera/CameraComponent.h"
#include "Components/InputComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Components/ActorComponent.h"
#include "Components/SphereComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/PlayerController.h"
#include "DrawDebugHelpers.h"
#define OUT
// Sets default values
ACustomCar::ACustomCar()
{
PrimaryActorTick.bCanEverTick = true;
//set this pawn to be controlled by the lowest-numbered player
AutoPossessPlayer = EAutoReceiveInput::Player0;
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
//create dummy root component we can attach things to.
RootComponent = SphereComponent;
OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent"));
OurVisibleComponent->SetupAttachment(RootComponent);
SphereComponent->SetSimulatePhysics(true);
SphereComponent->SetEnableGravity(false);
SphereComponent->InitSphereRadius(40.f);
SphereComponent->SetCollisionProfileName(TEXT("FloatingCar"));
SphereComponent->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly);
SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("OurSpringArm"));
SpringArmComponent->SetupAttachment(RootComponent);
SpringArmComponent->TargetArmLength = 300;
SpringArmComponent->bEnableCameraLag = true;
//Create a camera and a visible object
OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera"));
OurCamera->SetupAttachment(SpringArmComponent);
OurCamera->SetRelativeLocation(FVector(-250, 0, 250));
OurCamera->SetRelativeRotation(FRotator(-45, 0, 0));
}
// Called when the game starts or when spawned
void ACustomCar::BeginPlay()
{
Super::BeginPlay();
}
FVector ACustomCar::GetReachLineStart()
{
FVector PlayerPosition;
FRotator PlayerRotation;
PlayerPosition = GetActorLocation();
return PlayerPosition;
}
FVector ACustomCar::GetReachLineEnd()
{
FVector PlayerPosition;
FRotator PlayerRotation;
PlayerPosition = GetActorLocation();
return PlayerPosition - GetActorUpVector()*RaycastReach;
}
// Called every frame
void ACustomCar::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
CarSpeed = FVector::DotProduct(GetVelocity(), GetActorForwardVector());
{
Hovering();
}
}
void ACustomCar::Hovering()
{
FHitResult Hit = RaycastToFloor();
FVector groundNormal;
if (Hit.bBlockingHit)//if hit ground
{
float height = Hit.Distance;
groundNormal = Hit.Normal;
float forcePercent = 0.0f; // temporary variable for adjusting the force of the thruster for the hovering
if (height > 50.0f)
forcePercent = 0.75f;
else
forcePercent = 1.0f;
//Apply hover force
SphereComponent->AddForce(groundNormal * HoverForce * forcePercent);
//Apply custom gravity
SphereComponent->AddForce((-1)*groundNormal * HoverGravity * height);
}
else//flying
{
SphereComponent->AddForce(FVector(0, 0, -FallGravity));
}
}
// Called to bind functionality to input
void ACustomCar::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (PlayerInputComponent)
{
PlayerInputComponent->BindAxis("Accelerate", this, &ACustomCar::Accelerate);
PlayerInputComponent->BindAxis("Steer", this, &ACustomCar::Steer);
}
}
FHitResult ACustomCar::RaycastToFloor()
{
//Setup query parameters
FCollisionQueryParams TraceParameters(FName(TEXT("")), false, this);
FVector v1 = GetReachLineStart();
FVector v2 = GetReachLineEnd();
FHitResult Hit;
GetWorld()->LineTraceSingleByObjectType(
OUT Hit,
v1,
v2,
FCollisionObjectQueryParams(ECollisionChannel::ECC_WorldStatic),
TraceParameters
);
//draw debug line representing raycast
DrawDebugLine(GetWorld(), v1, v2, FColor::Red, false, 0, 0, 10.0f);
return Hit;
}
void ACustomCar::Accelerate(float AxisValue)
{
//SphereComponent->AddForce(FVector(GetActorForwardVector()*Acceleration*AxisValue));
SphereComponent->AddForce(FVector(GetActorForwardVector()*Acceleration*AxisValue));
}
void ACustomCar::Steer(float AxisValue)
{
FRotator steer = FRotator(0, AxisValue * SteerRate, 0);
SphereComponent->AddLocalRotation(steer);
}