How would I be able to reverse gravity for a split second? (My gravity system included)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By RuukasuDraw

Hi, I’m wondering if there’d be any way to reverse gravity for a split second if colliding with a CollisionShape2D. Here’s the gravity system I use:

extends KinematicBody2D

const UP = Vector2(0,-1)
const GRAVITY = 20
const SPEED = 200

var motion = Vector2()

func _physics_process(delta):
	motion.y += GRAVITY
	
	if Input.is_action_pressed("ui_right"):
		motion.x = SPEED
		$Sprite.flip_h = false
		$Sprite.play("Run")
	elif Input.is_action_pressed("ui_left"):
		motion.x = -SPEED
		$Sprite.flip_h = true
		$Sprite.play("Run")
	else:
		$Sprite.play("Idle")
		motion.x  = 0
	
	motion = move_and_slide(motion, UP)
	pass 

P.s Yes, my gravity is coded from a KinematicBody2D titled “Player”

If any code could be provided, that’d be a real big help. Thanks!

This is all in Godot 3.1.1

:bust_in_silhouette: Reply From: DrewS

You could add a variable var flipped = 1 and multiply gravity by that GRAVITY * flipped, then when you want to trigger the flipping you simply invert it flipped = -1 so now your gravity is reversed, to make it last one second add a timer.

extends KinematicBody2D

const UP = Vector2(0,-1)
const GRAVITY = 20
const SPEED = 200

var flipped = 1
var timer

var motion = Vector2()

func _ready():
    timer = Timer.new()
    timer.connect("timeout", self, "_on_timeout")
    timer.one_shot = true
    add_child(timer)

func _physics_process(delta):
    motion.y += GRAVITY * flipped

    if Input.is_action_pressed("ui_right"):
        motion.x = SPEED
        $Sprite.flip_h = false
        $Sprite.play("Run")
    elif Input.is_action_pressed("ui_left"):
        motion.x = -SPEED
        $Sprite.flip_h = true
        $Sprite.play("Run")
    else:
        $Sprite.play("Idle")
        motion.x  = 0

    if (CONDITION):
        flipped = -1
        timer.start(1)

    motion = move_and_slide(motion, UP)
    pass 

func _on_timeout():
    flipped = 1

You would change (CONDITION) to what you need to trigger the reversing, such as a collision. If you are using a collision you can use a signal from the collision body to trigger the flipping and timer.

flipped can also be a float which can also be used to increase gravity at times (renamed to gravity_scale or something).

Dlean Jeans | 2019-07-28 05:18

Thanks! This helps loads, but when I use this and replace the (CONDITION) with collisionflip, it says: error(33,6): Identifier 'collisionflip' is not declared in the current scope. What exactly does this mean? Or does it just mean I have to have an existing signal with the output of collisionflip?

RuukasuDraw | 2019-07-28 18:42

You will need to implement some sort of collision checking mechanism. Since your using move_and_slide you can check for a collision with:

if get_slide_count() > 0:
    collisionflip = true

this will cause it to flip gravity any time there is a collision. Or to limit it to some specific objects

for i in get_slide_count():
    var collision = get_slide_collision(i)
    if collision.collider.name == "specific object to flip with":
        collisionflip = true
        break

then add collisionflip = false at the end of the if (CONDITION): block.

DrewS | 2019-07-29 02:45