I don't think this is the best solution but this is the workaround I made to detect clicks on a joystick node that is child of a CanvasLayer. I have a structure like this:
What I did was:
- Add a script on the "joystick" node
- Manually detect clicks by position
- If click position belongs to the area I want, I call a function from the Player node
Sample code for joystick node (Godot 3):
extends Node2D
onready var joystickBtn = get_node("joystickBtn")
var btnPos = Vector2(0,0)
var btnSize = Vector2(0,0)
var btnRect2 = Rect2(Vector2(0,0), Vector2(0, 0))
func _ready():
set_process_input(true)
# Generate a Rect2 on the place we want to manage click
# For this example the are will be obtained from a button
btnPos = joystickBtn.get_global_position()
btnSize = joystickBtn.get_size()
btnRect2 = Rect2(btnPos, btnSize)
func _input(event):
var player = get_node("/root/mainNode/World/Player")
if event is InputEventMouseButton: # If event is mouse click
# Get click position
var clickPos = Vector2(event.position.x, event.position.y)
# If event is pressed and position belongs to btnRect2
if event.pressed and btnRect2.has_point(clickPos):
player.my_custom_function("arg1", "arg2")