🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Tech challenge - how to avoid ball mishits? (Unity)

Started by
9 comments, last by kenBlade 5 years, 2 months ago

hi all, just wondering if I could get your tips or insight on a specific gameplay and animation question I've had for a long time:

For tennis games and other games involving hitting fast moving objects, what would be a good way to avoid mishits like in this video? (Far side 0:50s and 0:58s)

 

(watch in .75 or .5 speed for even more clarity)

This is quite a common visual bug for tennis games as I assume the devs didn't have time to polish, but I want to make sure I plan and code for my tennis game to avoid this kind of blemish.

I'm assuming the fix would involve some kind of IK solution and maybe target matching to get the hitting animation to line up with the correct hit "pose".

Any advice for a Unity beginner like me would be super appreciated ?

Advertisement

Use a Fixed Time Step not Variable if the speed of the ball is causing missed collision.

Don't use Update() for anything physics related, that is why you have FixedUpdate()

Programmer and 3D Artist

thanks for the advice Rutin!

BTW I found this tutorial for Final IK which does exactly what I need. 

However I'm wondering if similar results can be obtained using Unity's built in IK?

(I don't need the uneven terrain adjustment, only the target tracking:)

https://www.youtube.com/watch?v=OhCtiV5r8HA

 

Any further suggestions?

There's basically two ways to handle that hit -- actually do real tennis racquet vs ball physics, or do fake physics... In the video it looks like they're faking it as at 0:50, yeah, you clearly see the ball get "hit" even though the racquet doesn't hit it...

With fake collisions, the gameplay can decide whether you hit or missed however it likes (did you press the right button, have the right timing, right skill, right dice roll, etc) and then if it decides that you hit the ball, it can temporarily place a rigid physics plane at some position that the ball will bounce off of, or use some other method such as just overriding the velocity of the ball directly. The next problem then is how to make the animation actually look convincing (and hide the fact that the physics are fake). To do this properly, you really want the game to be able to decide whether your character will hit or miss a short amount of time before that actually happens. The ball follows a predictable path, so you can estimate where it will be as it passes next to the character, and then use that position as an IK target for the character's racquet to reach. You now have a position for the racquet and a time that it need to arrive. You can then pick a swinging animation (or a blend of a few of them) and add some IK blending on top to make sure that the racquet reaches this location at this time. Then, it should look convincingly like the character actually hit the ball (even though it really just bounced off of a magic infinite-plane).

With real collisions, you do much of the same thing -- when the player presses a button to swing, you predict the ball's path and identify the exact location and time for when the ball will pass next to the character. You then select a blend of different swinging animations and IK algorithms to make sure that the character's racquet is swinging through that location at that time. You can use IK to subtly change the angle of the racquet based on the user's input in order for them to be able to aim their shots. Instead of doing fake collisions where the ball is magically bounced backwards, you do real collision against the racquet's collision shape. Because these are two small, very fast moving objects, you will want to perform your physics at a very small fixed step size / very large fixed update rate, or use a continuous-collision-detection scheme (CCD) that can determine sub-frame collisions between a moving sphere and a moving hull.

Thank you so much for such a crystal clear, detailed response!

 

I'm leaning towards the former -- fake physics -- as that's what most if not all non-VR, non-1st person tennis games do.

My follow up question below mainly involves (TLDR:) how do I implement this in a logical, natural looking, and easily tunable way in order to account for every hitting angle in my game? (by hitting angle, I mean the difference in height[Y] between the players hip and the incoming ball),

 

Here's my thought process. Hope I'm not horribly over complicating it or going down the wrong path--

Assumptions:

Setting an IK target is relatively easy in Unity since I can just create an empty game object and make it a child of the ball, or just make the ball the target object directly.

Unity's IK solution only allows the hands or feet to be controlled by IK -- I am assuming IK cannot control the racket directly.

To make the racket position AND angle (z-rotation, like a windshield wiper) look precise and convincing, this would require an accurate X/Y/Z position at contact and some z-rotation of the racket if the ball is above or below the "comfort zone" -- comfort zone being between hip to shoulder height. I don't want IK or code to affect the Y and X rotation of the hand or racket.

For this case, let's set the sweet spot to a range around the player's hip height as the Y value for comfort zone, say Y = {1.0-1.5}. In other words, the comfort zone is the range of Y values where the racket can hit the ball and still be parallel to the ground at contact.

Setting the correct X/Y/Z position seems easy enough since hand y = racket y, and hand z = racket z, and hand x = [racket X - racket length], but the z-rotation (windshield wiper motion) of the racket is where things get tricky--

Need to decide on the min/max Y range of the player's hand y before the hand+racket is allowed to z-rotate upwards or downward (lets say Ymin/ymax is 1 and 1.5), and the min/max hand+racket z-rotation angle (let's say -80deg to +80deg), then use that z-rotation angle and the racket's length to calculate the "sweet spot" of the racket face. then in code (or IK?),offset the players X position in order to line up the racket and and ball exactly-- not sure if using transform.position or IK would be the better solution here?

 

