Calculate Input Direction and Throw Ball/Object

Hello again dear friends!

I’m trying to throw my game ball in a specific direction based on thumb stick input.

I will admit, calculating direction from my gamepad has been an issue for me and my project. I’m not sure I’m ‘getting’ it.

With that said - I’d like to prototype a pass/throw ball mechanic into my sports game.

I would like to press and hold a “pass button” and bring up a interface interaction where the right thumbstick now moves a reticle in the desired passing location (rather than moving the game camera) and then on release, shoot the ball in that direction.

This is a bit over my head and I’ve barely started.

I’ll show you a mock-up I did that goes from default player view to pass button held and interface direction calculate based on player aim. Of course on release, the interface would drop and the ball would be thrown that way.

My current plan is the player can pass in a half circle in front of them, 180 degrees. Not behind.

Here is what I have currently. I only have the ball being flung in the direction of the camera.

Here is my blueprint. It is very bad. And embarrassing. Did I say bad?

What I’m doing is moving the ball to the hand socket, playing an ugly aim animation, detaching the ball and then quickly after hitting the ball with some force based on the camera direction. I’m unsure of how to calculate input direction and then add force toward that direction.

Also - I don’t really know how to “arc” said ball. I’m hitting it with 2 forces, 1 to throw down field and 1 in the up axis so it has a bit of arc. Not sure if that’s the best way.

So, this is a multi-part question:

-How to best get thumb stick input to have an effect on some kind of
game/world direction.

-How to throw something with force in said direction.

-How to get some kind of interface up, and a new state that doesn’t turn
the camera, and some kind of rotation
on the widget interface to show
direction intent.

4 BONUS. Can I do a quick hold and direction nudge for a short pass and a longer hold to “max out” the pass distance. Essentially tap for short and quick pass or hold for a longer “hail mary” style pass.

Whoever even tries to read all this and answer is a saint.

C’mon. You know I’ve got you covered, Jon.

But before I provide a full answer, some questions for you. Is the pass intended to be able to miss? Or will the throw “auto-aim” to always hit its target, and the interface is meant to target the most plausible teammate?

Each has its upsides and downsides in terms of programming the behavior, but rather than dump ideas for both, I thought it best to ask first.

In either case, the throw is the trickier part, but we’ll discuss that more after you respond. The easier part is part one of your question: how to convert thumb stick input into some kind of world direction.

Here’s how I’d do the thumb stick part:

  1. Get the current thumb stick X and Y input values from the pawn or player controller (whichever makes more sense for your setup)
  2. Multiply the stick Y input by your pawn’s world-space forward vector (Get Actor Forward Vector node)
  3. Multiply the stick X input by your pawn’s world-space right vector (Get Actor Right Vector node)
  4. Add these two vectors together, which will create a vector that points in the (world-space) direction corresponding to the thumb stick’s current input, relative to the player’s pawn (stick straight up = directly forward)
  5. Normalize this vector so its magnitude is exactly one
  6. (This is where behavior changes depending on how you want the ball throw to work — i.e. direct-hit auto-aim, or “it just goes into that direction somewhere”)

I’ll follow up more once I know more how to help, and that’s when I’ll properly “answer” the question. But hopefully the above explanation of how to map the thumb stick input has helped you “get” the topic a bit better.

More ideas coming your way soon. (By the way, get ready for some math.)

I was trying to give someone else a chance!!

Firstly, your question is very thoughtful, and touches on some design and play mechanics too. I don’t fully know the answer to that question yet. I think this mechanic will evolve after some multiplayer testing. Some examples of sports games:

In Football/Madden, the quarterback hits the input that receivers have above their head. I don’t think this option works (as well?) because receivers are running routes and the QB knows the route, and throws to connect to the route. In my game, teammates are player controlled and can move freely, dash, double jump so I feel like the ball would do funky things if a player was going straight and then decided to dash backward and jump.

Not sure on that.

In Basketball/NBA2K (more recent versions) there is a targeting indicator that highlights your target and its (I think) based on where you are looking/proximity. This is getting warmer.

I think my idea of a ‘targeting interface’ could put an indicator on the receiver of choice?

