Interactions - acbarker19/Godot-Action-RPG GitHub Wiki

Create a Hurtbox and Hitbox

  1. Create two new scenes by pressing the + icon at the top
  2. Save these scenes to the Overlap folder (or create it)
  3. Add Area2D nodes to both scenes
  4. Add CollisionShape2D nodes to both Area2D nodes

Add a Hitbox or Hurtbox to an Object

  1. Open an object's scene
  2. In the left menu, click Instance a scene file as a Node (looks like a chain)
  3. Select Overlap/Hitbox.tscn or Overlap/Hurtbox.tscn and click Open
  4. In the left menu, right click the Hitbox or Hurtbox and turn on Editable Children
  5. Select the Hitbox or Hurtbox's child CollisionShape2D
  6. In the right menu, select Shape > New DESIREDShape2D
  7. In the main window, move the collision shape to the correct location and resize it

Do Something When a Hurtbox is Interacted With

  1. Open an object's scene
  2. In the left menu, select the object's Hurtbox
  3. In the right menu, open the Node tab
  4. Double click Area2D > area_entered
  5. Click Connect to create function in the object's script
  6. Add code to the function
  • To play an animation and destroy an object in a better way, add the following:
func create_effect():
	var EffectObjectName = load("res://Effects/EffectObjectName.tscn")   // drag the effect file into the load() function to easily get the correct path
	var localEffect = EffectObjectName.instance()
	var world = get_tree().current_scene   // gets the uppermost world node
	world.add_child(localEffect)
	localEffect.global_position = global_position   // adds the destruction animation in the same position as the current object
		
func _on_Hurtbox_area_entered(area):
	create_effect()
	queue_free()   // destroys the current object

Move a Hitbox During an Animation

  1. Open an object's scene
  2. In the left menu, add a Position2D node and rename it to HitboxPivot
  3. Position HitboxPivot where desired
  4. Drag the Hitbox into HitboxPivot to make it a child
  5. In the left menu, click on AnimationPlayer to open the animation menu at the bottom
  6. Select a good frame to represent the animation
  7. In the left menu, click on the Hitbox
  8. Position the Hitbox where desired
  • If needed, click the Hitbox's CollisionShape2D and click the Shape in the right menu to change the radius or height
  1. In the left menu, select HitboxPivot
  2. In the right menu, select Node2D > Transform and click the key icon next to Position, Rotation Degrees, and/or Scale
  3. Make sure the key is moved to the first frame in the bottom menu
  4. Add more keys to other frames or animations

Hide a Hitbox When an Animation is Complete

  1. Open an object's scene
  2. In the left menu, click on AnimationPlayer to open the animation menu at the bottom
  3. In the left menu, click on the Hitbox's CollisionShape2D
  4. In the bottom menu, move to the frame where the Hitbox should be enabled
  5. In the right menu, select CollisionShape2D and click the key icon next to Disabled
  6. In the bottom menu, move to the frame where the Hitbox should be disabled
  7. In the right menu, select CollisionShape2D, check Disabled, and click the key icon next to it
  8. Add more keys to other frames or animations
  9. If the hitbox should be disabled at launch, move off of any other keyframes, and check Disabled

Add Layers to Determine What Objects Can Affect Other Objects' Hurtboxes

  1. In the top window Menu, select Project > Project Settings...*
  2. In the left menu of the popup, select Layer Names > 2D Physics
  3. For layers 1-4, add "World", "Player", "PlayerHurtbox", and "EnemyHurtbox"
  4. Close the popup

Add Layer Collision to Hitboxes and Hurtboxes

  1. Open the Hurtbox scene
  2. In the left menu, select the Area2D Hurtbox node
  3. In the right menu, deselect all boxes under Collision > Layer and Mask
  4. Repeat steps 1-3 for Hitbox
  5. Open a desired hurtbox object's scene
  6. In the left menu, click the Area2D Hurtbox node
  7. In the right menu, set Collision > Layer to EnemyHurtbox (the fourth box) and Mask to nothing
  8. Open a desired hitbox object's scene
  9. In the left menu, click the Area2D Hitbox node
  10. In the right menu, set Collision > Layer to nothing and Mask to EnemyHurtbox (the fourth box)

Add Layer Collisions for the Player and the World

  1. Open the Player scene
  2. In the left menu, select the KinematicBody2D Player node
  3. In the right menu, set Collision > Layer to Player (the second box) and Mask to World (the first box)
  4. Open the World scene or a world object's scene
  5. In the left menu, select the object's collidable node
  6. In the right menu, set Collision > Layer to World (the first box) and Mask to nothing

