Camera trace slightly innacurate

Hey everyone, I’m having a problem with doing a camera line trace. The idea is to get the third person follow camera line trace (basically the center of the screen), which works on the listen server, but the tracers on the client don’t exactly go to the center but slightly down and to the left. I’m not sure what the problem could be, might be a replication problem but I haven’t been able to figure it out yet… I attached an image of my blueprint (which is being called by a “Run on Server” event) and the listen server/client comparison.




Any help would be greatly appreciated.

Can’t seem to edit the post (getting an error) so I’m just adding a comment for further clarification.

I forgot to mention/elaborate that the follow camera trace line is the blue one, the red one is my weapon muzzle trace, which should end in the camera trace location (again, works fine on server). But judging by the second screenshot (client screenshot) it appears that the start location of my muzzle trace is also off (should start at the weapon barrel), so I guess both trace problems might have the same root cause…

You seem to have different screen sizes between client and server windows. I’m guessing this is what is throwing off the calculations.
The sizes have changed but notice that the crosshair is in the same space

Perhaps you are measuring the center of the screen wrong? Are you getting the resolution with dpi scaling?


Is your crosshair anchor in the center of the screen with alignment set to 0.5 x 0.5?

I don’t think the resolution is the problem, I’ve done the tests with different size windows and same size windows, result is always the same (server works fine, client with slight offset). Here’s a comparison of the same window sizes (left window is client so it has tracer debug turned off, the right one is server), both of them aiming at the same location with the crosshair.

Note: I attached links to screenshots because apparently I can’t embed any extra new media files because I’m a new member.

About the crosshair, yes I’ve anchored it to the center and aligned to 0.5 x 0.5

Btw, If you check the client screenshot from my original post, you can see that the blue camera trace line does not actually begin at the camera center, because otherwise it wouldn’t be visible. If the line trace started at the camera location, you wouldn’t actually be able to see it (like in the original listen server screenshot). Also the guns muzzle trace (red line) appears to begin a lot lower than it should on the original client screenshot, while the muzzle trace on the original listen server screenshot has the correct start position. I’ve been stuck on this problem for 2 days and I’m unable to come up with an explanation for this…

The client blue trace seems to be coming from the characters center of mass. Does it calculate the weapon socket position correctly?. Seems like the socket is not found so it’s defaulting to the center of the collision capsule for some reason.

You can also get the center of the screen through de-projection:

Also are you sure the follow camera is updating correctly? One of the characters will be an autonomous proxy it will have cut down nodes (no player controller etc)

You need to narrow down the information to two vectors:

  • gun barrel location
  • line trace hit
    and ignore the camera for calculations later on.
    Server should only register the start and end points & then do a check server side.

This is working:


2

If you want full server side only detection then you could pass in the client screen size to calculate the center of the screen server side and do the de-projection there.

Here it is in action

I see… so you’re saying that I should not be calculating the player/camera positions on server side, but do it on client side and just pass the results to the server? I’m guessing that calling “Get Player Controller” with Index = 0 on client (not on ROS event) will always return the local player since it will always be the first one in its replicated instance?

Anyways, this seems to fix my problem but kinda introduced another one.
The problem that appears now is that the damage is being applied inconsistently. When I shoot another character, the damage registers every third bullet or so…

Modified Bullet trace blueprint

Modified ROS Fire event

How I’m calling these

This is my MC_SpawnFX and SetAppliedDamage event/function

Are you firing at high speeds in succession? If som you could be saturating unreal’s network protocol and that can cut out any type of multi-casting (it has lower priority).

Are all fired bullets registered on the server side?

On client it should return the local player.

I would move the MC Spawn FX after Set Applied Damage just to keep the server / client logic in the same flow.

Not sure how unreal treats it, it the network is saturated and it drops the replication to clients in theory the next node should still execute.

Camera location:
Player Controller (cast to class) → Get Camera Manager → Get Camera Location

Camera Forward Vector:
Pawn → Get Base Aim Rotation → Forward Vector

Clients will match servers

Sorry for the late reply, It was 4 in the morning when I wrote my last reply :sweat_smile:

I have an EnhancedInputAction that triggers the shooting. I’m attaching the blueprint for semi auto firing mode, where the bullet trace and the server event is called. I also have a full auto fire mode, but for the sake of simplicity I’ll only attach the semi auto logic because the problem is present in both scenarios…

I moved the MC Spawn FX event to the end, so it looks like this now

And I just noticed that I forgot to add a screenshot of the “Set Applied Damage” function, so here it is

I’m not sure what you meant by “On client it should return the local player”, but after some debugging, I noticed that the damage is not always being applied because the Line Trace By Channel (bullets) in the ROS_Fire function returns false

I checked the collision presets on my character blueprint and they look fine, basically the capsule component should ignore these line trace channels, while the mesh component should block them


Thank you for your suggestion. Is there any pros / cons for doing it the way you suggested, or the way 3dRaven suggested it?

Rev0verDrive method will work too, though you still need to add in the trace from the weapon to the intersection of the line trace where it hits the wall.