Caveats:

My goal is to not change each animations elbow angle angle too much, but it would be super nice if there is a procedural way to add a little dynmaic extra elbow flexion or extension, and or shoulder raising/dropping and outward stretching or inward squashing (not sure if these are the right terms), depending on ball distance -- as long as it looks natural.

To sum everything up, I'm just trying to emulate what every AAA tennis game does to achieve proper contact of the racket with the ball in a more procedural way, to reduce the number of animations I would need to make. Please let me know if this seems like the right track!

40 minutes ago, kenBlade said:

Unity's IK solution only allows the hands or feet to be controlled by IK -- I am assuming IK cannot control the racket directly.

I haven't used Unity's IK, but if this is the case, you can always write your own solution. To get AAA style sports-game animation, you'll probably have to write a hell of a lot of custom animation code rather than using an off-the-shelf solution :(

In my experience, sports games do a lot of intensive animation blending and state transition stuff that isn't required by most games / won't be supported by general solutions. Things like keeping track of which foot was the last on the ground and doing different blends based on that (which requires tagging the foot-fall animation frames and then all other frames with left-phase or right-phase), tagging frames for when the ball and a hand/foot should collide or lose contact, having a massive database of similar animations on hand and being able to quickly query which ones are the best to blend for different target poses, etc...

41 minutes ago, kenBlade said:

To sum everything up, I'm just trying to emulate what every AAA tennis game does to achieve proper contact of the racket with the ball in a more procedural way, to reduce the number of animations I would need to make. 

Ignoring IK for a moment, you can get a long way with simple animation blending. Say you want to write a solution for when the ball is going to pass through a 1m x 1m square to the right of the character. You could make four swinging animations -- one for hitting a ball at each corner of that square -- and then by blending those four animations with varying weights, you can generate a new swing animation for any other point within that square too! To get better quality, you can add a fifth animation for the center of the square, too (which breaks it into 4 triangles, so can also make it cheaper as now you only need to blend three animations).

You can also make single-frame animations which are basically just poses, or different ways of holding the racquet. By blending those in, you can change the angle at which the racquet hits. Also, blending doesn't have to occur globally across the entire skeleton. When blending animations you can restrict it to just an arm and fade out at the shoulder, or just the spine, or just the legs, etc... Again, you can either use unity's existing tools for this, or take full control and implement all of this animation/pose logic yourself.

I would try to do most of the work by having a catalog of every different kind of swing that you want your characters to be able to make -- enough of them so that by blending them together you can pretty much place the racquet anywhere. Then I'd add IK on top of that just to do any final tweaking that's required, NOT as the main technique for getting the racquet to the right spot.

Also, if you want to completely avoid the fake hit situation from the video you posted, you can detect when your animation system has failed pretty easy by putting a sphere collider on the racquet and checking if the ball actually hits/misses it. If the ball misses the racquet (because your animation code has failed to move it to the right place), you can choose to not apply your fake physics :D 

 

Once again, thanks for your incredibly detailed answer!

A lot of the basics you described sounds perfectly doable with Unity's tools, while the more sophisticated parts may be solvable with custom editors and tools. Best of all, the way you described it is simple enough for beginner like me to understand. I esp. like the idea of the 4 corners with the point in the center -- who would've thought! 

Now that just leaves me one last question: do you do consulting for sports games? I wouldn't be surprised if you already do!

3 hours ago, kenBlade said:

Now that just leaves me one last question: do you do consulting for sports games? I wouldn't be surprised if you already do!

Haha I actually do, but only on the rendering code! e.g. I added HDR-TV support to the XbOne version of AO International Tennis, but honestly I have no idea how the gameplay / animation / physics tech on that game actually works ? What I've described is how I'd do it / my guess at how games like that work. I could ask them, but it might be considered a trade secret so I'd rather just guess ?

No way! I'm a fan, I actually own AO Tennis.

If they're willing to answer fan mail from a hobbyist developer, I'm wondering if I could ask them a bit about their engine and animation system. But this might also be a conflict of their interests..

My burning question is will they make a sequel or continue building on the existing game? I'm guessing it's the former.

Here's my WIP so far -- made 5 animations in a diamond shape (1 on each point + 1 center), and drew a circular hitbox since the racket face is large enough to round out the diamond's edges. Anything outside of that hitbox will require a different hitting anim, while anything within this hitbox counts as a safe clean hit and would look right. However this only works for the X/Y axis for balls where the player is stationary. For X/Z, I'm planning lots of different footwork patterns to account for z distance to the ball like approach shots and retreating shots. So far, so good! Really fun implementing the ideas we discussed.

image.png.5248fd540340bda3e523320baef62773.png

 

haven't completed solved my problem above, but wanted to share a short demo video.

next step will be to implement locomotion and ball striking.

 

 

This topic is closed to new replies.

Advertisement