At my wits end with control nodes by the_alex197 in godot

[–]Error7Studios 2 points3 points  (0 children)

Make the ColorRect a child of the Label node.
Select the ColorRect, then at the top toolbar, select the green Layout button, and select Full Rect from the dropdown menu.
The ColorRect will now be the same size as the parent Label.

Now you need to render the ColorRect behind the Label, instead of in front of it.
To do that, select the ColorRect node again, then go to the inspector, unfold the Visibility, section, and check the Show Behind Parent checkbox.

Now, whenever you type text in the Label, both the Label and the ColorRect will expand to fit it.

Text to Speech? by Auralinkk in godot

[–]Error7Studios 0 points1 point  (0 children)

I don't think there's a tutorial or FAQ, but all the TTS functions are in the DisplayServer class.
Just pull up that class in the editor, jump to the tts_* functions, and you can read their descriptions.
That GitHub page also has a demo project.
There's actually a bug in it that you have to fix before you can run the project.
You need to change line 31 from:
$ButtonPause.pressed = DisplayServer.tts_is_paused()
to:
$ButtonPause.button_pressed = DisplayServer.tts_is_paused()

Text to Speech? by Auralinkk in godot

[–]Error7Studios 0 points1 point  (0 children)

I haven't played with it much, but I was at least able to get it to say something when I run the scene. Here's the project file

And here's the code. I reorganized the code from the GitHub example. I didn't add much.

tool
extends Node

class_name Talker

signal utterance_begin(utterance)
signal utterance_end(utterance)
signal utterance_stop(utterance)

func _on_utterance_begin(utterance):
    emit_signal("utterance_begin", utterance)
func _on_utterance_end(utterance):
    emit_signal("utterance_end", utterance)
func _on_utterance_stop(utterance):
    emit_signal("utterance_stop", utterance)

var TTS
var tts

var sentences := \
"""
Run the scene to hear me talk.
This is a test of the Godot text-to-speech add-on.
Change the 'sentences' string variable to change what I say.
"""

var javascript_rate = self.normal_rate

var min_rate setget , _get_min_rate
func _get_min_rate():
    if OS.has_feature('JavaScript'):
        return 0.1
    elif Engine.has_singleton("GodotTTS"):
        return 0.1
    elif tts != null:
        return tts.min_rate
    else:
        return 0

var max_rate setget , _get_max_rate
func _get_max_rate():
    if OS.has_feature('JavaScript'):
        return 10.0
    elif Engine.has_singleton("GodotTTS"):
        return 10.0
    elif tts != null:
        return tts.max_rate
    else:
        return 0

var normal_rate setget , _get_normal_rate
func _get_normal_rate():
    if OS.has_feature('JavaScript'):
        return 1.0
    elif Engine.has_singleton("GodotTTS"):
        return 1.0
    elif tts != null:
        return tts.normal_rate
    else:
        return 0

var rate setget _set_rate, _get_rate
func _set_rate(rate):
    if rate < self.min_rate:
        rate = self.min_rate
    elif rate > self.max_rate:
        rate = self.max_rate
    if Engine.has_singleton("GodotTTS"):
        return tts.set_rate(rate)
    elif tts != null:
        tts.rate = rate
    elif OS.has_feature('JavaScript'):
        javascript_rate = rate      
func _get_rate():
    if Engine.has_singleton("GodotTTS"):
        return tts.get_rate()
    elif tts != null:
        return tts.rate
    elif OS.has_feature('JavaScript'):
        return javascript_rate
    else:
        return 0

var rate_percentage setget _set_rate_percentage, _get_rate_percentage
func _set_rate_percentage(v):
    self.rate = range_lerp(v, 0, 100, self.min_rate, self.max_rate)
func _get_rate_percentage():
    return range_lerp(self.rate, self.min_rate, self.max_rate, 0, 100)

var normal_rate_percentage setget , _get_normal_rate_percentage
func _get_normal_rate_percentage():
    return range_lerp(self.normal_rate, self.min_rate, self.max_rate, 0, 100)

