Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*by Vila Carlos for Vite23 Project*/
- #include "VRacer.h"
- #include "DetailLayoutBuilder.h"
- #include "VectorTypes.h"
- #include "GameFramework/Actor.h"
- #include "Components/BillboardComponent.h"
- #include "Particles/ParticleSystemComponent.h"
- #include "Math/UnrealMathUtility.h"
- #include "Physics/ImmediatePhysics/ImmediatePhysicsShared/ImmediatePhysicsCore.h"
- // Sets default values
- AVRacer::AVRacer()
- {
- // 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;
- SphereCollision = CreateDefaultSubobject<USphereComponent>("SphereCollision");
- SetRootComponent(SphereCollision);
- CamRotator = CreateDefaultSubobject<UBillboardComponent>("CamRotator");
- CamRotator->SetupAttachment(RootComponent);
- SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
- SpringArm->SetupAttachment(CamRotator);
- Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
- Camera->SetupAttachment(SpringArm);
- ShipMesh = CreateDefaultSubobject<UStaticMeshComponent>("ShipMesh");
- ShipMesh->SetupAttachment(RootComponent);
- BackCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("BackCamera"));
- BackCamera->SetupAttachment(ShipMesh);
- AirbrakeRight = CreateDefaultSubobject<UBillboardComponent>("AirbrakeRight");
- AirbrakeRight->SetupAttachment(ShipMesh);
- RightAirbrakeMesh = CreateDefaultSubobject<UStaticMeshComponent>("RightAirbrakeMesh");
- RightAirbrakeMesh->SetupAttachment(AirbrakeRight);
- AirbrakeLeft = CreateDefaultSubobject<UBillboardComponent>("AirbrakeLeft");
- AirbrakeLeft->SetupAttachment(ShipMesh);
- LeftAirbrakeMesh = CreateDefaultSubobject<UStaticMeshComponent>("LeftAirbrakeMesh");
- LeftAirbrakeMesh->SetupAttachment(AirbrakeLeft);
- PointLight = CreateDefaultSubobject<UPointLightComponent>("PointLightComponent");
- PointLight->SetupAttachment(ShipMesh);
- ParticleEffects = CreateDefaultSubobject<UBillboardComponent>("ParticleEffects");
- ParticleEffects->SetupAttachment(ShipMesh);
- AirflowLeft = CreateDefaultSubobject<UParticleSystemComponent>("AirflowLeft");
- AirflowLeft->SetupAttachment(ParticleEffects);
- AirflowRight = CreateDefaultSubobject<UParticleSystemComponent>("AirflowRight");
- AirflowRight->SetupAttachment(ParticleEffects);
- ExhaustRight = CreateDefaultSubobject<UParticleSystemComponent>("ExhaustRight");
- ExhaustRight->SetupAttachment(ParticleEffects);
- ExhaustLeft = CreateDefaultSubobject<UParticleSystemComponent>("ExhaustLeft");
- ExhaustLeft->SetupAttachment(ParticleEffects);
- SphereCollision->SetSimulatePhysics(true);
- SphereCollision->SetNotifyRigidBodyCollision(true);
- SphereCollision->BodyInstance.SetCollisionProfileName("BlockAllDynamic");
- SphereCollision->OnComponentHit.AddDynamic(this, &AVRacer::OnHit);
- }
- void AVRacer::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
- {
- if (Hit.PhysMaterial.Get() != nullptr )
- {
- if (Hit.PhysMaterial.Get()->GetFName().ToString() == "WallCollision")//WallCollisionMaterial
- {
- const FVector Force = GetVelocity()* (FMath::Max(WallDeceleration, 0)*-1);
- SphereCollision->AddForce(Force, NAME_None, true);
- }
- }
- }
- // Called when the game starts or when spawned
- void AVRacer::BeginPlay()
- {
- Super::BeginPlay();
- }
- void AVRacer::LookBack(float value)
- {
- if (value > 0.5f)
- {
- BackCamera->SetActive(true,false);
- Camera->SetActive(false,false);
- } else
- {
- BackCamera->SetActive(false,false);
- Camera->SetActive(true,false);
- }
- }
- void AVRacer::InputActionTurbo()
- {
- if (IsLocallyControlled())
- {
- if (HasAuthority())//Should Do Event to run on Server
- {
- if (bIgnition && bTurboAvailable)
- {
- //run timeline
- Turbo();
- }
- }
- }
- }
- bool AVRacer::LineTraceSingleForObjects(const FVector Start, const FVector End, FHitResult& OutHit) const
- {
- FCollisionQueryParams Params;
- Params.AddIgnoredActor(this);
- Params.bReturnPhysicalMaterial = true;
- FCollisionObjectQueryParams ObjectParams;
- ObjectParams.AddObjectTypesToQuery(ECC_WorldStatic);
- ObjectParams.AddObjectTypesToQuery(ECC_WorldDynamic);
- bool const bHit = GetWorld()->LineTraceSingleByObjectType(OutHit, Start, End, ObjectParams, Params);
- return bHit;
- }
- bool AVRacer::LineTraceSingleForObjectsStatic(const FVector Start, const FVector End, FHitResult& OutHit) const
- {
- FCollisionQueryParams Params;
- Params.AddIgnoredActor(this);
- Params.bReturnPhysicalMaterial = true;
- FCollisionObjectQueryParams ObjectParams;
- ObjectParams.AddObjectTypesToQuery(ECC_WorldStatic);
- bool const bHit = GetWorld()->LineTraceSingleByObjectType(OutHit, Start, End, ObjectParams, Params);
- return bHit;
- }
- void AVRacer::ShipControls(float DeltaTime, float Steering, float Thrust, float LeftAirbrake, float RightAirbrake, float Pitch)
- {
- SteeringValue = FMath::FInterpTo(SteeringValue, Steering, DeltaTime, SteeringInterpSpeed);
- ThrustValue = FMath::FInterpTo(ThrustValue, Thrust, DeltaTime, ThrustInterpSpeed);
- LeftAirbrakeValue = FMath::FInterpTo(LeftAirbrakeValue, LeftAirbrake, DeltaTime, AirbrakeInterpSpeed);
- RightAirbrakeValue = FMath::FInterpTo(RightAirbrakeValue, RightAirbrake, DeltaTime, AirbrakeInterpSpeed);
- PitchValue = FMath::FInterpTo(PitchValue, Pitch, DeltaTime, PitchInterpSpeed);
- }
- // Called every frame
- void AVRacer::Tick(float DeltaTime)
- {
- Super::Tick(DeltaTime);
- if (IsLocallyControlled() && bIgnition) {
- ShipControls(DeltaTime, GetInputAxisValue("Steering"), GetInputAxisValue("Thrust"), GetInputAxisValue("LeftAirbrake"),
- GetInputAxisValue("RightAirbrake"), GetInputAxisValue("Pitch") );
- }
- /*Vehicle Physics*/
- //Get Linear & Angular Velocity
- const FTransform T = SphereCollision->GetComponentToWorld();
- RelativeLinearVelocity = T.InverseTransformVectorNoScale(SphereCollision->GetComponentVelocity());
- RelativeAngularVelocity = T.InverseTransformVectorNoScale(SphereCollision->GetPhysicsAngularVelocityInRadians());
- SpeedRatio = RelativeLinearVelocity.X / (TopSpeed * 0.036);
- // LevitationTrace
- FVector InverseTransformDir = GetActorTransform().InverseTransformVectorNoScale(GetActorLocation());
- double PitchAngleRad = (DOUBLE_PI / 180.0) * PitchValue * PitchAngle;
- FVector EndDir = FVector(InverseTransformDir.X + LevitationHeight * PitchAngleRad,
- InverseTransformDir.Y,
- InverseTransformDir.Z - (bMagneticSurface ? LevitationHeight * 2 : LevitationHeight));
- FVector End = GetActorTransform().InverseTransformVectorNoScale(EndDir);
- FHitResult OutHit;
- LineTraceSingleForObjectsStatic(GetActorLocation(), End, OutHit);
- LevitationFactor = 1.0 - OutHit.Time;
- if (OutHit.PhysMaterial.Get() != nullptr) {
- const FString HitPhysMaterialName = OutHit.PhysMaterial.Get()->GetFName().ToString();
- bMagneticSurface = HitPhysMaterialName == "MagneticSurface";
- bLevitationTraceObstructed = bMagneticSurface || HitPhysMaterialName == "LevitationSurface";
- } else {
- bLevitationTraceObstructed = false;
- bMagneticSurface = false;
- }
- //Align Traces
- TArray<FVector> AlignTraceDirectionsFromCenter; //= {FVector(0,0,-1), FVector(), FVector(),FVector()};
- AlignTraceDirectionsFromCenter.Add(FVector(0,0,-1));
- AlignTraceDirectionsFromCenter.Add(FVector(0,1,0));
- AlignTraceDirectionsFromCenter.Add(FVector(0,-1,0));
- AlignTraceDirectionsFromCenter.Add(FVector(1,0,0));
- AlignTraceDirectionsFromCenter.Add(FVector(-1,0,0));
- AlignTraceDirectionsFromCenter.Add(FVector(0,0,1));
- int32 NumTraceDirections = AlignTraceDirectionsFromCenter.Num();
- FTransform ActorTransform = GetActorTransform();
- FVector ActorLocation = GetActorLocation();
- for (int32 i = 0; i < NumTraceDirections; i++)
- {
- FVector AlignTraceDir = AlignTraceDirectionsFromCenter[i].GetSafeNormal(0.0001);
- FVector LineTraceEnd = ActorTransform.TransformVectorNoScale(ActorTransform.InverseTransformVectorNoScale(ActorLocation) + AlignTraceDir * (bMagneticSurface ? LevitationHeight * 2 : LevitationHeight));
- FHitResult Out;
- if (LineTraceSingleForObjects(ActorLocation, LineTraceEnd, Out))
- {
- UPhysicalMaterial* PhysMaterial = Out.PhysMaterial.Get();
- if (PhysMaterial)
- {
- FName MaterialName = PhysMaterial->GetFName();
- if (MaterialName == FName("LevitationSurface") || MaterialName == FName("MagneticSurface"))
- {
- bAlignTraceObstructed = true;
- FloorSurfaceNormal = Out.Normal;
- break;
- }
- }
- }
- }
- //Set Levitation Force
- if (bLevitationTraceObstructed)
- {
- double LevForce;
- if (bMagneticSurface)
- {
- LevForce = (LevitationFactor*2.0 -1.0)*(LevitationForce*1.0);//-1.0
- UE_LOG(LogTemp, Warning, TEXT("bMagneticSurface True "));
- } else
- {
- LevForce = pow(LevitationFactor,2.0)*LevitationForce;
- }
- } else
- {
- RelativeLevitationForce = FVector::ZeroVector;
- }
- //Set Sideways Stabilization Force
- RelativeSidewaysStabilizationForce = FVector(0, RelativeLinearVelocity.Y*-1*SidewaysStability,0 );
- //Set Thrust Force
- double GetReverseTrust;
- ThrustValue > 0.0 ? GetReverseTrust = ThrustForce*ThrustValue : GetReverseTrust = ReverseThrustForce*ThrustValue;
- double MThrust = 1 - SpeedRatio * SpeedRatio;
- double LevitationMultiplier = bLevitationTraceObstructed ? 1 - FMath::Clamp(AirThrustReduction, 0.0, 1.0) : 1.0;
- RelativeThrustForce = FVector(GetReverseTrust * MThrust * LevitationMultiplier, 0, 0);
- RelativeBoostForce = FVector(BoostValue * BoostMultiplier + TurboValue * TurboMultiplier, 0, 0);
- double CombinedInputs = RelativeLinearVelocity.X > 0 ? (LeftAirbrakeValue + RightAirbrakeValue) * AirbrakeDeceleration * -1 : 0;
- RelativeBrakeForce = FVector(CombinedInputs, 0, 0);
- double DownforceValue = DownforceMultiplier * FMath::Abs(SpeedRatio) * -1;
- RelativeDownforce = GetActorTransform().InverseTransformVectorNoScale(FVector(0, 0, DownforceValue));
- if (bLevitationTraceObstructed && LeftAirbrakeValue > 0.9 && RightAirbrakeValue > 0.9 && RelativeLinearVelocity.Size() < (EBrakeMaxVelocity * 27.777))
- {
- RelativeEbrakeForce = RelativeLinearVelocity * (FMath::Abs(EBrakeForce) * -1);
- }
- else
- {
- RelativeEbrakeForce = FVector(0, 0, 0);
- }
- // Set Downforce
- float DownforceValue = DownforceMultiplier * FMath::Abs(SpeedRatio) * -1;
- RelativeDownforce = GetActorTransform().InverseTransformVectorNoScale(FVector(0, 0, DownforceValue));
- // Set E Brake Force
- if (bLevitationTraceObstructed && LeftAirbrakeValue > 0.9 && RightAirbrakeValue > 0.9 && RelativeLinearVelocity.Size() < (EBrakeMaxVelocity * 27.777))
- {
- RelativeEbrakeForce = RelativeLinearVelocity * (FMath::Abs(EBrakeForce) * -1);
- }
- else
- {
- RelativeAlignTorque = FVector::ZeroVector;
- }
- // Set Align Torque
- FVector RelativeAlignTorque(0, 0, 0);
- if (bAlignTraceObstructed)
- {
- float Xterm = (FVector::DotProduct(SphereCollision->GetRightVector().GetSafeNormal(0.0001), FloorSurfaceNormal.GetSafeNormal(0.0001)) * -1) * UpdateTorqueAlign();
- float Yterm = UpdateTorqueAlign() * GetPitchAngle();
- RelativeAlignTorque = FVector(Xterm, Yterm, 0);
- }
- // Set Steering Torque
- float AirbrakeSteering = (LeftAirbrakeValue * -1 + RightAirbrakeValue) * AirbrakeSteeringSupport * SpeedRatio;
- RelativeSteeringTorque = FVector(0, 0, SteeringTorque * SteeringValue + AirbrakeSteering);
- // Apply Linear Forces
- FVector Sum = RelativeLevitationForce + RelativeLevitationDampingForce + RelativeSidewaysStabilizationForce
- + RelativeThrustForce + RelativeBoostForce + RelativeBrakeForce + RelativeDownforce + RelativeDragForce + RelativeEbrakeForce;
- if (Sum.SizeSquared() < 100.0f) // Adjust threshold as needed
- {
- Sum = FVector::ZeroVector;
- }
- FVector Force = GetActorTransform().TransformVectorNoScale(Sum);
- SphereCollision->AddForce(Force, NAME_None, true);
- // Apply Angular Forces
- FVector AngularSum = RelativeAlignTorque + RelativeSteeringTorque;
- FVector Torque = GetActorTransform().TransformVectorNoScale(AngularSum);
- SphereCollision->AddTorqueInRadians(Torque, NAME_None, true);
- // Set Gravity
- SphereCollision->SetEnableGravity(!bMagneticSurface);
- }
- double AVRacer::GetPitchAngle() const
- {
- const FVector VectorToRotate = SphereCollision->GetComponentTransform().InverseTransformVectorNoScale(SphereCollision->GetForwardVector());//SceneComp->GetComponentToWorld().TransformVectorNoScale(SceneComp->GetForwardVector());
- FVector Dir = FRotator(PitchValue*PitchAngle,0,0).RotateVector(VectorToRotate);
- FVector Member1 = SphereCollision->GetComponentTransform().TransformVectorNoScale(Dir);
- return FVector::DotProduct( Member1.GetSafeNormal(0.0001), FloorSurfaceNormal.GetSafeNormal(0.0001));
- }
- double AVRacer::UpdateTorqueAlign() const
- {
- return bMagneticSurface ? UseFixedAlignTorque()*600 : UseFixedAlignTorque()*300;
- }
- double AVRacer::UseFixedAlignTorque() const
- {
- return PitchValue !=0.0f ? 0.5f : FMath::Max(LevitationFactor,0.2);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement