This is the testing Godot forums! All forum posts unique to this forum will be deleted! Please use the main forums here for any posts you want to keep. All forum rules still apply.

Dynamically adding a variable to a class/node

BatteryBattery Posts: 26Member
edited August 2016 in Programming
Anyone know how you can create and assign a variable to a class/node dynamically in another script, something like:<br /><br />
<br />func _ready():<br />&nbsp; &nbsp; var n = get_node(&quot;Node2D&quot;)<br />&nbsp; &nbsp; n.new_variable = &quot;some value&quot;<br />
<br /><br />Which would work in Python, but GDscript doesn't like it.

Tags :

Comments

  • BatteryBattery Posts: 26Member
    Ok, there's [tt]Object.set()[/tt] and [tt]Object.get()[/tt], which looking at the docs should insert properties into a class and fetch them. Except it doesn't. After using [tt]set()[/tt] calling [tt]get()[/tt] just returns nill and printing [tt]get_property_list()[/tt] doesn't show the added property. I guess that [tt]get()[/tt] and [tt]set()[/tt] just change properties created at run time, which is not clear in the docs. <br /><br />[tt]set_meta()[/tt] and [tt]get_meta()[/tt] do what I'm after, but it's not as 'nice' looking as using the dotted notation (ie. some_node.my_new_prop = x). The docs particularly clear on their usage, I guess they're there for adding new properties!<br /><br />Basically, what I'm doing is making a journal of monsters encountered/learnt about in the game. Each monster adds a new entry, and the player can click on the icon of the monster and it'll display information about that monster. So the buttons are created dynamically, and the monster information text is stored in a dictionary in a GDscript resource. I don't want to create an individual button for each monster, and each button doesn't need it's own script. So I need a way adding the dictionary to the newly created monster icon. This way all icons can share the same code. [tt]get_meta()[/tt] and [tt]set_meta()[/tt] work, but it doesn't feel right!
  • bitwesbitwes Posts: 74Member
    You can have all the buttons call the same event handler and make them pass in their index or name so that you can have one function that will display the text for each.<br /><br />This can be achieved through the editor or code.  Here's the code (not tested):<br />
    <br />var texts = {<br />&nbsp;  &#039;one&#039; = &#039;This is one&#039;,<br />&nbsp;  &#039;two&#039; = &#039;This is two&#039;,<br />&nbsp;  &#039;three&#039; = &#039;This is three&#039;<br />}<br /><br /># Loop through the texts hash creating a button for <br /># each entry.&nbsp; The text of the button will be the key <br /># and it will pass the value of the key to the even handler.<br />for key in texts:<br />&nbsp; var b = Button.new()<br />&nbsp; add_child(b)<br />&nbsp; b.set_size(Vector2(50, 50))<br />&nbsp; b.set_pos(Vector2(100, i * 100))<br />&nbsp; b.set_text(key)<br />&nbsp; b.connect(&#039;pressed&#039;, self, &#039;_on_journal_button_pressed&#039;, [key])<br /><br /><br />func _on_journal_button_pressed(key):<br />&nbsp; print(texts[key])<br />
    
    <br /><br />The magic is in the connect.  The last parameter is an array of things that will be passed to the event handler.  One caveat is that you MUST have one parameter to the handler for each element in the array (in our case just one).  If there is a mismatch between the number of elements in the array and the number of parameters to the handler, the handler won't be called.  Last I checked, there wasn't any indicator of an error either, so it can be a hassle to debug.
  • BatteryBattery Posts: 26Member
    Thanks, I never thought to use the buttons themselves as dictionary keys.

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.