I'm working on a HUD for a visual novel. I have a cache for characters that have been shown so far (independent of the characters actually on-screen), a function to hide them and another one to show them, move them around, change expressions, etc.
func show_char(who: String, model: String, lock_chars := true) -> void:
assert(who != "")
assert(who.is_valid_filename(), "'%s'" % who)
# Default to base_model if called with an empty string
if model == "":
model = base_model
assert(model.is_valid_filename(), "'%s'" % model)
# Determine side
var side: Container
if _next_side:
side = %Characters/Right
else:
side = %Characters/Left
assert(side != null)
# If this character has been shown before, simply reuse the node
var x: AspectRatioContainer = _chars.get(who)
if x:
print(x.get_node("model"))
var model = char_path + who + "/" + model
x.get_node("%model").texture = load(model)
# If the character is shown on the correct side or lock_chars
# is true, do nothing
if x.get_parent() == side or lock_chars:
return
# If the character is shown on a different side, hide them
if x.get_parent() != null:
x.get_parent().remove_child(x)
# Show character on the correct side
side.add_child(x)
x.set_owner(side)
# Toggle side
_next_side = not _next_side
return
# Character not shown before. Build a new branch
assert(_chars.get(who) == null,
"Tried to create an existing character '%s'" % who)
# Prepare the branch
var img := StyleBoxTexture.new()
var img_panel := Panel.new()
var img_container := AspectRatioContainer.new()
# Load texture
model = char_path + who + "/" + model
assert(ResourceLoader.exists(model),"%s" % model)
img.texture = load(model)
# Adjust min size
img_container.set_custom_minimum_size(img.texture.get_size())
# Build the new panel
img_panel.add_theme_stylebox_override("panel", img)
img_panel.set_name("model")
img_panel.set_unique_name_in_owner(true)
# Add panel to container
img_container.add_child(img_panel)
img_panel.set_owner(img_container)
# Name container
img_container.set_name(who)
img_container.set_unique_name_in_owner(true)
# Record it in _chars
_chars[who] = img_container
# Add it to SceneTree
side.add_child(img_container)
img_container.set_owner(side)
# Toggle side
_next_side = not _next_side
func hide_char(who: String) -> void:
assert(_chars.get(who) != null, "%s" % who)
assert(_chars.get(who).get_parent() != null, "%s" % who)
# Search CharacterRow for the given character and hide them.
var x: AspectRatioContainer = _chars.get(who)
x.get_parent().remove_child(x)
x.set_owner(null)
The character row is just a bunch of HBoxContainer
s inside of a MarginContainer
.
The problem comes from hiding and then showing the same character model. The first call to load()
, in the 2nd part of show_char()
, returns a Texture2D
, and life is good. The 2nd call then tries to load the same image but returns a CompressedTexture2D
, which raises an Invalid set index error. How can I force load()
to always return a Texture2D
?