With those examples in mind, I think I would like to incorporate some kind of “targeting” but also be able to just throw the ball live because you could have a teammate off screen, or you may just want to get rid of the ball if a defender is closing in to avoid a turnover.

The piece of the puzzle to solve here is the behavior of passing to a potential “targeted” teammate who has the ability to move with crazy otherworldy powers. I’m apprehensive about a “auto pass/catch” because I want to introduce a bit more skill into play that players can get better as they go, but to also make intercepting or picking up a bad pass possible for the defense as well.

Two tidbits - I do think I’d like to introduce power or pass types. If I tap quickly, I’d like a lob; high arc, less distance. This could be used to throw over a defender. I’d also like a version for held, which would be a bullet; less arc, more distance.

Final tidbit - The game has a subtle magnetic theme. So, passing is something that we can leverage that one where the ball might hit a player radius and start to magnetically move toward them. When we score goals, the ball is attracted to a master magnet so this is something we could leverage for the targeted receiver.

So I guess…Design my game too? (Do you do art as well?!)

Don’t tempt me. Designing is just as fun as engineering.

Here’s what I’m thinking for enabling different pass types, while also allowing the player to more finely tune how much to ‘lob’ or ‘bullet’ the pass: use the thumb stick’s position to determine not only pass direction, but also pass ‘bullet-ness’. That is, the farther the player presses the thumb stick (i.e., the farther it is from the neutral center), the more bullet-like the pass will be; the ‘lighter’ the player presses the stick, the more ‘lobbed’ the pass will be.

I offer up this approach on top of the quick-tap idea you mentioned, so the player can fine-tune the pass for as long as the pass button is held down.

If this works well and feels good — which I can’t really be too sure about, since I don’t have a gamepad in front of me right now — the design would sort-of favor bullet-like passes, which I think is actually pretty ideal: they’re the easiest to pull off for beginners, but also the easiest for opponents to intercept, because the ball would fly close to the ground (and can therefore be blocked by anyone in the path, even accidentally).

Following this logic, as players become more skilled, they will attempt the more difficult (due to having to more carefully aim their thumb) ‘lob’ pass, which is harder for opponents to block. These ‘lobs’ would also be harder to pull off perfectly, because the passing player would need to anticipate where their teammate is going, or at least where their teammate ought to be going.

On paper, all of that seems like it would work great to me — but, again, it will depend on how it feels when a controller is in-hand.

But the plus side is, if you do go with an idea like this, programming/scripting the throw logic will be relatively easy to do. (At least, easier than other possibilities I was considering, such as the auto-aiming throw I asked about earlier.)

Finally, of course I do art also. You should expect no less by now.

Look Tim Sweeny, your “Batch” persona isn’t fooling any of us.

Your explanation and idea work-shopping sounds really fun! And it seems to streamline input mechanics while preserving the idea of “pass types” which is intended to bring some player choice and a bit more skill ceiling to the game.

Additionally, this system seems to allow “free” passing as well as some “targeted” passing which is desired as well.

So - let’s do it! How much do I hire you for. I’ve got a highlighter and chap-stick beside me, not sure if you accept those as a sign-on bonus?

Here’s my interpretation of step 1 - Calculating input direction:

Please bask in this glory. This shares some (not all) similarities with my gamepad left thumbstick for player movement.

Next part of the question - Adding force to the ball in the direction?

Your interpretation is exactly how I described it. Only now, since we’ve refined the idea, we probably don’t want to normalize the vector as I originally suggested. We only want to normalize if the resulting magnitude (vector length) is greater than one.

The reason is, we now want the player to be able to specify ‘partial’ thumb stick inputs. This is what makes the ‘lob’ pass possible the way we’ve described it — the player pushes the thumb stick only partway. Pushing partway will produce X-axis and Y-axis inputs that are both less than one (or even much smaller than that). If we were to normalize every time, we’ll be destroying those partial inputs, because the resulting vector will always, no matter what, be forced into having a magnitude equal to one.

