![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | Andrew Strauch |
We have our player with cutout animation, and it uses inverse kinematics and bones for the limbs. Particularly, we are looking at the arms here.
We are attempting to add aiming to the gun. When facing to the right and aiming, it looks great. When facing to the left, however, it gets wonky and the arms don’t match up at all.
We are setting the parent Body sprite.scale.x to -1 when the player turns to the left. Tested it out in the editor and this works as expected.
For some reason, the rotations applied get messed up due to the flipping.
Code below:
var rotation_offsets
var transforms
Place player hands on Position2Ds on gun
func place_hand(base_node, ik_node, is_front):
transforms = []
rotation_offsets = []
var target = front_hand_position if is_front else back_hand_position
_calc_ik(base_node, ik_node, target, true)
_apply_ik(base_node, ik_node)
calculate
func _calc_ik(node, ik_node, target_node, is_forward, index = 0):
var length = 0
var target = null
transforms.append(null)
rotation_offsets.append(null)
if node.get_child_count() > 0 and node != ik_node:
target = node.get_child(0).global_position
rotation_offsets[index] = node.get_child(0).position.angle()
length = (target - node.global_position).length()
_calc_ik(node.get_child(0), ik_node, target_node, is_forward, index + 1)
if node == ik_node:
var rot = 0
var pos = target_node.global_position
transforms[index] = Transform2D(rot, pos)
else:
var rot = (transforms[index+1].get_origin() - node.global_position).angle()
var pos = (transforms[index+1].get_origin() - (Vector2.RIGHT * length).rotated(rot))
transforms[index] = Transform2D(rot, pos)
apply
func _apply_ik(node, ik_node, index = 0):
if node != ik_node:
var rotation_to_apply = transforms[index].get_rotation() - rotation_offsets[index]
_apply_ik(node.get_child(0), ik_node, index + 1)
node.global_rotation = rotation_to_apply
Hi!
First, i’m courious about is_forward
variable… it seems to be always true, and never used… is reserved for future use?
Second, i think the problem might be when rotating pos:
var pos = (transforms[index+1].get_origin() - (Vector2.RIGHT * length).rotated(rot))
I made a (more simple) aiming animation here and i had to add 180 when rotating if flipped.
I didn’t go through all the ik chain, just rotated one part of the body, so idk if this apply to your case… but may be it helps.
Also, let me ask you if the gun is flipped with the body (as it is its child or something like that) or not… cause rotation in gun seems to work fine.
p7f | 2019-08-27 12:32
or perhaps you should change the Vector2.RIGHT
when flipped.
p7f | 2019-08-27 12:33
Tried the vector.RIGHT, that’s just getting the normal though.
Here is a repo with the simplified version of the code that can be run in Godot. Left click for moving, and right click to process movement every tick. It mirrors the same IK chain.
Andrew Strauch | 2019-08-27 18:59
Did you ever get this figured out? I’m attempting to the exact same thing now - aiming a gun in my character’s hands using cutout animation, auto-gen bones, and IK. Any help you could give would be greatly appreciated.
dillydadally | 2021-10-11 05:03