#Rigidbody physics issue

1 messages · Page 1 of 1 (latest)

rich heath
#
class_name Box
extends RigidBody2D

signal grabbed()
signal thrown()

const HITBOX_SIZE: Vector2 = Vector2(96, 96)

var just_thrown_time: float = 1.0
var just_thrown_timer: float = 0.0

var is_being_carried: bool = false
var is_being_thrown: bool = false

var stack_object_below: Node2D

var throw_velocity: Vector2 = Vector2.ZERO


func _physics_process(delta: float) -> void:
    just_thrown_timer = max(0.0, just_thrown_timer - delta)
    
    if is_being_thrown:
        custom_integrator = true
        throw_velocity = diminish_throw_velocity(throw_velocity, delta)
    elif is_being_carried:
        global_position = stack_object_below.global_position + Vector2(0, -HITBOX_SIZE.y)
        custom_integrator = true
    else:
        custom_integrator = false


func _integrate_forces(state: PhysicsDirectBodyState2D) -> void:
    if is_being_thrown:
        if throw_velocity.is_equal_approx(Vector2.ZERO):
            is_being_thrown = false
        state.linear_velocity = throw_velocity


func is_grabbable() -> bool:
    return true

func get_carried_by(obj: Node2D) -> void:
    freeze = true
    rotation = 0.0
    lock_rotation = true
    
    is_being_carried = true
    
    stack_object_below = obj
    
    grabbed.emit()

func get_thrown(force: Vector2) -> void:
    print(force)
    freeze = false
    lock_rotation = false
    
    is_being_carried = false
    
    is_being_thrown = true
    
    stack_object_below = null
    throw_velocity = force
    
    just_thrown_timer = just_thrown_time
    
    thrown.emit()

func diminish_throw_velocity(velocity: Vector2, delta: float) -> Vector2:
    velocity.x *= 0.98
    velocity.y += 2000 * delta
    
    if just_thrown_timer > 0:
        return velocity
    
    if get_colliding_bodies().size() > 0:
        velocity.x = 0
        velocity.y = 0
    
    return velocity

This box item just snaps back to where it started being carried when it is thrown. Can anyone tell me why? This really has me stumped 😭

#

I assume it might be something to do with switching from integrate on to integrate off

rich heath
#

bump

candid kayak
#

Do you have a clip showing how it's working?

My best guess just from what I'm seeing here is that the elif is_being_carried logic affects global_position directly, so if somehow the code came back in here before updating the state properly, either it would break straight up or simply get set to the declared Vector2...

Seems unlikely, but could be worth setting some print statements at least to make sure that isn't happening.

rich heath
#

well i made the code a lot simpler and better according to the research i did

#
class_name Box
extends RigidBody2D

signal grabbed()
signal thrown()

const HITBOX_SIZE: Vector2 = Vector2(96, 96)

var is_being_carried: bool = false

var stack_object_below: Node2D

func _integrate_forces(state: PhysicsDirectBodyState2D) -> void:
    if is_being_carried:
        global_position = stack_object_below.global_position + Vector2(0, -HITBOX_SIZE.y)

func is_grabbable() -> bool:
    return true

func get_carried_by(obj: Node2D) -> void:
    is_being_carried = true
    stack_object_below = obj
    grabbed.emit()
    
    set_freeze(true)

func get_thrown(force: Vector2) -> void:
    is_being_carried = false
    stack_object_below = null
    thrown.emit()
    
    set_freeze(false)
    
    apply_central_impulse(force)


func set_freeze(on: bool) -> void:
    if on:
        freeze_mode = RigidBody2D.FREEZE_MODE_STATIC
        freeze = true
        gravity_scale = 0.0
        
        rotation = 0.0
        lock_rotation = true
    else:
        freeze = false
        gravity_scale = 1.0
        
        lock_rotation = false

But it's still not working.... global_positoin isn't being set at all (the code isn't even getting there??? and it's printing that is_being_carried is alternating every frame even though there's nothing that would caus ethat at all.

candid kayak
rich heath
#

the player object

#

so when I am setting global_position of the box in integrate_physics()

#

it doesn't even run because I don't think integrate_physics is called when frozen

#

but if I set it during physics_process_delta, then it just teleoprts back to where it was before it was frozen, when unfreezed

candid kayak
#

Hrmmm..

Why not just setup something in _process() or _physics_process() that does what _integrate_forces() is doing currently?

rich heath
#

it just teleports back

#

after I throw it

candid kayak
#

What if you don't freeze it? Does it cause issues?

#

Are you calling the function get_thrown directly? Or are you using call_deferred?

rich heath
#

I'm calling it directly

candid kayak
#

Can you try call_deferred for me? All that should do is call it after the current process frame has finished processing.. er something.

May not change anything, but worth trying.

Should effectively be:

throwable.call_deferred("get_thrown", force)