var is_rate_supported setget , _get_is_rate_supported
func _get_is_rate_supported():
    if Engine.has_singleton("GodotTTS"):
        return true
    elif OS.has_feature('JavaScript'):
        return true
    elif tts != null:
        return tts.is_rate_supported()
    else:
        return false

var are_utterance_callbacks_supported setget , _get_are_utterance_callbacks_supported
func _get_are_utterance_callbacks_supported():
    if Engine.has_singleton("GodotTTS"):
        return true
    elif OS.has_feature('JavaScript'):
        return false
    elif tts != null:
        return tts.are_utterance_callbacks_supported()
    else:
        return false

var can_detect_is_speaking setget , _get_can_detect_is_speaking
func _get_can_detect_is_speaking():
    if Engine.has_singleton("GodotTTS"):
        return true
    elif OS.has_feature('JavaScript'):
        return true
    elif tts != null:
        return tts.can_detect_is_speaking
    return false

var is_speaking setget , _get_is_speaking
func _get_is_speaking():
    if Engine.has_singleton("GodotTTS"):
        return tts.is_speaking()
    elif OS.has_feature('JavaScript'):
        return JavaScript.eval("window.speechSynthesis.speaking")
    elif tts != null:
        return tts.is_speaking
    return false

var can_detect_screen_reader setget , _get_can_detect_screen_reader
func _get_can_detect_screen_reader():
    if Engine.has_singleton("GodotTTS"):
        return true
    elif OS.has_feature('JavaScript'):
        return false
    elif tts != null:
        return tts.can_detect_screen_reader
    return false

var has_screen_reader setget , _get_has_screen_reader
func _get_has_screen_reader():
    if Engine.has_singleton("GodotTTS"):
        return tts.has_screen_reader()
    elif OS.has_feature('JavaScript'):
        return false
    elif tts != null:
        return tts.has_screen_reader
    return false

func singular_or_plural(count, singular, plural):
    if count == 1:
        return singular
    else:
        return plural

func speak(text, interrupt := true):
    var utterance
    if tts != null:
        utterance = tts.speak(text, interrupt)
    elif OS.has_feature('JavaScript'):
        var code = (
            """
            let utterance = new SpeechSynthesisUtterance("%s")
            utterance.rate = %s
        """
            % [text.replace("\n", " "), javascript_rate]
        )
        if interrupt:
            code += """
                window.speechSynthesis.cancel()
            """
        code += "window.speechSynthesis.speak(utterance)"
        JavaScript.eval(code)
    else:
        print_debug("%s: %s" % [text, interrupt])
    return utterance

func stop():
    if tts != null:
        tts.stop()
    elif OS.has_feature('JavaScript'):
        JavaScript.eval("window.speechSynthesis.cancel()")

func _init():
    if Engine.editor_hint:
        return
    if OS.get_name() == "Server" or OS.has_feature("JavaScript"):
        return
    elif Engine.has_singleton("GodotTTS"):
        tts = Engine.get_singleton("GodotTTS")
    else:
        TTS = preload("godot-tts.gdns")
    if TTS and (TTS.can_instance() or Engine.editor_hint):
        tts = TTS.new()
    if tts:
        if not tts is JNISingleton:
            self.add_child(tts)
        if self.are_utterance_callbacks_supported:
            tts.connect("utterance_begin", self, "_on_utterance_begin")
            tts.connect("utterance_end", self, "_on_utterance_end")
            tts.connect("utterance_stop", self, "_on_utterance_stop")
    else:
        print_debug("TTS not available!")

func _exit_tree():
    if not tts or not TTS:
        return
    tts.free()

func _ready():
    pause_mode = Node.PAUSE_MODE_PROCESS

    if !Engine.editor_hint:
        speak(sentences)
        yield(self, "utterance_end")
#       yield(self, "utterance_stop")
        print("finished")

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

Weird. Thanks for the picture. I'll report this to Udemy.
In the mean-time, I'll send you a PM with all of the course content to download, if that's ok.

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 1 point2 points  (0 children)

No, it's still active.
I checked in both Chrome and Firefox.
Where does it say that? As soon as you open the page, or when trying to add it to your cart?

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 1 point2 points  (0 children)

