KinematicBody2Ds are not colliding

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

Currently, I have two KinematicBody2D scenes in my game. The first one is the Player, which is a spaceship that is in the main scene from the beginning, and has an input to physics process coded as such:

extends KinematicBody2D

# Default thrust speed.
var thrust_speed : int = 20000

# Default angular speed.
var angular_speed : float = PI

# Drag.
var drag : int = 100

# Velocity.
var velocity : Vector2 = Vector2.ZERO

# Read user input & apply.
func get_input(delta):

  # Check for brake & adjust drag.
  if Input.is_action_pressed("brake"):
	  drag = 1000
  else:
	  drag = 100

  # Apply drag.
  if velocity.x > 0:
	  if velocity.x >= drag: velocity.x -= drag
	  else: velocity.x = 0
  elif velocity.x < 0:
	  if velocity.x <= drag: velocity.x += drag
	  else: velocity.x = 0
  if velocity.y > 0:
	  if velocity.y >= drag: velocity.y -= drag
	  else: velocity.y = 0
  elif velocity.y < 0:
	  if velocity.y <= drag: velocity.y += drag
	  else: velocity.y = 0
	
  # Check for guns.
  if Input.is_action_pressed("left_gun"):
	  $LeftGun.fire()
  if Input.is_action_pressed("right_gun"):
	  $RightGun.fire()

  # Reset direction.
  var direction = 0

  # Check for turns & adjust rotation.
  if Input.is_action_pressed("turn_left"):
	  direction = -1
  if Input.is_action_pressed("turn_right"):
	  direction = 1
  rotation += angular_speed * direction * delta

  # Check for thrust & adjust velocity.
  if Input.is_action_pressed("thrust"):
	  velocity = Vector2.UP.rotated(rotation) * thrust_speed
	  $ThrustSprite.play()
	  $ThrustSprite.show()
  else:
	  $ThrustSprite.hide()
	  $ThrustSprite.stop()
	
  # Apply movement.
  move_and_slide(velocity * delta)

# Physics process.
func _physics_process(delta):
    # Receive user input.
    get_input(delta)

The other KinematicBody2D scene is a Civilian spaceship that spawns at a random location on a Path2D and is added as a child node to the main scene within the script:

# Spawn a civilian.
func _on_CivilianTimer_timeout():
  # Instance a civilian.
  var civilian = civilian_scene.instance()

  # Choose a random location to spawn.
  var civilian_spawn_location = 
get_node("Player/Camera2D/NPCPath/NPCSpawnLocation")
  civilian_spawn_location.offset = randi()

  # Set direction perpendicular to spawn location.
  var direction = civilian_spawn_location.rotation + (PI / 2)

  # Add randomness to direction.
  direction += rand_range(-PI / 4, PI / 4)
  civilian.rotation = direction

  # Set the location.
  civilian.position = civilian_spawn_location.position

  # Choose velocity for civilian.
  var velocity = Vector2(rand_range(10000.0, 20000.0), 0.0)
  civilian.set_linear_velocity(velocity.rotated(direction))

  # Spawn civilian by adding to scene.
  add_child(civilian)

  # Start timer again.
  $CivilianTimer.start()

Civilian scene then applies the given linear velocity as such:

extends KinematicBody2D

# Linear velocity.
var linear_velocity : Vector2 = Vector2.ZERO

# Ready.
func _ready():
  pass

# Physics process.
func _physics_process(delta):
  move_and_slide(linear_velocity)

# Set the linear velocity.
func set_linear_velocity(velocity):
    linear_velocity = velocity

Both bodies have a CollisionPolygon2D set, so that’s all sorted.

As both bodies are using move_and_slide(), I figured there would be some basic collision behaviour, but they don’t touch each other. The Player spaceship passes underneath the Civilian spaceship. Furthermore, I have called get_last_slide_collision() on both bodies and observed during a collision, but it returns a null object even when the bodies are overlapping.

I have searched dozens of other questions but I’m at a loss here.

Are you able to post the entire script for your nodes? If you like I have the same name on discord, maybe a bit faster solving this on there.

LordBoots | 2022-12-03 19:55

