Grabbing Animation in Fighting Game?

Hi there,

So, I want a character’s hands to go for the enemy’s arms and then throw the enemy.

But how would I do the game logic of this??

I was hoping I could use IK, and have the hand bones steer-seek the enemy’s wrists, elbows, etc.

But I can only have game logic for the entire armature, not just one or two bones, right?

Can I… parent an individual bone to a fist mesh? I tried, but didn’t work out.

Otherwise, would I have to animate each and every character so that their throwing animations sync up with their being-thrown animations?
Might be complicated if there are different characters with different heights, sizes, etc.
But then again, this is probably how Street Fighter did it back in the day.

Please lemme know your thoughts, thanks.

I do not think that “generated” animation makes a lot of sense (IK & Co.). It would require an awful lot of work and would (mostlikely) look not very plausible. Adjusting and refining would be very hard.

Therefore I would follow the pre-defined animation road. You would need the animation pair of each character. Yes, these will be quite a lot of them.

There might be an option to have some sort of dynamic variations (e.g. hand position dependent on character height). You could do that by playing different animations on separate animation layers.

The important task is that the animation requires initial poses (how the characters stand to each other) before starting both animations. As this might be a bit tricky it might be good enough when the poses are nearly correct.

Yep, you would.

I don’t feel like SF uses IK for throws, since throwing someone and being thrown is more than just a movement isolated to the arms or legs. The entire body is involved - that’s also what makes animation in any respect look good. The entire body should be involved in whatever animation is going on (not necessarily technically - you might be playing multiple animations under the hood on the same armature, for example, but the character should basically look like their entire body is involved).

I would worry about it if you see it’s a problem. Until then, just go the easy route with a test - get one fighter being thrown by the other. Get the animation synced, and then determine if it’s an insurmountable problem. If you feel like it’s too much, well, 2D and 3D fighting games are very animation and character heavy game types. There’s not really a way around that, unless you create the game from the ground up with a gimmick for animation (see this game, Neko Fight, or the more popular Toribash).

I do throws in my own game, by having the thrown actor move into a local position of the thrower,

Local = throwers.worldPosition +throwers.worldOrientation*Vector([x,y,z])

I store data inside a list and pass it into a state, that is used to align the actor,
(in this case pick up the enemy agent)

I use a system I call a “branchless functionary”

Where I call states using

if "ActStrip" in own:
    Strip = own['ActStrip'][0]
    NewState = stateDictionary(strip[0])
    NewState(strip[1])

This way, the throwing actor can pop a action into the thrown actor, (“Thrown”, [dataAboutThrow])
The thrown actor, and throwing actor can store each other as a property, so the throwers state, can actually animate the thrown actor.

Otherwise, would I have to animate each and every character so that their throwing animations sync up with their being-thrown animations?
Might be complicated if there are different characters with different heights, sizes, etc.
But then again, this is probably how Street Fighter did it back in the day.

Logic pretty much dictates that you’ve got to put tons of cubes all over your character to detect what body part collides with which body part of the other character.

If you hit space play animation punch, if fist comes into contact with enemy make the enemy play animation “get hit”. If button space and shift are pressed at the same time play aniamtion “throw” but only if cube close to the character’s chest comes into contact with enemy then send message to enemy and have an animation of his be played and make the character you control play an animation. While these animations play out you’ll also have to deactivate lots of the cubes you’ve parented to parts of the body so there are no conflicts. It’s a lot of work depending on how many moves the characters is going to have.

Also if there are going to kick or punching chanes you’ll have to trigger the next animation to play after you’ve hit one button once and if you want to second punch in the chain to do more damage you’ll have to change the properties of the cube that comes into contact with the enemy. Man it’s a lot of work, it’s probably best to setup all the logic for one character first then have that character fight the same character so you can synch the two characters.

Yeah lots of work, good luck, might be a smart idea to draw some kind of plan on paper so you don’t get confused while putting it together.

you can get a localized hit position, of a hitpoint to detect where that point is relative to either combatant

local = point - agent.worldPosition
local = agent.worldOrientation.inverted()*local

this gives you lots of data

for instance

if local.x<0:
(point is behind agent)

if local.x>0:
(point is in front of agent)

if local.y>0:
(point is on right)

and you can also define a cone using local.x and abs(local.y)


if local.x&gt;0:
    if (abs(local.y)-local.x)&lt;0:
        point is in a cone in front of agent.


Thanks everyone for your replies!
Pardon the late reply, I’m back on blenderartists now.

@Monster,

I guess I’ll just go with making a bunch of grabbed and throwing animations.

Hmm… positioning and pose is important… Could be more complicated that I thought. Something tells me this is more easy in a sidescroller fighting game than in a 3D one. Oh well.

@SolarLune

Yeah, I’m probably going the aniomation route.
Thanks for the fact that fighting games are animation-heavy. I’ll have to prepare for that.
But what do you mean by character heavy?

and ROFL at Neko Fight!

@BluePrintRandom

Sorry, but I don’t know python (yet?).
Your game looks funny tho lol.
But your 2[SUP]nd[/SUP] post… Do you mean the game can set variable values based on where hitboxes are at a given moment?

@Leinadien

Why would I have to change the properties of the cube that touches the enemy?

I figure it’ll deal the same amount of damage.
Though, changing properties is easy enough.
But yeah, I’ll definitely plan this out before doing the gamelogic.

You can move agents to spaces local to other agents

from mathutils import Vector
LocalPoint = Enemy.worldPosition + (Enemy.worldOrientation*Vector([X,Y,Z]))

You can move the enemy, or the player into position /rot over a few frames, and then sync the throw.

I will provide a basic example tonight.

You will need a state machine, and the more complex the game, the more organized it needs to be.

Logic is fast, but there is a limited number of states, and python can actually be faster once you reach a certain complexity level.

I actually use a list as a state machine, and use a dictionary hash table for super fast look up of the state to call, (avoiding a huge if / else tree)


Agent[“ActStrip”] = [ [ “StateName”, [data]], [“NextStateName”, [data] ]

In the agent the code that runs the state machine is

If "ActStrip" in agent:
 
    if len(agent["ActStrip"]) &gt;0:
         Function = Dictionary[agent["ActStrip"] [0][0]] 
         Function( agent["ActStrip"][0][1])

import bge
from mathutils import Vector


def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    space = cont.sensors['space']
    
    
    if 'Target' not in own:
        own['Target']=own.scene.objects['Player_1']
    
    if 'Path' not in own and space.positive:    
        own['Time']=20
        own['Path']=True
    elif 'Path' in own:
        local = own['Target'].worldPosition+(own['Target'].worldOrientation*Vector([-3,0,0]))
        v2 = own.getVectTo(local)
        if own['Time']&gt;=1 and v2[0]&gt;0:
            
            
            
            #v2[0] = distance
            #v2[1] = angle
            own.applyMovement(v2[1]*(v2[0]/own['Time']),0)
            own['Time']-=1
        else:
            own.worldPosition=local     
            del own['Path']
        
        
            
main()




Attachments

MoveToPoint.blend (414 KB)