Godot 4.4
Is there a way for a TextureRect to take up an irregular area?
I am attempting to make clickable objects that visually overlap with one another. I initially tried to use Area2Ds and collision shapes, however, if one area is clicked, the area behind it is also clicked. Control nodes and TextureRects seem like better options for layering, but are inconvenient for irregularly-shaped objects. Is there a way to create an irregularly-shaped TextureRect?
You can override _has_point and check for areas that should be ignored, you can then check the opacity of the texture (if it supports it)
Would I override functions in a â_readyâ function?
This isnât functional code, but I feel like Iâm getting at the right idea:
func _ready() -> void:
$Pipe.has_point(point)
var point = $Pipe.texture.opacity
Iâm not sure how the opacity variable is stored. The texture is a transparent PNG, so checking the opacity should work out.
No you override it like you override _ready, but in the texture rect, in a new script for it
Something more similar to this?
extends TextureRect
func _has_point(point: Vector2) -> bool:
Vector2 = texture.has_alpha()
1 Like
It would be return has_alpha but yes, you can check using different methods on Image from texture.get_image
This gives me an âInvalid access to property or key âhas_alphaâ on a base object of type âimageâ.â error, so I donât think Iâm calling the alpha correctly
extends TextureRect
func _has_point(point: Vector2) -> bool:
return texture.get_image().has_alpha
You should probably use texture..get_image().get_pixelv(point).a > 0.0 or some similar threshold, youâre not calling a method here
Should I use an âifâ statement to check for the alpha?
extends TextureRect
func _has_point(point: Vector2) -> bool:
if texture.has_alpha() == true:
return texture.get_image().get_pixelv(point).a > 0.0
Sounds good, Iâd also check that texture.get_image() is valid with an if statement too
I have a âNot all code paths return a valueâ error at the func line of my current code
Yes, add a return false at the end
The code doesnât trigger errors anymore, but now the object attached doesnât react to anything.
extends TextureRect
func _has_point(point: Vector2) -> bool:
if texture.has_alpha() == true:
return texture.get_image().get_pixelv(point).a > 0.0
return false
I tried keeping the original code in the control node:
extends Control
var pipe_base = preload("res://sprites/placeholder_sprites/pipe.png")
var pipe_outline = preload("res://sprites/placeholder_sprites/outlined/pipe_outline.png")
func _on_pipe_mouse_entered() -> void:
$Pipe.texture = pipe_outline
func _on_pipe_mouse_exited() -> void:
$Pipe.texture = pipe_base
func _on_pipe_gui_input(event: InputEvent) -> void:
if event.is_action_pressed("click"):
if Global.UMBRELLA == true:
print("The umbrella shields the door. The door is safeguarded")
$"../UmbrellaOpen".visible = true
Global.SAFEGUARDED = true
else:
print("The pipe is unsecure")
and adding it to the TextureRect node:
extends TextureRect
func _has_point(point: Vector2) -> bool:
if texture.has_alpha() == true:
return texture.get_image().get_pixelv(point).a > 0.0
return false
var pipe_base = preload("res://sprites/placeholder_sprites/pipe.png")
var pipe_outline = preload("res://sprites/placeholder_sprites/outlined/pipe_outline.png")
func _on_mouse_entered() -> void:
$Pipe.texture = pipe_outline
func _on_mouse_exited() -> void:
$Pipe.texture = pipe_base
func _on_gui_input(event: InputEvent) -> void:
if event.is_action_pressed("click"):
if Global.UMBRELLA == true:
print("The umbrella shields the door. The door is safeguarded")
$"../UmbrellaOpen".visible = true
Global.SAFEGUARDED = true
else:
print("The pipe is unsecure")
Then the texture probably doesnât support alpha, or doesnât support reading the alpha, so youâd need to solve it by some other way, canât really help further with that
You could try removing the has_alpha check as it might give false results, and see if that helps