0 votes

Is there a way to extract original text from a string?
I'd like to pass a string to another script, but for that script to take the name in the string as if it were one of it's global variables.

Example;

Script 1:

func _set_parameters():
     var outcome
     if test = true:
            outcome = "alive"
     else:
          outcome = "dead"
     $other_script._testing_for(outcome)

Script 2:

var alive = "I live!"
var dead = "I'm not alive!"

func _testing_for(incoming # Would like for this to be interpreted without the quotation marks from the first script.):
     print(incoming)

This way I don't have to assign each possible string to a variable.

in Engine by (293 points)

2 Answers

+1 vote
Best answer

Let's see if I understand: you want to use the content of the incoming parameter to select the variable to print, but without explicitly checking it (ie: if incoming == "alive": print(alive) elif incoming == "dead" ...), right? You can use index notation to access a variable's content with a string, like this:

var myVar = "Hello world"

func _ready():
    var stringToPrint = self["myVar"]
    print(stringToPrint)

Your script 2 would end up like this:

var alive = "I live!"
var dead = "I'm not alive!"

func _testing_for(incoming):
     print(self[incoming])

However, if you feel the need to access different variables by string, it usually indicates that what you want is a dictionary. Here's what that would look like:

var states= {
    "alive": "I live!",
    "dead": "I'm not alive!"
}

func _testing_for(incoming):
     print(states[incoming])

You can add a check to see if the key exists in the dictionary before accessing it (if states.has(incoming): ...), since accessing a value that doesn't exist will throw an exception, but sometimes you want the game to crash immediately while developping so you can catch errors sooner (ex: the caller shouldn't call _testing_for with a value that doesn't exist.

An improved version would use something like an enum for keys:

enum States {
    alive,
    dead
}
var states= {
    States.alive: "I live!",
    States.dead: "I'm not alive!"
}

func _testing_for(incoming): #incoming must be one of States enum
     print(states[incoming])

You would call _testing_for from another scripts like so:

func _set_parameters():
     var outcome
     if test = true:
            outcome = $other_script.States.alive
     else:
          outcome = $other_script.States.dead
     $other_script._testing_for(outcome)

Using an enum means you can more clearly define what values can be passed to your function and makes it less likely that you'll make typos in your strings.

by (1,112 points)
selected by

Looks like making a dictionary was what I needed to do. I appreciate the run down on enums too. I haven't tried using either of those methods yet, until now. The doc's make it look much more intimidating than it is.

Thank you!

0 votes

You can certainly pass a string argument from one script another. And, pretty much exactly as you outline above.

The only real trick is that you need to have access to the node that contains the other script.

For example, this should work as expected:

Tree

- Node2D
  - Sprite

Script on Node2D

_ready():
    $Sprite.print_me("My string")

Script on Sprite

func print_me(input):
    print(input)

That'll print My string

Is that what you're trying to do?

by (10,856 points)

Also, for clarity, the original string can be stored in a variable...

var my_string = "A new string"
$Sprite.print_me(my_string)

That'll print A new string, as expected...

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.