Is your full auto constantly hammering the server with new requests each fire? if so that is your problem. You should be sending info to the server of when you begin full auto and when you release.
The server should handle the firing loop on it’s own without the constant need to send information “fire”, “fire”,“fire” a could of times a second.

it should be client sends to server => I’ve begin to fire => server fires either burst or looped full auto (if ammo) => client sends stop fire => server stops its firing loop.

Just make sure the start and end fire requests to the server are reliable or you might empty your gun without the stop info.

I see what you’re saying… I will modify the full auto to incorporate your suggestions, but the problem is not specific to full auto, but also to semi auto, which (judging by your suggestion for full auto) is done correctly. Client sends to the server that It fired a single shot and sends the calculated weapon muzzle start location and camera line trace end location => server draws the line trace from the weapon muzzle to the camera center and checks if there were any hits => applies damage, etc.

It appears to me that there is a problem with this bullet line trace (which is done on server)
For example, this is me firing the pistol (which routes to semi auto flow of the blueprint), on the screenshot you can see that the first tracer was registered as a hit, while the other two were not. I waited about half a second to a second before firing the next shot.

Are you sure it’s not a visual bug? The dot at the collision point is basically a rotated plane. Don’t judge the hit by visuals alone. print out the hit outcome or log it.

Yup, I already confirmed it with a print out, I printed out both the client sided tracer (center screen blue tracer) hit boolean and the server sided bullet tracer (red) hit boolean. The blue registers correctly while the red one does not.

What is the default reaction to the bullets trace channel? is it block or ignore?
Notice that while firing you are only tracing against this channel and not just static / dynamic geometry.

Perhaps that is why the trace is not registering with walls. If the default reaction in the custom trace channel is set to ignore then that would be the main culprit. Default reaction should be block.

Go into any random static mesh component and see the response reaction for bullet trace (ignore,overlap or block) => needs to be block.

The default is set to block

Here’s a screenshot of the character mesh collision preset

And its capsule component collision preset

Here’s a gif of me shooting another character and the log messages of the bullet trace hit
(sorry for the low framerate, there’s an upload limit, open in another tab for better visibility)

BulletTracerTest

Try turning on trace complex. The source of the trace still doesn’t seem to originate from the gun muzzle. Are you getting the gun muzzle exit socket location?

Same result on the trace complex.
Good catch, I had a slight difference in my muzzle socket name default variable and the actual socket name. I fixed this and now the tracer goes directly from the muzzle (I guess it went from the weapon center of mass before, because it couldn’t find the socket), but the main problem still persists. This is my setup for muzzle.

Muzzle socket on the pistol skeleton

Muzzle Socket Name variable on the Pistol blueprint class

Where I’m getting the muzzle location

How the function looks like

The way I’m doing my traces ensures the servers will closely match the clients.

I’m working with true first person, camera is attached to head basically. When I crouch the clients camera stays with the skeletal mesh. If I use a camera reference on the server the cam is in it’s default standing position. So the traces will not match. To get them to you have to use camera manager → get camera location. Same applies for rotation and forward. Can’t simply use the cameras rotation, you use control rotation or base aim rotation. Base Aim Rotation is the better option, it’s more accurate.

For shooting I have two setups. One for hip and one for ADS. The Hip shooting does a line trace forward and I take the impact if a hit occurred, else trace end, then find look at rotation from muzzle to the that location. This gives me an Aim vector to use for my projectiles Aim velocity.

For ADS firing you don’t have to trace. (Muzzle location + (Cam Forward vector * n distance)) will give you a aim point. Multiply that by muzzle velocity and you have a Aim Velocity Vector for the projectile.

Shooting logic on my end is split into Proxy based systems. Client (Autonomous), Server (Authority) and then Simulated to get your shots on other screens.

My projectiles are object pooled. So no "spawn/destroy perf hits.

Client fires a local only projectile that interacts with the world. Impact fx such as squibs and decals etc. Client then sends an RPC to the server to fire. Server fires its own local projectile. Then Multicasts to Sims to fire their local. Server passes the relevant info to sims (aim velocity etc).

When the server hits it multicasts the Hit location/normal etc to SIMS. If a player is hit it RPC’s the hit player with custom hit info.

No projectiles are replicated in this setup. It’s all low data localized.

Here’s a demo of it. Mind that I haven’t finished setting up left hand IK or Aim offset. Weapon in the demo is simply attached to the right hand.

Also should note there are 3 projectile classes (autonomous, simulated and authority) as well as dedicated obj pool managers for each. Each projectile class is coded to do its specific job. No carry over bloat.

e.g. clients have a visual element, sims/server only collision. sims has audio flyby (whizz). server has hit reg → dmg etc.

1 Like

Edit:
Ok revised the project

vid

Works ok on both server and client.

Edit max target distance float in bottom right of client fire can be disconnected & replaced with smaller float (it just needs to slightly extend beyond the normal distance). Was tired at that point :stuck_out_tongue: