The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

I'm trying to remake my simple blobby-volley-like game in godot but I'm having a trouble with making player (KinematicBody2D with circle CollisionShape2D) hit the ball (RigidBody2D with circle CollisionShape2D). I decided the ball to be RigidBody2D because I want it to rotate on hit and all physics stuff like that.

My goal is to make the player simply push the ball at the particular speed and keep player's movement unaffected after hitting the ball. I've tried to use moveandslide() on player but of course it doesn't let him move after hitting the obstacle. set_pos() is also a bad idea as it makes the player teleport and let him go through the ground (which is StaticBody2D).

I've also tried to use moveandslide() and manually detect the collision using script attached to KinematicBody2D. However, it doesn't seem to work properly, it detects collision with the ball from time to time as if player has to touch the ball in a specific way to trigger the collision detection.

Here's my player script:

    extends KinematicBody2D

export var player_index = 1
export(Color, RGB) var color

const movement_speed = 350
const jump_speed = 700
const push_speed = 300
const custom_gravity = 1000
const floor_normal = Vector2(0, -1)

var velocity = Vector2(0, 0)
var can_jump = false

var collision_counter = 0

func _ready():
    # Called every time the node is added to the scene.
    # Initialization here
    get_node("body").set_modulate(color)
    set_process(true)

func _process(delta):
    check_input()
    check_collision_with_ball()
    move_dolfon(delta)

func move_dolfon(delta):
    # Apply gravity
    velocity.y += custom_gravity * delta

    # Move the dolfon
    velocity = move_and_slide(velocity, floor_normal)
    can_jump = is_move_and_slide_on_floor()

func check_input():
    if Input.is_action_pressed("p" + str(player_index) + "_move_left"):
        velocity.x = -movement_speed
        scale(Vector2( 1, 1))
    elif Input.is_action_pressed("p" + str(player_index) + "_move_right"):
        velocity.x =  movement_speed
        scale(Vector2(-1, 1))
    else:
        velocity.x = 0

    if Input.is_action_pressed("p" + str(player_index) + "_jump") && can_jump:
        velocity.y = -jump_speed

func check_collision_with_ball():
    if is_colliding() && player_index == 1:
        var collider = get_collider()
        if collider.get_name() == "ball":
            var dir = (get_collision_pos() - get_node("collision_shape").get_pos()).normalized()
            print("we hit a ball")

If needed, I can send the current project

in Engine by (27 points)

1 Answer

+2 votes

The move API won't solve your problems here (because is a simple overlap prevention method), you need another body to act as a solid against the ball, like:

main_body (kinematic, using move, obstacle mask)
|-shape
|-sub_body(kinematic, moved by parent, ball layer)
    |-shape

The secondary body will be moved by the parent like if is using "set_pos".
If you want the kinematic body to be notified of collisions, use the ball's body_enter signal.

ps: to use physics, do things in _fixed_process.

by (7,890 points)

Thanks! I didn't know it is so simple and straightforward

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.