Pickup system

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

Hello, I made a simple pickup system but I’m not 100% glad about it.
Here’s code:

func pickup():
	if reach.is_colliding():
		if reach.get_collider().is_in_group("AK"):
			weapon_to_spawn = ak.instance()
		elif reach.get_collider().is_in_group("Knife"):
			weapon_to_spawn = knife.instance()
		elif reach.get_collider().is_in_group("Grenade"):
			weapon_to_spawn = grenade.instance()
		elif reach.get_collider().is_in_group("AWP"):
			weapon_to_spawn = awp.instance()
		elif reach.get_collider().is_in_group("Axe"):
			weapon_to_spawn = axe.instance()
		else:
			weapon_to_spawn = null
	else:
		weapon_to_spawn = null
		
	if Input.is_action_just_pressed("interact"):
		if hand.get_child(0) == null:
			if weapon_to_spawn != null:
				hand.add_child(weapon_to_spawn)
				reach.get_collider().queue_free()
				weapon_to_spawn.rotation = hand.rotation	
		else:
			if hand.get_child(0).is_in_group("AK"):
				weapon_to_drop = ak.instance()
			elif hand.get_child(0).is_in_group("Knife"):
				weapon_to_drop = knife.instance()
			elif hand.get_child(0).is_in_group("Grenade"):
				weapon_to_drop = grenade.instance()
			elif hand.get_child(0).is_in_group("AWP"):
				weapon_to_drop = awp.instance()
			elif hand.get_child(0).is_in_group("Axe"):
				weapon_to_drop = axe.instance()
				
			get_parent().add_child(weapon_to_drop)
			weapon_to_drop.global_transform = hand.global_transform
			weapon_to_drop.dropped = true
			hand.get_child(0).queue_free()	

This function works in a process(delta), and yes I know it’s kinda shitty. So here’s my question - how to improve it? Maybe more accurately how to do it without all of this instance stuff and how to connect player’s node and script with gun’s node and script?
When I add player script as a global varabiale it won’t work. I tried adding a separete code to the reach node (it’s raycast) to make it act like a weapon handler or like a bridge between gun and player but it didn’t quite work.

:bust_in_silhouette: Reply From: exuin
  • don’t call in process, just call in _unhandled_input
  • you can store all the groups and corresponding weapons in a dictionary and iterate through it
:bust_in_silhouette: Reply From: stormreaver

In my games, I create a separate subclass for each game object type, with each such subclass ultimately inheriting from a common base class. Each subclass has, among other properties, the full res:// path to itself. When I need to instantiate a new object due to collision, I need to only read the path variable from the collision object provided by Godot’s collision detection system.

This system has at least two very desirable properties:

  1. Instantiating new objects is done in constant time, as there is no code logic involved in determining what needs to be instantiated. Therefore performance is limited only by Godot’s collision subsystem efficiency. Godot’s collision subsystem performance improvements automatically cascade down to my game without me having to change anything in my own code.

  2. It is infinitely extendable without having to change a single line of mainline code involved in the collision/instantiation process. When I add a new game object type, I need only write the subclass.