How to Control the Damage of a Hitbox

  1. Open the Hitbox scene
  2. Attach a script to the parent node
  3. Add the following:
export var damage = 1
  1. Any specialized hitboxes (such as the SwordHitbox for the player) can extend the Hitbox.gd file instead of Area2D. To easily do this, delete "Area2D" from the extends line at the top of the file and drag the Hitbox.gd file from the bottom left file browser to after the word "extends".
  2. Inside the scene of the desired object, select the Hitbox node in the left menu
  3. In the right menu, change the Script Variables > Damage to the desired value

Create a Player Detection Zone

It may be useful to determine if the player has entered a certain area, such as to pick up an item or to determine if an enemy has spotted them.

  1. Create a new scene by pressing the + icon at the top
  2. Save the scene to the Enemies folder (or Overlap if it will be used outside of enemy spotting)
  3. Add an Area2D node to the scene
  4. Add a CollisionShape2D node as a child of the Area2D node
  5. To only check if the player has entered the zone, select the Area2D parent node and in the right menu, set Collision > Layer to nothing and Collision > Mask to Player
  6. Create a script for the Area2D parent node
  7. Select the Area2D parent node and in the right menu, open the Node tab and add the body_entered(body: Node) and body_exited(body: Node) signals
  8. In the script, add the following:
extends Area2D

var player = null

func can_see_player():
	return player != null

func _on_PlayerDetectionZone_body_entered(body):
	player = body

func _on_PlayerDetectionZone_body_exited(body):
	player = null

Stop Player from Continually Being Hurt By Enemies

  1. Open the Hurtbox scene
  2. Add a Timer node to the Hurtbox scene
  3. In the right menu, add the timeout() signal
  4. In the Hurtbox script, add the following:
extends Area2D

const HitEffect = preload("res://Effects/HitEffect.tscn")

var invincible = false setget set_invincible

onready var timer = $Timer

signal invincibility_start
signal invincibility_ended

func set_invincible(value):
	invincible = value
	if invincible:
		emit_signal("invincibility_started")
	else:
		emit_signal("invincibility_ended")

func start_invincibility(duration):
	self.invincible = true
	timer.start(duration)

func create_hit_effect():
	var effect = HitEffect.instance()
	var main = get_tree().current_scene
	main.add_child(effect)
	effect.global_position = global_position

func _on_Timer_timeout():
	self.invincible = false
  1. Add the following to the Player script:
onready var hurtbox = $Hurtbox

func _on_Hurtbox_area_entered(area):
	stats.health -= area.damage
	hurtbox.start_invincibility(0.5)
	hurtbox.create_hit_effect()
  1. Add the following to the Bat script:
onready var hurtbox = $Hurtbox

func _on_Hurtbox_area_entered(area):
	stats.health -= area.damage
	knockback = area.knockback_vector * 120
	hurtbox.create_hit_effect()

Allow Enemy to Damage Again Player if They Stay in Player's Hurtbox

  1. Create invincibility signals for the Hurtbox
  2. Select the Hurtbox node
  3. In the right menu, select the Node tab
  4. In the right menu, add the invincibility_start() and invincibility_ended() signals
  5. In the Hurtbox script, add the following:
func _on_Hurtbox_invincibility_start():
	monitorable = false

func _on_Hurtbox_invincibility_ended():
	monitorable = true

Create a Soft Collision to Prevent Enemies from Overlapping

  1. Create a new Scene
  2. Set the root node as Area2D
  3. Rename the Area2D as SoftCollision
  4. Add a CollisionShape2D as a child node
  5. Save the scene as SoftCollision in the Overlap folder
  6. Create a script for the SoftCollision node
  7. Add the following to the script:
func is_colliding():
	var areas = get_overlapping_areas()
	return areas.size > 0
	
func get_push_vector():
	var areas = get_overlapping_areas()
	var push_vector = Vector2.ZERO
	if is_colliding():
		var area = areas[0]
		push_vector = area.global_position.direction_to(global_position)
		push_vector = push_vector.normalized()
	return push_vector
  1. Add a SoftCollision layer
  2. In the right menu, set Collision > Layer to SoftCollision and set Collision > Mask to SoftCollision

Add Soft Collisions to an Enemy to Prevent Overlap

  1. Open the Bat scene
  2. In the left menu, click Instance a scene file as a Node (looks like a chain)
  3. In the left menu, right click the SoftCollision and turn on Editable Children
  4. In the right menu, select the Shape and resize
  5. Open the Bat script and add the following:
onready var softCollision = $SoftCollision

func _physics_process(delta):
	// state machine code
			
	if softCollision.is_colliding():
		velocity += softCollision.get_push_vector * delta * 400
	velocity = move_and_slide(velocity)