Hi, I am trying to create a garden simulator and i'm stuck on a problem, I have a basic point and click planting system but I don't know how to prevent from these plants from stacking ontop of eachother. Here are the photos of my basic setup:
#Planting System
1 messages · Page 1 of 1 (latest)
you could check whether currentseed is null and return if its not prior to the planting logic
If raycast is hitting a plant return
How would I do any of that
Sorry I’m kinda new
Ask chatgpt brother, use the tool to your disposal
I guess but i want to learn how to do it alone first
This is a help thread. People come here to learn and understand how to do new things and we expect people to respond to these with helpful responses.
Not only is replying to these with ai generated code or answers against our guidelines, it’s also not helpful
Please refrain from doing this again
ok but how do i do this 😭
You need to store what plant has been placed in each plot.
So when you click a plot, you can check that to see if there's anything there.
In this case i assume New_Plant is the plant you just placed, store that in a variable OUTSIDE the function so it persists after the function ends.
Oh sht sorry didn't know
So I should change the New_Plant variable to a list
and when I click, i check the cords of the other plants within the list and if its like 10 pixels away from the plant it will be placed?
How many plants do you want per plot?
its not on a grid based system so its basically how many you can fit
aah, in that case you may want to make the plants themselves be an area, and when you place down the plant, cancel the attempt if it results in an overlap with another plant.
so an area2d?
Yeah.
There are other ways to check for overlap, but that's the most automatic kind.
ok last question what would be the method for that
as the plot itself is an area2D
Basically when the plant is placed down. You can use get_overlapping_areas() on _ready() to get an Array of all other areas it overlaps with.
Then check if any of them are plants. If they are, delete the plant and report that the placement failed.
You could also check BEFORE placing the plant trough other methods. But this saves you from creating new objects or using PhysicsServer methods.
Ok thanks!
uh so from the Plot script I can't call get_overlapping_areas() for the new plant
Im doing it like so
var placeable = NewPlant.get_overlapping_areas()
The new plant can do that by itself in its own script.
oh
That is why i am saying that you have to place it first and then make the plant delete itself.
If you where to do a different check, from the plot for example, then you could prevent the placement altogheter. But it would be a bit more complicated.
so I would have to create a seperate script?
oh ok I see now
so is there any way you could communicate the destruction of the new plant back to the plot script
You can connect a signal from the plant as it is being added.
But it depends on what is the goal of that.
If you just need to check how many plants there are, you can have the plot itself count the amount of plants overlapping it.
later on I would like to limit the amount of plants
so if the plant is destroyed i want the plant to be refunded
That is what i assumed.
A signal would work for that.
Like:
#Plant script
signal cancelled
func validate_placement():
for area: Area2D in get_overlapping_areas():
#The area found has a Plant script
if area is Plant:
#Emit a signal, delete itself and exit this function
cancelled.emit()
queue_free()
return
When creating the plant, you can connect it like so:
NewPlant.cancelled.connect(refund)
add_child(NewPlant)
func refund():
plants_remaining += 1
You can either "tag" them with a group, or just check for their class (in this case i am assuming your plant script has class_name Plant in it, and using the is operator to check that)
For some reason it still doesn't work
after debugging i think there is something wrong with this piece of code
print_debug(area)
if area is Plant:
cancelled.emit()
queue_free()
return```
Make sure that the plants do have a script with class_name Plant
And that the collision_layer and mask of the involved areas allow them to be found.
I checked all these and it seems to be what you said
btw its inside the _onready() function and it seems to not get past the "for area" part
_onready() is not a built in function. Are you calling it from somewhere?
it must mean that it did not find anything during ready.
Or that none of what it found was a Plant
If you use breakpoints (just type breakpoint in the line in which you wish to stop) you can check the tree and the relevant values while the game is frozen.
You can then navigate with these buttons
Okay so what do I check for
Ok so I figured out that the area vairable just returns false no matter where it is placed
Nvm I just figured it out, the ready function was somehow happening before the node was added as a child in the tree
Even when I reorganize the code for the Placement check to happen
I still get 0 results for overlaping areas
contrary to when I put overlapping layers into proccess i get the desired output
please help i have no idea what is happening
please someone help me
Try enabling Project>Visible Collision Shapes and use breakpoints to better check what is running when.
I at least can't help much more with this context.
Make a signal that will be emitted only after the get_overlapping_areas() function is finished
Before validate_placement() function, add await function, so that the validation_placement() function will run only after get_overlapping_areas() function is finished
Im kinda stuck on how to do what you are saying
I created a new signal called "Resume"
Where are you having trouble?
I followed what you said and it still doesn't work
for somereason the area function still outputs "[]"
Is the get_overlapping_areas() function working properly?
Yea, when I put it in the process function it works fine
So get_overlapping_areas() doesn't work in validate_placement()?
No it returns an empty array
idk why its called after the node is put inside the node tree
Try using breakpoints or print statements to determine which functions run first
I don't think I can be of much help other than that
Ok
I just figured out something
when get_overlapping_areas() is called inside the validate_placement() function
it doesn't appear on the scene despite being inside the node tree
What doesn't appear on the scene?
The seed scene doesn't appear on the game screen
its not hidden and without the breakpoint after get_overlapping_areas() it appears no problem
Your problem may be related to that then
Alright ill try to debug further
I have no idea what is going on
does get_overlapping_areas() only work when the node is rendered
Did you mess with masks or layers any?
No they are all on layer one
there is something wrong with the way I'm calling the function atleast I think
Ok so I figured out the problem
get_overlapping_layers occurs during a physic update while _ready() and _on_input_event() runs before the physics update
but how do I fix this?
Maybe call it from somewhere else?
Or put
"await ready"
so that, it will continue only after ready function is run
wdym
i think this got a bit too out of hand.
It is probably easier to just use global variables to keep track of everything important and use that for checks and stuff.