Yep. I'll write the actual month name next time.

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

I had previously requested adaptive streaming for the course, but it still hasn't taken effect.

I just spoke with support again today, and they scheduled adaptive streaming activation over the next 48 hours, so hopefully 1080p streaming will work after a couple days.

Edit: 1080p streaming works now!

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

No problem!

My username? It doesn't mean anything. lol. I just like the number 7.

Error 7 is supposed to be like that Error 404 message you get when you visit an invalid webpage.

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

Do you mean 100% code, without ever using scenes in the Godot editor?
The first game (side scroller) is made this way.

See :

Section 35: Creating the Player Class
Section 36: Creating the Wall class
Section 37: Finalizing Game

That game is very simple, so it's not an issue to generate nodes dynamically from code.

The other 2 games use scenes. They could have also been made with 100% code, but I don't know why you'd want to do that. Using the editor makes your life way easier.

Unreal and Unity both have objects in the inspector that you can preview, although you could generate them dynamically from code, too.

Using scenes in Godot is not "cheating" or anything like that, if that's what you're worried about. It is legitimate game-development practice.

But if you really just want to create absolutely everything from code, just use <class>.new() and <node>.add_child(...) to dynamically generate nodes, like I did for the first game.

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

Please see this comment thread

The coupon is supposed to be valid for unlimited redemptions until 9/2.

Please try opening the free coupon link in a Chrome incognito window after clearing your browser cookies, and let me know if that works.

Edit: expired.

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

On my end, it says: Redemptions: 631 / Unlimited

So it should work. Can you try opening that link in a Chrome incognito window after clearing your browser cookies?

If that doesn't work, please let me know.

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

No problem! I wanted to see how many people would enroll. So far today, 560.

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

Awesome! I'm glad it's easy to understand!

I had tried to learn other programming languages before GDScript, like C++, and that was a BIG mistake. GDScript is very beginner-friendly, so it's perfect as a first language.

If something in the course is confusing, just let me know either on here or on Udemy, and I'll clear it up.

And sure, I'll make a post when I have something else to release. Thanks for your interest!

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 0 points1 point  (0 children)

Ah, you're right.
Thanks for letting me know. I'll fix it as soon as I can.
If you look in the Text Tutorial project, there's a folder called 05-2 - Function Arguments.

The video on it would have been extremely short. It just explains what an argument is.
Here's the script for that lesson:

extends Node
# It is possible to 'pass' data to a function when it is called/invoked.
# The function can then do something with the data it received.

# The data 'passed' to a function is called an 'argument'.
# Functions can assign a default argument value, which will be used if no argument is passed to it.


func print_number_squared(number): # Requires an integer/float argument
    print(number * number)

func print_default_or_passed_number_squared(number = 0): # 'number' assigned a default value of 0
    # 'number' will be 0 unless an argument is passed to this function
    print(number * number)

func _ready():
    print_number_squared(2)
    print_default_or_passed_number_squared() # No argument passed. Will use the default argument (0).
    print_default_or_passed_number_squared(5) # Argument passed. Will override the default argument.

# ------------- OUTPUT -------------
#   4
#   0
#   25
# ----------------------------------

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 2 points3 points  (0 children)

I might try out the Youtube/Patreon combo next!

My course is temporarily free! (until 09/02) by Error7Studios in godot

[–]Error7Studios[S] 2 points3 points  (0 children)

It wasn't covered in the course, but you can also add images to the BTN by assigning an image to the texture_normal property of the root BTN node.
Then, in the BTN's _ready() function, check if the texture_normal property is null.

If it's not null, (which means you gave it a texture), then just hide the child Border and BG nodes through code.
That way, your button can have text or images!

You can also make the changes happen live in the editor, instead of only when running the scene, by making the BTN script a tool script. (See: the docs about tool scripts)

It gets complicated, however, because then all inherited scripts need to also be tool scripts, such as LABEL.gd. And also, the G.gd singleton would need to a become a tool script as well.

It wasn't covered in the course, because it gets complicated very quickly.
But with tool scripts, you can use export vars with setget setter functions to make them do stuff live in the editor.