Space.gd
extends Node2D# Viewport size.var viewport_size : Vector2 = Vector2.ZERO - Pastebin.com

Player.gd
extends KinematicBody2D# Default thrust speed.var thrust_speed : int = 200 - Pastebin.com

Civilian.gd
extends KinematicBody2D# Linear velocity.var linear_velocity : Vector2 = V - Pastebin.com

I just noticed that the projectiles (RigidBody2D) that are fired by the Player collide with the Player’s spaceship but not with the Civilian spaceships too. What’s interesting is that these Missiles are instanced and added as child nodes in the script too, but from the Gun node’s script, so I’ll add those too in case you spot anything.

Gun.gd
extends Node2D# Allow instancing of projectiles.export(PackedScene) var pr - Pastebin.com

BlasterMissile.gd
extends RigidBody2D# Ready.func _ready(): # Hide the animation. $Explo - Pastebin.com

BlackBladedAxe | 2022-12-03 20:22

Okay so, I don’t know your nodeTree structure but from what I can see you’re see you’re referencing the Player inside the civilian class using $Player which if instanced won’t work because it only searches it’s own node tree.

This is a snippet of code from my Enemy.tscn scene which I then instance to spawn.

"References"
onready var player = $"/root/main/Player"
onready var timer = $Timer
onready var enemies = get_node("/root/main/Level/NavigationMeshInstance/Enemies")
onready var agent : NavigationAgent = $agent

As you can see I’m using $agent and $Timer because they are part of the same node tree whereas the other references are using absolute paths because they are out of scope. Without an absolute path it will only search for that node inside of it’s own scene tree so when instanced it can’t find what it’s looking for.

I’ve also found that if you pass self through the _ready() class it initialized the node. It could be trying to load variables before the node is initialized for some reason. I’ve had to do this multiple times to get around this issue…which may or may not be a bug, in all honesty I too could be doing something horribly wrong but at the end of the day it works.

LordBoots | 2022-12-03 20:40

There is no reference to Player, or any other nodes, in the Civilian script. When Civilians are instanced in Space, they are added to Space tree. Could this be a reason why they are not colliding? It would make Player and Civilian siblings, so I don’t see why they wouldn’t collide.

BlackBladedAxe | 2022-12-03 21:09

Would you be willing to upload your project folder? might be easier for me to have a mess about inside it till it’s solved. It’s a bit difficult without having the nodeTree and knowing what scripts are attached to what objects. I can understand if not though

LordBoots | 2022-12-03 21:12

I also messed up I meant the reference in the space script

LordBoots | 2022-12-03 21:13

:bust_in_silhouette: Reply From: LordBoots

My other answer is where you want to look.

I’ve only really messed around with 3D stuff in Godot.

Documentation states you can call for collisions on move and slide.

# Using move_and_slide. velocity = move_and_slide(velocity) for i in get_slide_count(): var collision = get_slide_collision(i) print("I collided with ", collision.collider.name)

It appears to be a reference error thought try rewriting the imports like this:
var somevar = get_node("/root/someNode1/someNode2/targetNode")
OR
var somevar = $"/root/someNode1/someNode2/targetNode"

These are absolute paths, they get around any nodePath issues by starting at the root of the scene.
Can you paste any errors from the interpreter? the game will still run in most cases with broken import but it will throw a red error.

:bust_in_silhouette: Reply From: LordBoots

Well, I figured it out for you. I had this same issue early this morning.

Delete your _ready() function. It’s an inbuilt function that initializes the object. It only contains pass which stops the initialization altogether.

Deleted it. No change.

BlackBladedAxe | 2022-12-03 21:07

:bust_in_silhouette: Reply From: BlackBladedAxe

I sorted it. I deleted and remade the CollisionPolygon2D child in the Civilian scene and it works now. No idea why it wasn’t working before, I double-checked the points and segments, everything seemed fine. May be a quirk, or I may have accidentally disabled something in my fumbling.

Many thanks (and apologies) to those that helped!

Nothing to be sorry about. Hope it’s all smooth sailing from here.

LordBoots | 2022-12-03 21:38