So instead, we should only normalize if the combined vector’s magnitude (its length) is greater than one. We can do that very simply by using the Vector Length Squared node along with a float > float node and a Branch node. We’re using the ‘squared’ version of that node here because it avoids calculating an unnecessary square-root. Anyway, just type 1 into the float > float node, because we want to know if the vector’s squared length is greater than one (because 1 squared is also 1).

Hold on to that vector for now. I’ll write up some more ideas in my next message.

By the way, sorry about typing all this stuff out rather than posting screenshots. If you haven’t already guessed, I’m not always at my game-dev workstation, if you know what I mean.

And, as for salary, your offer is generous, but I’m afraid I cannot work for any less than two chap-sticks, plus three bad jokes, paid semi-monthly.

Thanks for continuing to check back in!

I’m excited to carry on with the next parts of the question so I’ll wait til you get a chance to prove some of it out and/or create some visual examples. Ready to get to work here!

Again, your help and ideas have been incredible and I appreciate it so much <3
-Jon

Alright. Well, I didn’t get a chance to fire up the engine last night and actually test out these ideas. So here’s the next-best thing (but keep your expectations low).

I’ll just brain-dump here for now, and hopefully something in the mess will inspire an idea for how to move forward with implementing your feature. Here goes.

  • Let’s call the vector you created (and showed in the screenshot) “ThrowVector”. ThrowVector will, once you modify that normalize to be conditional, give you both the direction and magnitude of the player’s right thumb stick input. The direction part will, duh, be used to determine the throw’s direction. The magnitude part will be used to determine how ‘lobbed’ the pass will be.
  • So far, I’m assuming ThrowVector won’t have much (or any) Z-axis magnitude. This depends on how you allow your players to aim their little pawn dude while they’re running around and getting ready to pass the ball. I’m expecting they can rotate their pawn any which way along the world Z axis (like standing upright and turning in a circle) but that they cannot rotate their pawns on either the X or Y axes. In other words, I’m expecting the pawns to always be perfectly upright. If this is a false assumption, it’s no big deal, we just need to make some adjustments later.
  • Sticking, for now, with the assumption that the player’s pawn is throwing while perfectly upright, we know that ThrowVector has a value of 0 in its Z component. This is because neither the pawn’s forward vector nor right vector (which we got using those two nodes) can point upward or downward at all if the pawn is perfectly upright. Since those two vectors each had a Z value of 0, the resulting combination (which is stored in ThrowVector) will also be 0.
  • Since ThrowVector is, therefore, essentially starting out as a 2-dimensional vector, it’s up to us to add some Z value to make the ball be thrown upward. How much will be determined by ThrowVector’s magnitude.

(Continued in next comment)

  • We discussed making the ball be ‘lobbed’ more (i.e. thrown with a higher arc) if the thumb stick is only pushed partway. What this means in my head is, when the magnitude of the throw input vector is lower, the ball gets a larger Z impulse (causing the ball to fly higher). When the magnitude of the throw input is higher (i.e. the stick is pushed farther), the ball gets a lower Z impulse (causing a more bullet-like throw).
  • So the relationship between the thumb stick input and the impulse’s Z component is inverse-proportional, or something like: (1 - MagnitudeOfThumbStickInput) * MaximumUpwardImpulse
  • (In that preceding equation, MagnitudeOfThumbStickInput is required to be normalized to a range of 0 to 1)
  • Similarly, the ball’s horizontal speed when thrown should be proportional (not inverse this time) to the stick’s input magnitude. Something like: MagnitudeOfThumbStickInput * MaximumHorizontalImpulse
  • Essentially, the results of those two simple equations will be combined into one new 3-dimensional vector, which will then be fed into a physics impulse function (such as this Add Impulse node) to actually cause the ball to be launched

To be sure, variables like those I called MaximumUpwardImpulse and MaximumHorizontalImpulse will need to be tuned a lot to find values that feel right.

Also, you may need to ignore thumb stick input magnitudes below a certain minimum, using a branch node or something, because when the thumb stick is barely pushed, it may be that the player isn’t consciously aiming yet (this is very much like setting the dead zone for the thumb stick, and that may be the better way to handle this, but that depends on which is easier for you)

I might think of something else to dump in a little bit, but that’s all I had loaded in mind-memory for now.

