void FAnimNode_WheelHandler::Initialize(const FAnimationInitializeContext& Context) { // TODO: only check vehicle anim instance // UVehicleAnimInstance AWheeledVehicle * Vehicle = Cast<AWheeledVehicle> ((CastChecked<USkeletalMeshComponent> (Context.AnimInstance->GetOuter()))->GetOwner()); ; // we only support vehicle for this class if(Vehicle != nullptr) { VehicleSimComponent = Vehicle->GetVehicleMovementComponent(); int32 NumOfwheels = VehicleSimComponent->WheelSetups.Num(); if(NumOfwheels > 0) { WheelSimulators.Empty(NumOfwheels); WheelSimulators.AddZeroed(NumOfwheels); // now add wheel data for(int32 WheelIndex = 0; WheelIndex<WheelSimulators.Num(); ++WheelIndex) { FWheelSimulator & WheelSim = WheelSimulators[WheelIndex]; const FWheelSetup& WheelSetup = VehicleSimComponent->WheelSetups[WheelIndex]; // set data WheelSim.WheelIndex = WheelIndex; WheelSim.BoneReference.BoneName = WheelSetup.BoneName; WheelSim.LocOffset = FVector::ZeroVector; WheelSim.RotOffset = FRotator::ZeroRotator; } } } FAnimNode_SkeletalControlBase::Initialize(Context); }
void UVehiclePathFollowingComponent::SetMoveSegment(int32 SegmentStartIndex) { UPathFollowingComponent::SetMoveSegment(SegmentStartIndex); AWheeledVehicle* Owner = Cast<AWheeledVehicle>(MovementComp->GetOwner()); if (Owner) { InitialDistanceToDestination = (Owner->GetActorLocation() - GetCurrentTargetLocation()).Size(); } }
void ANetworkController::ReceivedRemoveAllVehicles() { for (TActorIterator<AWheeledVehicle> ObjIt(GetWorld()); ObjIt; ++ObjIt) { AWheeledVehicle* Vehicle = *ObjIt; Vehicle->Destroy(); } for (TActorIterator<AMockingVehicle> ObjIt(GetWorld()); ObjIt; ++ObjIt) { AMockingVehicle* Vehicle = *ObjIt; Vehicle->Destroy(); } for (TActorIterator<AActor> ObjIt(GetWorld(), AArrow); ObjIt; ++ObjIt) { (*ObjIt)->Destroy(); } }
void UVehiclePathFollowingComponent::FollowPathSegment(float DeltaTime) { if (MovementComp) { UWheeledVehicleMovementComponent* VehicleMoveComp = Cast<UWheeledVehicleMovementComponent>(MovementComp); AWheeledVehicle* Owner = Cast<AWheeledVehicle>(VehicleMoveComp->GetOwner()); if (Owner && VehicleMoveComp) { if(DesiredVehicleSpeedInKMH == 0.0f) VehicleMoveComp->SetHandbrakeInput(true); else VehicleMoveComp->SetHandbrakeInput(false); FVector VehicleLocation = Owner->GetActorLocation(); FVector Destination = GetCurrentTargetLocation(); FVector DirectionToDestination = Destination - VehicleLocation; //Vector pointing to current destination (not necessarily the final destination) //____STEERING____ float DesiredSteering = 0.f; float DeltaYaw = (DirectionToDestination.ToOrientationRotator() - Owner->GetActorForwardVector().ToOrientationRotator()).Yaw; bool DestinationToRight = DeltaYaw >= 0; if (DeltaYaw > 180.f || DeltaYaw < -180.f) { DestinationToRight = !DestinationToRight; if (DestinationToRight && DeltaYaw >= -360.f + MaxSteeringAngle) { DesiredSteering = 1.f; } else if (!DestinationToRight && DeltaYaw <= 360.f - MaxSteeringAngle) { DesiredSteering = -1.f; } else if(DestinationToRight) { DesiredSteering = FMath::GetMappedRangeValueClamped(FVector2D(-360.f, -360.f + MaxSteeringAngle), FVector2D(0, 1.0f), DeltaYaw); } else { DesiredSteering = FMath::GetMappedRangeValueClamped(FVector2D(360.f - MaxSteeringAngle, 360.f), FVector2D(-1.f, 0.f), DeltaYaw); } } else { if (DestinationToRight && DeltaYaw >= MaxSteeringAngle) { DesiredSteering = 1.f; } else if (!DestinationToRight && DeltaYaw <= -MaxSteeringAngle) { DesiredSteering = -1.f; } else DesiredSteering = FMath::GetMappedRangeValueClamped(FVector2D(-MaxSteeringAngle, MaxSteeringAngle), FVector2D(-1.f, 1.f), DeltaYaw); } CurrentSteering = DesiredSteering; VehicleMoveComp->SetSteeringInput(CurrentSteering); //____END STEERING____ //____THROTTLE____ float CurrentSpeedInKMH = VehicleMoveComp->GetForwardSpeed() * 0.036f; //Convert to KM/H //TODO: Allow speed to be 0, but never 0 if DesiredSpeed is > 0 float EstiamtedDesiredSpeed = DesiredVehicleSpeedInKMH - (FMath::Abs(CurrentSteering) * DesiredVehicleSpeedInKMH * 0.8); CurrentThrottle += UPIDController::NextValue(VelocityController, EstiamtedDesiredSpeed - CurrentSpeedInKMH, DeltaTime); CurrentThrottle = FMath::Clamp(CurrentThrottle, 0.f, 1.f); VehicleMoveComp->SetThrottleInput(CurrentThrottle); //____END THROTTLE____ //Direction the wheel is facing DesiredMoveDirection = Owner->GetActorForwardVector().ToOrientationRotator().Add(0.f, FMath::GetMappedRangeValueClamped(FVector2D(-1.f, 1.f), FVector2D(-90.f, 90.f), CurrentSteering), 0.f).Vector(); ABikeV3Pawn* BikePawn = Cast<ABikeV3Pawn>(Owner); if(BikePawn) BikePawn->CurrentHandlingInput = CurrentSteering; #ifdef NDEBUG float DistanceToDestination = DirectionToDestination.Size(); DrawDebugPoint(GetWorld(), Destination, 50.0f, FColor::Blue); DrawDebugLine(GetWorld(), VehicleLocation, VehicleLocation + DirectionToDestination, FColor::Yellow); if (GEngine) { GEngine->AddOnScreenDebugMessage(0, 1.0f, FColor::Cyan, FString::Printf(TEXT("Throttle %0.3f Steering: %0.3f"), CurrentThrottle, CurrentSteering)); GEngine->AddOnScreenDebugMessage(1, 1.0f, FColor::Cyan, FString::Printf(TEXT("Distance to destination: %0.2f"), DistanceToDestination)); GEngine->AddOnScreenDebugMessage(2, 1.0f, FColor::Cyan, FString::Printf(TEXT("Current Speed in KM/H: %0.2f"), CurrentSpeedInKMH)); GEngine->AddOnScreenDebugMessage(3, 1.0f, FColor::Cyan, FString::Printf(TEXT("DeltaYaw %0.3f"), DeltaYaw)); } #endif } } }
void UVehiclePathFollowingComponent::FollowPathSegment(float DeltaTime) { if (MovementComp) { UWheeledVehicleMovementComponent* VehicleMoveComp = Cast<UWheeledVehicleMovementComponent>(MovementComp); AWheeledVehicle* Owner = Cast<AWheeledVehicle>(VehicleMoveComp->GetOwner()); if (Owner && VehicleMoveComp) { FVector VehicleLocation = Owner->GetActorLocation(); FVector Destination = GetCurrentTargetLocation(); FVector DirectionToDestion = Destination - VehicleLocation; float DistanceToDestination = DirectionToDestion.Size(); FRotator RotatorToDestination = FRotationMatrix::MakeFromX(DirectionToDestion.GetSafeNormal2D()).Rotator(); float DeltaYaw = (RotatorToDestination - Owner->GetActorRotation()).Yaw; bool DestinationInFront = DeltaYaw - 70.0f <= EPSILON && DeltaYaw + 70.0f >= EPSILON; float DesiredSteering = FMath::GetMappedRangeValueClamped(FVector2D(-180.0f, 180.0f), FVector2D(-1.0f, 1.0f), DeltaYaw); if (!DestinationInFront && DistanceToDestination < 1e3) // reverse DesiredSteering = -DesiredSteering; VehicleMoveComp->SetHandbrakeInput(false); // The DesiredSteering includes the sensed steering already CurrentSteering += UPIDController::NextValue(HeadingController, DesiredSteering - CurrentSteering, DeltaTime); VehicleMoveComp->SetSteeringInput(CurrentSteering); float PercentDistanceLeft = DistanceToDestination / InitialDistanceToDestination; float DesiredThrottle = 0.0f; // #TODO Turn hardcoded values into variables if (DestinationInFront) DesiredThrottle = FMath::Clamp(PercentDistanceLeft, 0.35f, 0.8f); else DesiredThrottle = -0.5f; // default throttle when going in reverse /* #TODO Fix Math: Allow user to specify a maximum vehicle speed that the PID controller should approach. */ CurrentThrottle += UPIDController::NextValue(VelocityController, DesiredThrottle - CurrentThrottle, DeltaTime); VehicleMoveComp->SetThrottleInput(CurrentThrottle); #ifdef NDEBUG DrawDebugPoint(GetWorld(), Destination, 50.0f, FColor::Blue); DrawDebugLine(GetWorld(), VehicleLocation, VehicleLocation + DirectionToDestion, FColor::Yellow); if (GEngine) { GEngine->AddOnScreenDebugMessage(0, 1.0f, FColor::Cyan, FString::Printf(TEXT("Throttle %0.3f Steering: %0.3f"), CurrentThrottle, CurrentSteering)); GEngine->AddOnScreenDebugMessage(1, 1.0f, FColor::Cyan, FString::Printf(TEXT("Distance to destination: %0.2f"), DistanceToDestination)); } #endif } } }
static float GetForwardSpeed(const AWheeledVehicle &Vehicle) { const auto *MovementComponent = Vehicle.GetVehicleMovementComponent(); check(nullptr != MovementComponent); return MovementComponent->GetForwardSpeed(); }