Download

Issue with a Third Person Shooter and line tracing

Hello everyone,

I have my projectile working as described in this tutorial (https://www.youtube.com/watch?v=FwVYXlsTPD4 roughly 7 mins in is the blueprint, my code is written in c++ based on this), but ran into a issue with my game being in third person only. When my player is too close to a wall (or low cover) on his right hand side, the line trace from the camera to the center of the crosshair hits somewhat behind my player or off to his side and the projectile shoots backwards or to the side depending on the location of the hit. Since it has a “hit” it still uses this direction and thus shoots in an unwanted location, sometimes even hitting himself.

Is there a way to know that the hit location is behind the gun/player and not the actual intended location? I was thinking of using vector math but I am not too strong in that subject and it has been a while since I’ve used it. Can’t figure this one out. Someone have any suggestions on how to know if the line trace hit was behind the player?

While this is a really old page that references Unrealscript, this page is incredibly useful for learning some advanced vector maths, how to use them not just a theoretical explanation: https://wiki.beyondunreal.com/Legacy…s_ViewRotation

I’m not sure if I am using it right. I followed the link and used the sample formula they show on the wiki.

Original:
actor A, B;
vector aFacing,aToB;
// What direction is A facing in?
aFacing=Normal(Vector(A.Rotation));
// Get the vector from A to B aToB=B.Location-A.Location;
orientation = aFacing dot aToB;
// > 0.0 B is in front of A
// = 0.0 B is exactly to the right/left of A
// < 0.0 B is behind A

My code:
// A = StartingLocation, B = Hit.ImpactPoint

FVector AFacing = StartingLocation.Rotation().Vector().GetSafeNormal();
FVector AToB = Hit.ImpactPoint - StartingLocation;

// > 0.0 b is in front of A, = 0.0 b is exactly left or right of A, < 0.0 is behind of A
float Orientation = FVector::DotProduct(AFacing, AToB);
UE_LOG(LogTemp, Warning, TEXT(“Orientation is: %f”), Orientation);

if (Orientation > 0.0f)
{
StartingRotation = UKismetMathLibrary::FindLookAtRotation(StartingLocation, TraceEnd);
}

I also tried doing the second formula:

Original:
orientation = vector(B.Controller.GetViewRotation()) dot Normal(A.Location - B.Location);
// > 0.0 A points forwards in relation to B (up to 90° apart) // = 0.0 A is perpendicular to B (exactly 90° between A and B) // < 0.0 A points backwards in relation to B (more than 90° apart)

My code:
float Orientation = FVector::DotProduct(StartingLocation.Rotation().Vector(), (Hit.ImpactPoint - StartingLocation).GetSafeNormal());

I ended up figuring it out thanks to that link and insight from Tom Looman. I needed to use the rotation from the camera not the muzzlesocket of the weapon:

//EyeRotation is my camera’s rotation, Hit is the output from LineTraceBySingleChannel, StartingLocation is the location of the weapon’s muzzlesocket

float Orientation = FVector::DotProduct(EyeRotation.Vector(), (Hit.ImpactPoint - StartingLocation).GetSafeNormal());

UE_LOG(LogTemp, Warning, TEXT(“Orientation is: %f”), Orientation);

if (Orientation > 0.0f)

{
StartingRotation = UKismetMathLibrary::FindLookAtRotation(StartingLocation, TraceEnd);
}

//else leave StartingRotation to be set as FRotator StartingRotation = MyOwner->GetController()->GetControlRotation();