Hopefully that thought-spew makes sense and helps, somehow, in some incredibly improbable way.

Thank you so much for continuing to think this out with me!

I read your response slowly several times and tried to follow along.

Let me first answer your question - When players are moving around the field, they can move the camera freely with their right thumb stick. This is very much like a third person action game/shooter.

What I’m currently imagining passing to feel like is the player holds an input to pull up a “passing interface”. While the input is held, they move the right thumbstick (almost like a radial menu) to “aim”. We have been currently discussing that the thumbstick dictates direction AND pass strength. When the player releases the pass input, the interface drops and the ball goes flying based on their thumbstick decision making. So, I think we’re on the same page. The player will be upright and the camera will be locked while holding the pass button down (cause HUD widget interaction).

I anticipate as players get good, this action will be SUPER quick. A quick hold of pass, a little nudge or flick, and then a release.

So, on to my understanding of your dump:

No normalization of the vector and instead we use vector length squared greater than 1 as a condition to branch the action. As a visual person, I put a “placeholder” PASS input button that fires into the branch.

I’m targeting my gameball which is what I’d like to add the impulse to so that seems right but the rest is where I get lost.

You came up with 2 equations to calculate 2 axis’ of direction? Then you add them together? Then there’s a Z (up?) axis added as well? These 3 come together into the impulse direction?

What if the branch is false? What goes there?

Hopefully we can take this step by step! Before going into input sensitivity or a passing widget, maybe we just try to get a directional impulse propelling my ball in the thumbstick direction?

<3, Jon

P.S.

I know that demo doesn’t include the interface icon thing you are also asking about, but, trust me, that’s gonna be cake when we get to it.

I feel bad for just drive-by blasting a bunch of nonsense in your general direction and then disappearing for a day. But never fear, I realized that what I was trying to explain would be pretty hard to quickly sum up using just words and screenshots.

So I created a demo project. I know it’s unconventional, but I hope you’ll be able to download it, check it out, and learn from it. I created the project in version 4.19.2, which is the oldest version I have installed, which I hope makes it slightly more accessible for anyone who wants to check it out. It’s based on the Third Person Template, which I modified only as needed to get things working.

Here’s the link to the .zip file containing the project: [Third Person Template with Rough Ball Passing Mechanic][2]

I used the left shoulder button to initiate “pass mode” and the right thumb stick to aim the pass. The ball is thrown when the shoulder button is released.

To sum up the experiment in an opinion: I think it’s okay, but not amazing. One thing I think you’ll notice right away, that bugs me enough that I would want to change it, is that the camera inevitably jerks a bit right after the ball is thrown. This is because aiming the throw and rotating the camera both use the right thumb stick, and there’s always a fraction of a second after the shoulder button is released before I reacted and released the thumb stick. This can be corrected by changing when and how the ball is passed, but, for this demo, I tried to stick with what we had already been discussing.

Finally, I tried to comment everything to make it clear, but I fully expect there to be questions. And I’m happy to answer them!

Here’s hoping this demo project was actually a worthwhile way to communicate these ideas!

You’re unbelievable…

Haven’t dove into this yet but I wanted to shoot you a quick message. I’ll report back after I play around tonight and tomorrow - I can’t thank you enough for all your help and support.

This forum is lucky to have you around dude!
-Jon

Hi the-batch and John, I have been working on something similar to Johns project. I have a targeting system and simple AI that quickly attaches the ball when an overlap event occurs (catching) however I do plan on changing that system. Anyway I have had trouble applying impulse based on the duration of my hold on the throw/pass buttons. I was hoping to check out the project file you made batch to get a better understanding of what you two were discussing in this forum.
Unfortunately when I open the project it is pretty empty. No third person character or anything really other than the basic first person template stuff.
Any ideas on what I did wrong? I even installed 4.19.2 still no luck.
Btw I’m new to unreal and this is the first time I’ve tried to open a project or asked questions here. Hope you guys still remember this thing and can give me some advice.
Thank you in advance I hope this message finds you.

Hey guys I figured it out. Sorry if you waisted anytime trying to help. I appreciate you guys and good luck John. I hope you are having succes with your progress.