Advertisement

Aim assist and bullets correction

Started by December 03, 2019 03:08 PM
7 comments, last by G-Dot 5 years ago

Hello, everyone! Recently I've tried to add an aim assist system to my game and faced some difficulties. I need to mention 2 things:

  • I don't use hitscan weapons, so the correction can be done by correcting spawn angle of a bullet or by setting home target component in UE4 projectile movement component.
  • I work in UE4 and planning to make this system with C++.

Explanation

Firstly, let me explain what I want to achieve. I want bullets to have a little correction after shooting so that player don't need to aim perfectly. There are some situations where real position of sight is different from actual bullet trajectory, for example:

Central dot is little bit off of the target, but in this case I want bullet to hit enemy.

Part of the enemy is hidden behind the obstacle and central dot is pointing to the obstacle, but still I want bullet to hit.


There are only a little part of enemy visible, and maybe situation a little bit extreme, but I want bullet to hit.


Basically what I want is to have a hit if part of enemy model is inside this shape:


Possible solution

I have only one idea of how it could work. It's scheme looks like this:

So on the upper part of image is how it looks like in screen space view. The blue dot in the center represents a player's sight center and it's a line trace. Then we got a green "circle", basically it's 4 line traces and finally we got red "circle", but again it's just 8 line traces. Side view showing a direction of line traces, they will be traced in cone shape.

How it will work

When one of the red traces hit the target, bullet trajectory will be slightly adjusted to the direction of target, meaning it's not a 100% hit, but rather 50%. If one the green of blue traces hit the target then your bullet trajectory will be adjusted so that's a 100% hit. Blue trace is for situations, when your sight right at enemy, but the green traces don't hit the target.

Conclusion

It's may be not very good solution, for my opinion, because it's not very accurate and may cause some performance issues, since I need to trace 13 lines each frame. But it's the best, which I came up with. So maybe there are some better solutions, which can be done inside UE4.




The easiest approach is just to test a cone instead of a line. A cone test is just an angle check between two lines - you take one line from the player to the target, a second one from the player to the reticle, and you check the angle between those two lines (i.e. using the dot product) is less than the angular width of the entire reticle.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Advertisement
swiftcoder said:

The easiest approach is just to test a cone instead of a line. A cone test is just an angle check between two lines - you take one line from the player to the target, a second one from the player to the reticle, and you check the angle between those two lines (i.e. using the dot product) is less than the angular width of the entire reticle.

But how can I know to which enemy I should trace the line? It's may be 2 or more enemies on the screen at the same time.

When both combatants are stationary, then using a progressively widening circle should get good results. Perform one ray cast. If it hits, fire a bullet along that ray. If not, try again in a tight circle around the the initial ray. Continue expanding the circle until you hit a target, or until you give up and call it a miss.

When combatants are moving, things become a lot more complicated. Maybe I'm intentionally leading the target because the target is moving, and the aim assist will cause me to miss. Maybe I'm intentionally not leading the target even though it is moving because I expect the target to make a quick turn, and again the aim assist will cause me to miss. I don't think that there's a truly good solution to this problem.

a light breeze said:
When both combatants are stationary, then using a progressively widening circle should get good results. Perform one ray cast. If it hits, fire a bullet along that ray. If not, try again in a tight circle around the the initial ray. Continue expanding the circle until you hit a target, or until you give up and call it a miss.

When combatants are moving, things become a lot more complicated. Maybe I'm intentionally leading the target because the target is moving, and the aim assist will cause me to miss. Maybe I'm intentionally not leading the target even though it is moving because I expect the target to make a quick turn, and again the aim assist will cause me to miss. I don't think that there's a truly good solution to this problem.

I don't think that this could work fine since you can position your reticle a little bit off and it's center will be on the obstacle, but enemy still be in valid zone. In this case sphere trace will never hit enemy and always will count it as a miss.

But if instead of sphere trace use some line traces, which will create a doted circle, that might work. I defenetly give it a try.

Advertisement
G-Dot said:
But how can I know to which enemy I should trace the line? It's may be 2 or more enemies on the screen at the same time.

Unless we are talking about hundreds of enemies on screen, just check them all. A few ray casts aren't very expensive.

Ideally you'd have a cone-cast operation available to you, but it doesn't look like Unreal provides one. You can probably use a cone-shaped physics collision object to cut down the potential list of enemies (make it invisible and turn off physics response).

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

So I've tried to make the system, which I've mentioned in my first post. I was a little bit surprised, but it worked out. But with one exception. I thought that I should do that double cone trace every frame, but I realised that this is unnecessary. So I make this line traces each time player hit the fire button.

Also I've got some control over guns behavior. I've promoted trace distance, green and red circle radiuses to the variables and I can manually set up them in order to get more variety in guns. In addition I've promoted amount of line traces for each circle, because 8 lines for red and 4 for green was not very good values. Results can be seen in screenshots:

Not very hard gun to use, cause it have a pretty large green(100% hit) and red(50% hit) circles.

This gun is more difficult to use, because of the smaller circles.

This is how it works with enemies. Pink rectangle represents a hit point without gun's default spread.

It can appear that now aiming is very simple and in order to hit enemy player need just to look at him. But in reality my game is very fast and player got split of second to aim at enemy. Besides only green circle guaranty a 100% hit and it's not very large to land a headshot randomly aiming at enemy.
So summing up my feelings from playing with this system the game became better and I've get that I wanted. So I can say, that for me this system have worked out.

This topic is closed to new replies.

Advertisement