void ABaseCharacter::OnFire() { if (ProjectileClass != NULL) { //Gets the direction that the camera is looking FVector cameraLoc; FRotator cameraRot; GetActorEyesViewPoint(cameraLoc, cameraRot); FVector const muzzleLocation = cameraLoc + FTransform(cameraRot).TransformVector(MuzzleOffset); FRotator muzzleRotation = cameraRot; //Skew the aim point upward muzzleRotation.Pitch += 10.0f; UWorld* const world = GetWorld(); if (world) { FActorSpawnParameters spawnParameters; spawnParameters.Owner = this; spawnParameters.Instigator = Instigator; //Spawns the projectile ABaseProjectile* const projectile = world->SpawnActor<ABaseProjectile>(ProjectileClass, muzzleLocation, muzzleRotation, spawnParameters); if (projectile) { //Gets launch direction FVector const launchDir = muzzleRotation.Vector(); projectile->InitVelocity(launchDir); } } } }
AFPSGCharacter::AFPSGCharacter() : Super() { bReplicates = true; // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; GetCapsuleComponent()->bGenerateOverlapEvents = true; //Initialize the first person camera component firstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FPSGFirstPersonCamera")); firstPersonCameraComponent->AttachParent = GetCapsuleComponent(); FVector characterViewLocation; FRotator characterViewRotation; GetActorEyesViewPoint(characterViewLocation, characterViewRotation); //Position the camera and use the view rotation of the pawn that we get from input firstPersonCameraComponent->RelativeLocation = characterViewLocation; firstPersonCameraComponent->RelativeRotation = characterViewRotation; firstPersonCameraComponent->bUsePawnControlRotation = true; //Initialize the first person mesh component firstPersonMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FPSGFirstPersonMesh")); firstPersonMesh->SetOnlyOwnerSee(true); firstPersonMesh->AttachParent = firstPersonCameraComponent; firstPersonMesh->bCastDynamicShadow = false; firstPersonMesh->CastShadow = false; //The regular body mesh should not be visible to the player GetMesh()->SetOwnerNoSee(true); movementDirection = EMoveDirection::NONE; maxHealth = 100.0f; currentHealth = 100.0f; currentWeapon = NULL; isFiring = false; isFalling = false; amountOfGrenades = 0; maxGrenades = 0; deathAnimation = NULL; inventoryWeaponSocket = ""; boneHead = ""; //Reserve memory for at least 10 elements (weapons) weaponInventory.Reserve(10); dieCallback = false; }
bool AController::LineOfSightTo(const AActor* Other, FVector ViewPoint, bool bAlternateChecks) const { if( !Other ) { return false; } if ( ViewPoint.IsZero() ) { FRotator ViewRotation; GetActorEyesViewPoint(ViewPoint, ViewRotation); } static FName NAME_LineOfSight = FName(TEXT("LineOfSight")); FCollisionQueryParams CollisionParms(NAME_LineOfSight, true, Other); CollisionParms.AddIgnoredActor(this->GetPawn()); FVector TargetLocation = Other->GetTargetLocation(Pawn); bool bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, TargetLocation, ECC_Visibility, CollisionParms); if( !bHit ) { return true; } // if other isn't using a cylinder for collision and isn't a Pawn (which already requires an accurate cylinder for AI) // then don't go any further as it likely will not be tracing to the correct location if (!Cast<const APawn>(Other) && Cast<UCapsuleComponent>(Other->GetRootComponent()) == NULL) { return false; } float distSq = (Other->GetActorLocation() - ViewPoint).SizeSquared(); if ( distSq > FARSIGHTTHRESHOLDSQUARED ) { return false; } if ( !Cast<const APawn>(Other) && (distSq > NEARSIGHTTHRESHOLDSQUARED) ) { return false; } float OtherRadius, OtherHeight; Other->GetSimpleCollisionCylinder(OtherRadius, OtherHeight); //try viewpoint to head bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, Other->GetActorLocation() + FVector(0.f,0.f,OtherHeight), ECC_Visibility, CollisionParms); return !bHit; }
void AFPSCharacter::OnFire() { //try and fire a projectile if (ProjectileClass != NULL) { //Get the camera transform FVector CameraLoc; FRotator CameraRot; GetActorEyesViewPoint(CameraLoc, CameraRot); // MuzzleOffset is in camera space, so transform it to world space before offsetting from the camera to find the final muzzle position FVector const MuzzleLocation = CameraLoc + FTransform(CameraRot).TransformVector(MuzzleOffset); FRotator MuzzleRotation = CameraRot; MuzzleRotation.Pitch += 2.0f; //Skew the aim upwards a bit UWorld* const World = GetWorld(); if (World) { FActorSpawnParameters SpawnParams; SpawnParams.Owner = this; SpawnParams.Instigator = Instigator; // spawn the projectile at the muzzle AFPSProjectile* const Projectile = World->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams); if (Projectile) { // find launch direction FVector const LaunchDir = MuzzleRotation.Vector(); Projectile->InitVelocity(LaunchDir); } } } //try and play the firing sound if (ARWeaponSound != NULL) { UGameplayStatics::PlaySoundAtLocation(this, ARWeaponSound, GetActorLocation()); } }
void AController::GetPlayerViewPoint( FVector& out_Location, FRotator& out_Rotation ) const { GetActorEyesViewPoint( out_Location, out_Rotation); }
bool AAIController::LineOfSightTo(const AActor* Other, FVector ViewPoint, bool bAlternateChecks) const { if (Other == nullptr) { return false; } if (ViewPoint.IsZero()) { FRotator ViewRotation; GetActorEyesViewPoint(ViewPoint, ViewRotation); // if we still don't have a view point we simply fail if (ViewPoint.IsZero()) { return false; } } static FName NAME_LineOfSight = FName(TEXT("LineOfSight")); FVector TargetLocation = Other->GetTargetLocation(GetPawn()); FCollisionQueryParams CollisionParams(NAME_LineOfSight, true, this->GetPawn()); CollisionParams.AddIgnoredActor(Other); bool bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, TargetLocation, ECC_Visibility, CollisionParams); if (!bHit) { return true; } // if other isn't using a cylinder for collision and isn't a Pawn (which already requires an accurate cylinder for AI) // then don't go any further as it likely will not be tracing to the correct location const APawn * OtherPawn = Cast<const APawn>(Other); if (!OtherPawn && Cast<UCapsuleComponent>(Other->GetRootComponent()) == NULL) { return false; } const FVector OtherActorLocation = Other->GetActorLocation(); const float DistSq = (OtherActorLocation - ViewPoint).SizeSquared(); if (DistSq > FARSIGHTTHRESHOLDSQUARED) { return false; } if (!OtherPawn && (DistSq > NEARSIGHTTHRESHOLDSQUARED)) { return false; } float OtherRadius, OtherHeight; Other->GetSimpleCollisionCylinder(OtherRadius, OtherHeight); if (!bAlternateChecks || !bLOSflag) { //try viewpoint to head bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, OtherActorLocation + FVector(0.f, 0.f, OtherHeight), ECC_Visibility, CollisionParams); if (!bHit) { return true; } } if (!bSkipExtraLOSChecks && (!bAlternateChecks || bLOSflag)) { // only check sides if width of other is significant compared to distance if (OtherRadius * OtherRadius / (OtherActorLocation - ViewPoint).SizeSquared() < 0.0001f) { return false; } //try checking sides - look at dist to four side points, and cull furthest and closest FVector Points[4]; Points[0] = OtherActorLocation - FVector(OtherRadius, -1 * OtherRadius, 0); Points[1] = OtherActorLocation + FVector(OtherRadius, OtherRadius, 0); Points[2] = OtherActorLocation - FVector(OtherRadius, OtherRadius, 0); Points[3] = OtherActorLocation + FVector(OtherRadius, -1 * OtherRadius, 0); int32 IndexMin = 0; int32 IndexMax = 0; float CurrentMax = (Points[0] - ViewPoint).SizeSquared(); float CurrentMin = CurrentMax; for (int32 PointIndex = 1; PointIndex<4; PointIndex++) { const float NextSize = (Points[PointIndex] - ViewPoint).SizeSquared(); if (NextSize > CurrentMin) { CurrentMin = NextSize; IndexMax = PointIndex; } else if (NextSize < CurrentMax) { CurrentMax = NextSize; IndexMin = PointIndex; } } for (int32 PointIndex = 0; PointIndex<4; PointIndex++) { if ((PointIndex != IndexMin) && (PointIndex != IndexMax)) { bHit = GetWorld()->LineTraceTestByChannel(ViewPoint, Points[PointIndex], ECC_Visibility, CollisionParams); if (!bHit) { return true; } } } } return false; }