Help with function GetPhysicalFireStartLoc

Hello friends.

There is a small bug on my game, I think it’s the most significant bug, and I think it can break the gameplay especially on closed maps.

For the sake of getting a bit more of realism, I decided to make all my game’s guns as projectile guns instead of Instant Hit. Because this way I can set some specific physical properties for the bullets for each weapon (speed, acceleration, damage, and so on).

And added to this, I made a particle effect to simulate the bullets tracing, which made it look very nice.

However, I have a bug, that initially I thought no one would realize it, but now, after too many downloads of my game’s demo (1200 downloads), many players complained about this.

The bug in question is that, whenever the player pawn is** leaning back against the wall **(any static mesh), the projectile is not ejected from the gun, or better, it hits the wall behind him on the height of the player camera, this way:

The function is


simulated function vector GetPhysicalFireStartLoc(optional vector AimDir) from UTWeapon.uc class. 

This is the line of code which controls the projectile fire action:


FireStartLoc = Instigator.GetPawnViewLocation() + (FireDir * FireOffset.X); 

I suspect it has to do with the player camera, because, as I am using **BehindView **camera to make a 3rd person view, and on the moment the player leans his back against the wall, the camera changes it’s point of view, and the fire start location is calculated based on the Pawn View Location.

After digging the code UTWeapon.uc, and a lot of trials and errors, I changed the Fire Start Location to this:


FireStartLoc = Instigator.Location - FireDir*FiredProjectileClass.default.CylinderComponent.Translation.X;

FireStartLoc.Z = FireStartLoc.Z + FMin(Instigator.EyeHeight, Instigator.CylinderComponent.CollisionHeight - FiredProjectileClass.default.CylinderComponent.CollisionHeight - 1.0);

This seemed to solve the problem, now the projectile is fired from the gun, no matter the player position, even if he is leaning against a wall.

However, a side effect now is that, as it does not take into consideration the fireoffset anymore,** I lost accuracy on the aim**, which means the projectile never hits the center of the crosshair. It sometimes hits, especially when the player is far from to the target, but whenever I zoom the aim (right mouse button), or the closest the player moves towards the target, the projectile moves away from the crosshair towards the left direction.

The old calculation ( FireStartLoc = Instigator.GetPawnViewLocation() + (FireDir * FireOffset.X); ) gives perfect accuracy to the aim, as the projectiles hit the exact center of the crosshair, no matter the player position or camera angle (except the bug whenever leaning the back against a wall).

Any help?

Here is the complete function:


