Procedural Animation Issues

Godot 4.2

I am trying to code procedural animation for a 2D bird, and so far it is going pretty well. But the knee keeps bending into the floor and I also can’t find a good way to make the foot raise while stepping into the target position. This is my script for the leg:

extends Node2D

@onready var foot = $Foot
@onready var lower_leg = $LowerLeg
@onready var upper_leg = $UpperLeg
@onready var leg_pos = $leg_pos
@onready var target_pos = $target_pos
@onready var rest_pos = $rest_pos
@onready var floorcast = $FloorCast
@onready var frontcast = $FrontCast
@onready var footcast = $Foot/FootCast
@onready var parent = $“…”
@onready var kneeshape = $“…/KneeShape”
@onready var footshape = $“…/FootShape”
@onready var wing = $“…/Wing”

@export var lower_leg_offset := 1.0
#Leg lengths
var upper_leg_length = 150.0
var lower_leg_length = 150.0

#Step threshold
var step_threshold = 20.0
var max_distance = 10.0
#Easing parameters
var easing_speed = 0.2
var stepped := false

var line_color = Color(0, 0, 0)
var line_thickness = 4

func _ready():
#leg_pos.top_level=false
#leg_pos.position = rest_pos.position
foot.global_position = leg_pos.global_position
wing.rotation_degrees = 180.0

func _draw():
var previous_position = null
for child in get_children():
if !child is Marker2D and !child is RayCast2D:
if previous_position != null:
draw_line(previous_position, child.position, line_color, line_thickness)
previous_position = child.position

func _process(_delta):

queue_redraw()
var target_vector = target_pos.global_position - leg_pos.global_position
var _distance_to_target = target_vector.length()

if frontcast.is_colliding():
	var collision_point = frontcast.get_collision_point()
	target_pos.global_position = collision_point
# Check if the raycast is colliding
if floorcast.is_colliding():
	if leg_pos.top_level==false:
		var collision_point = floorcast.get_collision_point()
		leg_pos.position.y = lerp(leg_pos.position.y, collision_point.y, 1)
		leg_pos.top_level=true
	#if distance_to_target < upper_leg_length + lower_leg_length:
		#leg_pos.global_position.y = lerp(leg_pos.global_position.y, collision_point.y, 0.1)
	wing.rotation_degrees = lerp(wing.rotation_degrees, 90.0, 0.1)
	foot.global_position = leg_pos.global_position
	if leg_pos.global_position.distance_to(target_pos.global_position) > upper_leg_length + lower_leg_length and frontcast.is_colliding():
		#Calculate the midpoint
		var midpoint = (leg_pos.position - target_pos.position) / 2
		#Add a vertical offset to the midpoint
		midpoint.y -= 20.0  # Adjust this value to control the height of the raise

		leg_pos.global_position = lerp(leg_pos.global_position, target_pos.global_position, 1)

else:
	leg_pos.global_position = lerp(leg_pos.global_position, rest_pos.global_position, 0.1)
	foot.global_position = leg_pos.global_position
	wing.rotation_degrees = lerp(wing.rotation_degrees, 180.0, 0.1)
	leg_pos.top_level=false
footshape.global_position = foot.global_position

var foot_position = leg_pos.global_position
var base_position = upper_leg.global_position
var leg_vector = foot_position - base_position
var distance_to_foot = leg_vector.length()

if distance_to_foot > upper_leg_length + lower_leg_length:
	leg_vector = leg_vector.normalized() * (upper_leg_length + lower_leg_length)

#Calculate the knee position
var mid_point = base_position + leg_vector * 0.5
var offset_length = sqrt(upper_leg_length * upper_leg_length - (distance_to_foot * 0.5) * (distance_to_foot * 0.5))
var offset = Vector2(-leg_vector.y, leg_vector.x).normalized() * offset_length
var knee_position = mid_point + offset

if target_pos.position.x > 0.0:
#Target is on the right
	knee_position = lerp(knee_position, mid_point + offset, 1)
else:
#Target is on the left
	knee_position = lerp(knee_position, mid_point - offset, 1)

lower_leg.global_position = knee_position
kneeshape.global_position = lower_leg.global_position

This is my first time asking on a site like this, so apologies if I forget something. (I’m also not the best at math in this sort of situation, so I would appreciate a comprehensible answer)

Here’s a video too:

1 Like

If you make a bare bones project that uses this script and has the same buggy behavior and upload it to github, I will download it and pick at it some.

I actually do not know how to use github, sorry

Do you use amy version control?

what’s that?

Oh wait, you just mean version control?
I’m not sure how to check what version control I am using, but it does say the metadata is for “Git”.