0 votes

Greets!

Sry, but i tried all kind of gets to reach the wanted node in some other branch, couldn't get it...

Here's my tree:

https://imgur.com/fTyiFgB

And from the second lowest CollisionShape, i want to reach the 'Use' button node selected.
How please?

in Engine by (321 points)

2 Answers

0 votes

Generally I do this by exporting node paths:

export(NodePath) var use_button_path
onready var use_button = get_node(use_button_path)

After adding this code to the script attached to your CollisionShape2D, set it in the editor by selecting the collision shape node in the "Scene" view and hitting "Assign" in the "Inspector" view.

If you're reusing the script on multiple collision shapes and some of them don't care about the use button, that's a problem because the code above explodes if the use_button_path is null. You can fix this by changing the scripts the other shapes use (maybe an opportunity for inheritance if you're into that sort of thing) or by changing the script to check that use_button_path isn't null in _ready() before calling get_node.

Also keep in mind that standard NodePath shenanigans apply: if you move the node within the scene hierarchy or move the node the path is referencing, you'll have to assign the nodepath again, just like if you'd used code.

by (629 points)
edited by

Thxs, tried it with a lil bit more complex attempt, tryin to get the Use node for its cursorstate variable and adding a rolladice function:

extends CollisionShape2D

export(NodePath) var use_button_path
onready var use_button = get_node(use_button_path)
onready var cursor_state = use_button.cursor_state


func _ready():
    randomize()

func _on_action_pressed():
    roll_a_dice(1, 100)

func roll_a_dice(minimum, maximum):
    return randi() % (maximum-minimum) + minimum

func _on_Area2D_input_event(_viewport, event, _shape_idx):
    var roll = roll_a_dice(1, 100)
    print(roll)
    if event is InputEventMouseButton and event.pressed and event.button_index == 1:
        if roll < GlobalP.charm and cursor_state == "selecting":
            print("okokooooooooooooooooook")

And same with Jgodfrey method, got no errors, but a long list of roll numbers, and not the expected "okokooooooooooooooooook" (when roll should be under GlobalP.charm).

0 votes

If you want to access the node strictly by its path in the scene tree, you can do that. Though, it can be brittle, as changes to the scene tree hierarchy can break paths you have in code.

So, with that caution, you should be able to access the node in question via:

var node = get_node("/root/Node2D/Control/Use")

See various examples of navigating the scene tree using absolute and relative paths here:

https://docs.godotengine.org/en/3.2/classes/class_node.html#class-node-method-get-node

by (10,914 points)

Thxs, here's my try with a lil more complex attempt, tryin to get the Use node for its cursorstate variable and adding a rolla_dice function:

extends CollisionShape2D

onready var node = get_node("/root/Node2D/Control/Use")
onready var cursor_state = node.cursor_state

func _ready():
    randomize()

func _on_action_pressed():
    roll_a_dice(1, 100)

func roll_a_dice(minimum, maximum):
    return randi() % (maximum-minimum) + minimum

func _on_Area2D_input_event(_viewport, event, _shape_idx):
    var roll = roll_a_dice(1, 100)
    var node = get_node("/root/Node2D/Control/Use")
    print(roll)
    if event is InputEventMouseButton and event.pressed and event.button_index == 1:
        if roll < GlobalP.charm and cursor_state == "selecting":
            print("okokooooooooooooooooook")

But i can't say that i reach the node since i got no error, but a long list of roll numbers in the stead of one, and not the "okokooooooooooooooooook" expected...

To verify whether you got the node, write out some property associated with it. For example:

print(node.name);

You have several pieces of logic that have to be true before you get to your print("okok...") statement, so I'd guess one or more of those are false?

I'd print out the interesting values there (roll, GlobalP.charm, and cursor_state) to make sure they are what you think they are.

The if event is ... line looks ok to me. I'd guess if you remove the if roll < ... line, you'll see your okoko... print line.

Once that's verified, you just need to figure out what logic there is returning false.

But, none of that really has anything to do with accessing the node (the original question).

Yes, the node is found and printed, but no, all of my statements are true. Trouble is that they appears continuously wich just one click on the CollisionShape, that way:

15 (roll)
Use (node name)
100 (GlobalP.charm)
56
Use
100
75
Use
100
And so on, indefinetely. Yes, my cursor_state is normal, when it should be "selecting"...
But yes sry, not much from the original question

Well, there's nothing magical about if statements - they're just logic. If all of the components are true, you should have no trouble getting inside one...

I'd recommend just setting a dubug breakpoint in the offending code and just examine each part of the logic - there's an issue there somewhere.

Assuming you don't know how to use the debugger, you could also just break the more complex if blocks into simpler ones and print something as you enter each level. So, something like this:

if event is InputEventMouseButton:
    print("mouse button event")
    if event.pressed:
        print("button pressed")
        if event.button_index == 1:
            print("left button pressed")
            if roll < GlobalP.charm:
               print("roll < GlobalP.charm")
               if cursor_state == "selecting":
                   print("cursor_state = selecting")
                   print("okokokok")

That way, you can see what individual logic is failing you... Beware of typos as the above was entered directly into the post and is untested...

Sry, found the culprit. My var cursorstate is still normal, though i changed it before clicking the area2D.
It's just that i was getting the first cursor
state var from the Use node, when i should get the one from its on_pressed function. And i don't know how to do that.

I was about to ask it as another question... :)

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.