• Godot HelpProgramming
  • How to I change the Area2D collision mask in code on an Instance, as a child of the instance?

I'm trying to use the same bullet scene for all actors that fire bullets, but I want to resolve friendly fire and actually have the bullet to hit the proper target.

I know that you can change the collision mask in code, but I don't know how to do it for an Instance like the bullet instance.

The Bullet scene has an Area2D child for detecting collisions.

I have a Shoot function that creates the instance of the bullet, logically to me that would be where you'd change the collision mask of the Area2D Node child of the Bullet that would be set to mask a certain layer.

As of right now I do have both a player actor and an enemy actor successfully able to fire the same bullet but the bullet only damages the enemy, and it passes right through the player actor.

I did have this working the way I wanted by simply using two different bullets, one setup for the player to damage the enemy and one for the enemy that's setup to damage the player, but I want to try to reuse assets in the game, have a more professional project.

Thank you very much for your help.

Thank you for the reply.

I know how to do that on the Bullet scene itself, but that doesn't help with being able use that in the function that creates an instance of the bullet.

I need something like this:

func shoot():
	var bullet = bulletPath.instance()
	var target = $Node2D/BulletDirection.global_position
	var direction = Vector2.ZERO
	var bullHitBox = HitBox
	get_parent().add_child(bullet)
	bullet.set_collision_mask_bit(3, true)
	bullet.set_collision_mask_bit(2, false)
	bullet.position = $Node2D/BulletEmitter.global_position
	bullet.rotation_degrees = $Node2D.rotation_degrees
	direction = bullet.global_position.direction_to(target).normalized()
	bullet.set_direction(direction)

The code above isn't giving me any errors, but it's also not changing the collision mask of the Area2D HitBox of the bullet.

I attempted, "bullet/HitBox.set_collision_mask_bit(3, true)" but that gave me errors.

I do know the function to use, I just don't know how to use it on the child of an instance.

Try the test project attached. For sure it's simpler than your setup still can give you some clues. :)

Thank you all very much for your help, it turns out I had the correct code that I needed I just used the wrong case when typing the variable name, but I fixed the case of the variable name and it's working as intended. :)

For future reference what I did was I created a variable hitBox that was tied to the child HitBox of the Bullet, when I attempted to assign the collision mask I mistakenly typed, "HitBox," instead of, "hitBox."

Here's the working code if someone needs to see an example in the future:

Bullet.gd

extends KinematicBody2D

var bulletVelocity := Vector2.ZERO
var direction := Vector2.ZERO
const bulletSpeed = 500
onready var hitBox = $HitBox

func _physics_process(delta: float) -> void:
	if direction != Vector2.ZERO:
		bulletVelocity = direction * bulletSpeed
		global_position += bulletVelocity * delta

func set_direction(direction: Vector2):
	self.direction = direction

func _on_VisibilityNotifier2D_screen_exited():
	queue_free()

func _on_HitBox_area_entered(area):
	queue_free()

Player.gd (only the shoot function):

func shoot():
	var bullet = bulletPath.instance()
	var target = $Node2D/BulletDirection.global_position
	var direction = Vector2.ZERO
	get_parent().add_child(bullet)
	bullet.hitBox.set_collision_mask_bit(3, true)
	bullet.hitBox.set_collision_mask_bit(2, false)
	bullet.position = $Node2D/BulletEmitter.global_position
	bullet.rotation_degrees = $Node2D.rotation_degrees
	direction = bullet.global_position.direction_to(target).normalized()
	bullet.set_direction(direction)

I've reformatted the posts to fix the code-block formatting.

8 months later