The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

Just like in a text adventure, I want what the player types in to return a text response based on what the player types in. I know a signal would be used to accomplish this, but I still don't have a good grasp on custom signals. I am using the LineEdit and RichTextLabel nodes.

Additionally, would there be an easier or simpler way to organize the responses, instead of using several if statements?

Thanks!

in Engine by (40 points)

2 Answers

0 votes
Best answer

I think a dictionary {} might be good for this.

I like signals, but I think a plain _process(delta) would be fine.

If I was you I would look through all the String class methods:
http://docs.godotengine.org/en/latest/classes/class_string.html

and I would look though the methods in TextLabel and every other text node you might want to use. Try to see what every node can really do ( and remember it can do everything that it is inheriting from too)

     extends TextEdit

# this is a dictionary
        var responses = {["hi", "who are you"] : "hi, I'm a dog", ["i like cats", "i don't like dogs"]: "I'm going to bite you."} 
        var foundResponse = true

        func _ready():

            set_process(true)
        func _process(delta):
            if Input.is_action_pressed("ui_right") == true:

            var inputText = get_text()
            inputText = inputText.to_lower() # make lowercase

           # look for a response in the keys of the dictionary
            for key in responses.keys():
                if inputText in key:
                    get_node("Label").set_text(responses[key])
                    foundResponse = true
                    return

            if foundResponse == false:
                get_node("Label").set_text("i don't understand")

            foundResponse = false
by (545 points)
selected by

Thanks for the advice and link. Can you explain why you would use _process(delta) instead of a signal?

This is my code so far, which returns text from the LineEdit node onto the RichTextLabel, but the RichTextLabel isn't able to return a response relative to the player response.

extends LineEdit

signal return_text

var response = self.get_text()
var _node

func _text_response():
  response.connect("return_text", self, "_signal_response")

func _ready():
  _node = self.get_parent().get_node("RichTextLabel")

func _on_LineEdit_text_entered(text):
  if text.length() > 0:
    _node.add_text(">"+ text)
    _node.newline()
    self.clear()

func _on_text_response(responseIn):
   emit_signal("return_text")

Do you know why the signal isn't working?

info about signals:
# the built-in signals emit automatically (based on built-in triggers)
# but custom ones do not, so you need to add an emitter: emitsignal("yoursignalname")
# the problem you have is: you don't have anything to trigger your emit
signal()

_process(delta) vs signals
# signals from my understanding are basically free ( the engines checking things if you use them or not)
# signals only send you info when something happens
# _process(delta) allows you to check things constantly

http://docs.godotengine.org/en/latest/tutorials/step_by_step/scripting.html
http://docs.godotengine.org/en/latest/reference/gdscript.html#signals

extends LineEdit

signal return_text

var response = self.get_text()
var _node

# you can connect your signal in _ready() (so I delete _text_response())

func _ready():
    _node = self.get_parent().get_node("RichTextLabel")             

    # you might be better off using a built-in one like "text_entered"
    connect("text_entered", self, "_on_LineEdit_text_entered") 

func _on_LineEdit_text_entered(text):
    if text.length() > 0:
        _node.add_text(">" + text)
        _node.newline()
        self.clear()

    # Don't really understand whats going on with this part, but I don't think you need it.
    #func _on_text_response(responseIn):
    #   emit_signal("return_text")
0 votes

You don't need signals for this.
If you want some response on keyboard input, you should be using built-in _input(event) processing loop.

func _ready():
    set_process_input(true)

func _input(event):
    if event.type == InputEvent.KEY
    # update label / process input

InputEvent

As for processing, I'd follow the other answer with dictionary approach

by (29 points)
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 Frequently asked questions and 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 [email protected] with your username.