simulated function vector GetPhysicalFireStartLoc(optional vector AimDir)
{
local UTPlayerController PC;
local vector FireStartLoc, HitLocation, HitNormal, FireDir, FireEnd, ProjBox;
local Actor HitActor;
local rotator FireRot;
local class<Projectile> FiredProjectileClass;
local int TraceFlags;

if( Instigator != none )
{
PC = UTPlayerController(Instigator.Controller);

FireRot = Instigator.GetViewRotation();
FireDir = vector(FireRot);
FiredProjectileClass = GetProjectileClass();

//1st condition for spawning projectile//
if (PC == none || PC.bCenteredWeaponFire || PC.WeaponHand == HAND_Centered || PC.WeaponHand == HAND_Hidden)
{
FireStartLoc = Instigator.GetPawnViewLocation() + (FireDir * FireOffset.X);
}

//2nd condition for spawning projectiles//
else if (PC.WeaponHand == HAND_Left)
{
FireStartLoc = Instigator.GetPawnViewLocation() + ((FireOffset * vect(1,-1,1)) >> FireRot);
}

//condition for spawning projectiles if in FPS View for player///////////////////////////////////////////////////////////////////
else if (PC.bBehindView == false)
{

FireStartLoc = Instigator.GetPawnViewLocation() + (FireDir * FireOffset.X);
//FireStartLoc = Instigator.Location - FireDir*FiredProjectileClass.default.CylinderComponent.Translation.X;
//FireStartLoc.Z = FireStartLoc.Z + FMin(Instigator.EyeHeight, Instigator.CylinderComponent.CollisionHeight - FiredProjectileClass.default.CylinderComponent.CollisionHeight - 1.0);
}
//condition for spawning projectiles if in FPS View for player///////////////////////////////////////////////////////////////////

//default condition for spawning projectiles for player
else
{
FireStartLoc = Instigator.GetPawnViewLocation() + (FireOffset >> FireRot);
//FireStartLoc = Instigator.Location - FireDir*FiredProjectileClass.default.CylinderComponent.Translation.X;
//FireStartLoc.Z = FireStartLoc.Z + FMin(Instigator.EyeHeight, Instigator.CylinderComponent.CollisionHeight - FiredProjectileClass.default.CylinderComponent.CollisionHeight - 1.0);
}

if ( (PC != None) || (CustomTimeDilation < 1.0) )
{
FiredProjectileClass = GetProjectileClass();
if ( FiredProjectileClass != None )
{
FireEnd = FireStartLoc + FireDir * ProjectileSpawnOffset;
TraceFlags = bCollideComplex ? TRACEFLAG_Bullet : 0;
if ( FiredProjectileClass.default.CylinderComponent.CollisionRadius > 0 )
{
FireEnd += FireDir * FiredProjectileClass.default.CylinderComponent.Translation.X;
ProjBox = FiredProjectileClass.default.CylinderComponent.CollisionRadius * vect(1,1,0);
ProjBox.Z = FiredProjectileClass.default.CylinderComponent.CollisionHeight;
HitActor = Trace(HitLocation, HitNormal, FireEnd, Instigator.Location, true, ProjBox,,TraceFlags);
if ( HitActor == None )
{
HitActor = Trace(HitLocation, HitNormal, FireEnd, FireStartLoc, true, ProjBox,,TraceFlags);
}
else
{
FireStartLoc = Instigator.Location - FireDir*FiredProjectileClass.default.CylinderComponent.Translation.X;
FireStartLoc.Z = FireStartLoc.Z + FMin(Instigator.EyeHeight, Instigator.CylinderComponent.CollisionHeight - FiredProjectileClass.default.CylinderComponent.CollisionHeight - 1.0);
return FireStartLoc;
}
}
else
{
HitActor = Trace(HitLocation, HitNormal, FireEnd, FireStartLoc, true, vect(0,0,0),,TraceFlags);
}
return (HitActor == None) ? FireEnd : HitLocation - 3*FireDir;
}
}
return FireStartLoc;
}

return Location;
}

One way to do this is to do a hitscan trace (from the camera) at the moment of fire to get the anticipated hitloc. Then just spawn the projectile from the pawn’s weapon, pointing at that hitLoc.

Thanks mate for the tip, I will try it. In this same function there is already a hitscan call.

Do you have these settings in each gun in default properties? if not put them there.
try adjusting these to move the projectile more forward at spawn time.



FireOffset=(X=50,Y=10.0,Z=-5.0)//Forward+ to back-, left- to right+, up+ to down-;//moves paintball

PlayerViewOffset=(X=50,Y=5.0,Z=-10.0)//+Forward to -back, -left to +right, +up to -down;//moves the arms and gun


hopefully it is that easy and if so then making adjustments to X IN FireOffset should solve this.

Thanks mate for the tip. Yeah, I have setup the fireoffset of each gun, but the problem is not that simple. @CobaltUDK also had this same problem, and he told me he solved by changing the tracing of the projectile, making the fire start position on a socket in the weapon. I am waiting him to explain to me how he solved in Unreal Script.

use the MuzzleVector for fire start position. in the ProjectileFire() when you initiate yourprojectile(MuzzleVector, pBallSpeed);



RealStartLoc = GetPhysicalFireStartLoc();
MuzzleVector = Normal(Vector(GetAdjustedAim(RealStartLoc)));


The float param pBallSpeed is a private custom added var for the projectiles speed.

Thanks bro, I will try it, then I post here the results.

Cheers

:cool:

Something we had an issue with like yours, but it was standing with a wall or object to close in front of us. caused the problem your describing. never tried the wall behind. might have to test that just to see. The closeness i am talking about was basically just about standing on it maybe 5 feet away at most, you would see no projectile. like it made contact before it spawned. but then also the faster the bullet speed is. the farther in front of your gun the projectile will spawn so you might see a space between your barrel tip and bullet spawn, like a gapped space. Especially on a dedicated server. Not so noticeable on listen or standalone modes. i was setting max projectile speed at 300fps. Real guns run way higher so i am assuming that gap will get worse as in larger> farther out in front of the barrel tip before it actually spawns. Pretty sure this is caused by the time it takes to replicate the projectile which if i remember right is either 0.03 or 0.3 seconds to replicate the projectile before it spawns. If you find a solution to that let me know. i would love to hear about it, if found.