top of page
Search

Dev Log 8# Fixing AimOffsets and learning how Unreal uses bitwise operations to send rotation values

When it comes to information on all the things inside unreal editor there's no short of help on the internet creating Aim Offsets are no exception. To create an Aim Offset you need single frame animations that contain a single pose and an aim offset is essentially just a blendspace of all those single frame animations.

I found that unreal 5 wouldn't let me shorten an animation down to a single frame unless it was the starting frame. For most of my animations would always keep two frames it would have this weird jitter when played, this would ruin the aim offset. I found that if you create an animation from the current pose this solves the problem.

I also learnt a little bit of cool info about bitwise operations and an example of how they're used in UE5 whilst I was dealing with a bug that was only found in multiplayer testing.


To begin with the issue I faced, it was a bug discovered on the other clients and server. When you aim at the ground your pitch value is -180 degrees however on simulated proxies your character's pitch value only goes from 0 to 360 so when your pitch value goes below 0 degrees your character faces upwards instead of downwards from a simulated proxy's perspective.


So how do we go about fixing this? The first thing that will probably come to mind is the replicated UProperty macro as that is often the best way to synchronise all clients in a game. However a player needs the ability to aim at all times whilst playing because of this a function that handles the player's aim rotation is being called in the tick function and its not a good idea to have a replicated variable in the tick function as it could lead to performance issues.


How does Unreal manage to send important floats such as player rotation values across the network? They do this by compressing them into shorts also known as 16 bit integers and then decompressing once these shorts have been sent across the network and reached their destination. In these compression functions they map the parameter by multiplying it by the output value range and dividing it by the input value range. In the compress function specifically Unreal also uses an AND bitwise operation after this calculation to mask off any winding by comparing the result with the max value a short can be, which in this scenario means that any value that exceeds 360 degrees (which is the max range for a float) gets 360 subtracted from it giving you the final result.

The solution. Since floats sent across the network don't recognise negative numbers and when on simulated proxies the value when facing downwards ranges from 270 to 360 we can map these values in an if check where the conditions are that the current pitch is greater than 90 and is not locally controlled. We create two vectors an input range of 270-360 and an output of -90-0. We then clamp these values through a function called FMath::GetMappedRangeValueClamped as our aim should not exceed this range when facing towards the ground.

https://docs.unrealengine.com/5.0/en-US/API/Runtime/Core/Math/FMath/GetMappedRangeValueClamped/1/





 
 
 

Comments


bottom of page