I need help with some information. I am implementing a hack and slash game in Godot and i need to know how to cause the animations to interpolate so that the sword swing stops when it hits a shield …
If i increase the number of physics steps will the animation start doing sub-ticks, like 0.001 or a frame for example?
So for accurate sword motion collision i would just increase the physics steps or physics frame rate and make sure the animation is set to continuous ?
How can i make sure collisions with an object like a shield are processed before the torso? At the moment i set a flag when the shield is hit and then in ``physics_process()`` i allow the damage if the shield was not hit … but i wonder if it can be done purely with signals or whether the shield will be processed after the torso…
Animations have nothing to do with physics. They are just visual representations. If your physics granularity is denser than your rendered frames granularity and you want to stop the animation as a result of a time-dense physics, then use the physics callback mode. It’ll let you stop the animation at physics tick granularity.
Yeah ill try to stop the animation on collision … i was calling get_tree().paused = true previously before i had the callback mode set.
I havent tried pausing since so maybe the result will show less penetration. I might also try raycasting forwards from the sword instead of between the last two frames, but then i dont know the ray length. So i need a way of running the animation a frame in advance then drawing a previous or interpolated frame.
Ok, theres a shield Area3D and a torso Area3D. So if the collisions are handled with signals i have implemented two algorithms.
The first just trusts the physics system to detect the sword hitting the shield because the area sweeps through before hitting the torso.
The second collects flags for each area intersected by the sword and uses physics process to cast rays through the swords current and previous positions. This works better but im not sure why.
Ok if the first policy is used then if the shield is on the left, and the sword arrives from the left hitting the shield first and also penetrating the torso then you could hope that the shield is processed first when godot processes the signals, so that the sword can be disabled from causing damage and the animation could be paused.
If the sword arrives from the right and passes through the torso but also touches the shield near the end then of course you need the torso to be processed first.
I suppose both methods work and always benefit from higher frame rates, then the error shrinks. It would be good if the algorithm was ‘iron clad’ (pardon the pun) for lower end systems .
The sword area has a script on it that has the method motion_active() and motion_inactive()triggered by the animation with a method call track and it also records the positions of two points that are child nodes of the sword.
I have a script on the character model that processes the signals from the collisions then in physics_process() i just check the sword rays from between the positions stored in the sword position array betweenarray.size()-2and array.size()-1
And also a point in the middle. I find the nearest position but that isnt really correct if you imagine the tip travels further in a frame than the base of the sword so the collision distance should be a percentage.
So i need to get animation time for the frames processed and then use seek() to find the position more closely matching the collision point, perhaps with lerp().
I will probably need to save the animation time of each recorded point and use that for seek … problem is that the animation calls actually come from the physics process of a parent node …
Just experiment manually how much you need to rewind until you find a value that sells the illusion. It’s a game, not a scientific simulation of sword and shield impact.
The animation needs to be rewinded on the owner of the sword … so im thinking the physics process of the reciever character calls a function on the sword owner that calls seek()
with t1 and t2 as the last and current animation times and a=nearest_col/ray_length is the percentage of the collision and the ray length. Basically seek_time=lerp(t1,t2, a)
And these are just approximations because the rays are taking a shortcut compared to the true arc of the sword between frames