Hello guys!
I wanna ask some help for this issue.
For some reason, the BlackHoleSkill os moving through the ground, following a strange direction.
Here are the code snippets:
The Black Hole Skill:
// Fill out your copyright notice in the Description page of Project Settings.
#include "BlackHoleSkill.h"
#include "Kismet/GameplayStatics.h"
#include "FPSConstants.h"
#include "Components/SphereComponent.h"
#include "DrawDebugHelpers.h"
#include "Kismet/KismetMathLibrary.h"
#include "Components/BoxComponent.h"
#include "Engine/LevelBounds.h"
#include "GameFramework/ProjectileMovementComponent.h"
// Sets default values
ABlackHoleSkill::ABlackHoleSkill()
{
// 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;
BlackHoleGravitationalInfluence = CreateDefaultSubobject<USphereComponent>(TEXT("BlackHoleGravitationalInfluence"));
BlackHoleGravitationalInfluence->SetSphereRadius(300);
//BlackHoleGravitationalInfluence->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
//BlackHoleGravitationalInfluence->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
//BlackHoleGravitationalInfluence->SetGenerateOverlapEvents(true);
//BlackHoleGravitationalInfluence->SetSimulatePhysics(true);
BlackHoleGravitationalInfluence->SetCollisionProfileName("Projectile");
RootComponent = BlackHoleGravitationalInfluence;
BlackHoleEventHorizon = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BlackHoleEventHorizon"));
BlackHoleEventHorizon->SetWorldScale3D(FVector(.05f, .05f, .05f));
BlackHoleEventHorizon->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
BlackHoleEventHorizon->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
BlackHoleEventHorizon->SetGenerateOverlapEvents(true);
BlackHoleEventHorizon->SetSimulatePhysics(true);
BlackHoleEventHorizon->SetupAttachment(BlackHoleGravitationalInfluence);
BlackHoleMovementComp = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("BlackHoleMovementComp"));
BlackHoleMovementComp->SetUpdatedComponent(BlackHoleGravitationalInfluence);
BlackHoleMovementComp->InitialSpeed = 3500.f;
BlackHoleMovementComp->MaxSpeed = 3500.f;
BlackHoleMovementComp->bRotationFollowsVelocity = true;
BlackHoleMovementComp->bShouldBounce = true;
InitialLifeSpan = 6.f;
}
// Called when the game starts or when spawned
void ABlackHoleSkill::BeginPlay()
{
Super::BeginPlay();
UE_LOG(LogTemp, Warning, TEXT("BEGINPLAY() CALLED"));
//FBoxSphereBounds BlackHoleBounds = BlackHoleEventHorizon->GetStaticMesh()->GetBounds();
FBoxSphereBounds BlackHoleBounds = BlackHoleEventHorizon->Bounds;
UE_LOG(LogTemp, Warning, TEXT("Black Hole game radius = %f"), BlackHoleBounds.SphereRadius);
float ScaleRatio = BlackHoleBounds.SphereRadius / CalculateSchwarzschildRadius();
UE_LOG(LogTemp, Warning, TEXT("ScaleRatio = %f"), ScaleRatio);
FVector BoundingBoxSize;
ULevel* CurrentLevel = GetLevel();
if (CurrentLevel)
{
FBox BoundingBox = ALevelBounds::CalculateLevelBounds(CurrentLevel);
if (BoundingBox.IsValid)
{
BoundingBoxSize = BoundingBox.GetSize();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("BoundingBox isn't valid."));
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("CurrentLevel is null."));
}
float Radius = CalculateGravitationalinfluenceRadius();
float ScaledGravitationalInfluenceRadius = 0.1 * Radius * (BoundingBoxSize.X / Radius);
//float ScaledGravitationalInfluenceRadius = CalculateGravitationalinfluenceRadius() * ScaleRatio;
BlackHoleGravitationalInfluence->SetSphereRadius(ScaledGravitationalInfluenceRadius);
UE_LOG(LogTemp, Warning, TEXT("ScaledGravitationalInfluenceRadius = %f"), ScaledGravitationalInfluenceRadius);
DrawDebugSphere(
GetWorld(),
GetActorLocation(),
ScaledGravitationalInfluenceRadius,
//2000,
50,
FColor::Red,
false,
180,
0,
5.f
);
/*
float Radius = -1.f;
ULevel* CurrentLevel = GetLevel();
if(CurrentLevel)
{
ALevelBounds* LevelBounds = CurrentLevel->LevelBoundsActor.Get();
if(LevelBounds)
{
UBoxComponent* BoundingBox = LevelBounds->BoxComponent;
if(BoundingBox)
{
Radius = BoundingBox->Bounds.SphereRadius;
}
else
{
UE_LOG(LogTemp, Warning, TEXT("BoundingBox is null."));
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("LevelBounds is null."));
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("CurrentLevel is null."));
}
*/
UE_LOG(LogTemp, Warning, TEXT("Map name = %s"), *(GetWorld()->GetName()));
UE_LOG(LogTemp, Warning, TEXT("Map width = %f"), BoundingBoxSize.X);
UE_LOG(LogTemp, Warning, TEXT("Map length = %f"), BoundingBoxSize.Y);
UE_LOG(LogTemp, Warning, TEXT("Map depth = %f"), BoundingBoxSize.Z);
}
float ABlackHoleSkill::CalculateSchwarzschildRadius()
{
UE_LOG(LogTemp, Warning, TEXT("GRAVITATIONAL_CONST = %s"), *FString::Printf(TEXT("%f"), GRAVITATIONAL_CONST));
UE_LOG(LogTemp, Warning, TEXT("BlackHoleMassScale = %f"), BlackHoleMassScale);
UE_LOG(LogTemp, Warning, TEXT("SUN_MASS = %f"), SUN_MASS);
UE_LOG(LogTemp, Warning, TEXT("SPEED_OF_LIGHT = %f"), FMath::Pow(SPEED_OF_LIGHT, 2));
UE_LOG(LogTemp, Warning, TEXT("SchwarzschildRadius = %f"), 100 * ((2 * GRAVITATIONAL_CONST * (BlackHoleMassScale * SUN_MASS)
) / FMath::Pow(SPEED_OF_LIGHT, 2)));
return 100 * ((2 * GRAVITATIONAL_CONST * (BlackHoleMassScale * SUN_MASS)
) / FMath::Pow(SPEED_OF_LIGHT, 2));
}
float ABlackHoleSkill::CalculateStellarMeanDeviation()
{
if (BlackHoleClusterMinVelocity <= 0.f)
{
BlackHoleClusterMinVelocity = .01f;
}
TArray<float> BlackHoleClusterVelocityArr;
float StellarVelocitySum = 0.f;
for (int Index = 0; Index < BlackHoleClusterCount; Index++)
{
float StellarVelocity = FMath::FRandRange(BlackHoleClusterMinVelocity,
BlackHoleClusterMaxVelocity
);
BlackHoleClusterVelocityArr.Add(StellarVelocity);
StellarVelocitySum += StellarVelocity;
}
float StellarMeanVelocity = StellarVelocitySum / BlackHoleClusterCount;
float DistancefromMeanSum = 0.f;
for (float StellarVelocity : BlackHoleClusterVelocityArr)
{
float DistanceFromMean = UKismetMathLibrary::Abs(StellarMeanVelocity - StellarVelocity);
DistancefromMeanSum += DistanceFromMean;
}
return DistancefromMeanSum / BlackHoleClusterCount;
}
float ABlackHoleSkill::CalculateGravitationalinfluenceRadius()
{
UE_LOG(LogTemp, Warning, TEXT("GravitationalInfluenceRadius = %f"), 100 * (GRAVITATIONAL_CONST * (BlackHoleMassScale * SUN_MASS)
) / CalculateStellarMeanDeviation());
return 100 * (GRAVITATIONAL_CONST * (BlackHoleMassScale * SUN_MASS)
) / CalculateStellarMeanDeviation();
}
void ABlackHoleSkill::MoveinDirection(FVector Direction)
{
BlackHoleMovementComp->Velocity = Direction * BlackHoleMovementComp->InitialSpeed;
}
void ABlackHoleSkill::PostInitializeComponents()
{
Super::PostInitializeComponents();
UE_LOG(LogTemp, Warning, TEXT("POSTINITIALIZECOMPONENTS() CALLED"));
FBodyInstance* BlackHoleBodyInstance = BlackHoleEventHorizon->GetBodyInstance();
if (BlackHoleBodyInstance)
{
BlackHoleBodyInstance->SetMassOverride(SUN_MASS, true);
BlackHoleBodyInstance->SetMassScale(BlackHoleMassScale);
}
}
// Called every frame
void ABlackHoleSkill::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
And the Character who summons it:
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "FPSCharacter.h"
#include "FPSProjectile.h"
#include "Animation/AnimInstance.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Kismet/GameplayStatics.h"
#include "BlackHoleSkill.h"
AFPSCharacter::AFPSCharacter()
{
// Create a CameraComponent
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
CameraComponent->SetupAttachment(GetCapsuleComponent());
CameraComponent->SetRelativeLocation(FVector(0, 0, BaseEyeHeight)); // Position the camera
CameraComponent->bUsePawnControlRotation = true;
// Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
Mesh1PComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh"));
Mesh1PComponent->SetupAttachment(CameraComponent);
Mesh1PComponent->CastShadow = false;
Mesh1PComponent->SetRelativeRotation(FRotator(2.0f, -15.0f, 5.0f));
Mesh1PComponent->SetRelativeLocation(FVector(0, 0, -160.0f));
// Create a gun mesh component
GunMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FP_Gun"));
GunMeshComponent->CastShadow = false;
GunMeshComponent->SetupAttachment(Mesh1PComponent, "GripPoint");
}
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
// set up gameplay key bindings
check(PlayerInputComponent);
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCharacter::Fire);
PlayerInputComponent->BindAction("BlackHole", IE_Pressed, this, &AFPSCharacter::SummonBlackHole);
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
}
void AFPSCharacter::Fire()
{
// try and fire a projectile
if (ProjectileClass)
{
FVector MuzzleLocation = GunMeshComponent->GetSocketLocation("Muzzle");
FRotator MuzzleRotation = GunMeshComponent->GetSocketRotation("Muzzle");
//Set Spawn Collision Handling Override
FActorSpawnParameters ActorSpawnParams;
ActorSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding;
// spawn the projectile at the muzzle
GetWorld()->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, ActorSpawnParams);
}
// try and play the sound if specified
if (FireSound)
{
UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
}
// try and play a firing animation if specified
if (FireAnimation)
{
// Get the animation object for the arms mesh
UAnimInstance* AnimInstance = Mesh1PComponent->GetAnimInstance();
if (AnimInstance)
{
AnimInstance->PlaySlotAnimationAsDynamicMontage(FireAnimation, "Arms", 0.0f);
}
}
}
void AFPSCharacter::SummonBlackHole()
{
if(BlackHoleSkillClass)
{
FVector MuzzleLocation = GunMeshComponent->GetSocketLocation("Muzzle");
FRotator MuzzleRotation = GunMeshComponent->GetSocketRotation("Muzzle");
FActorSpawnParameters ActorSpawnParameters;
//ActorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding;
ActorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
//GetWorld()->SpawnActor<ABlackHoleSkill>(BlackHoleSkillClass, GetActorLocation(), GetActorRotation(), ActorSpawnParameters);
ABlackHoleSkill* BlackHoleThrown = GetWorld()->SpawnActor<ABlackHoleSkill>(BlackHoleSkillClass, MuzzleLocation, MuzzleRotation, ActorSpawnParameters);
BlackHoleThrown->MoveinDirection(MuzzleRotation.Vector());
}
}
void AFPSCharacter::MoveForward(float Value)
{
if (Value != 0.0f)
{
// add movement in that direction
AddMovementInput(GetActorForwardVector(), Value);
}
}
void AFPSCharacter::MoveRight(float Value)
{
if (Value != 0.0f)
{
// add movement in that direction
AddMovementInput(GetActorRightVector(), Value);
}
}
Any clues?
Thanks